migrated playlist to DSLV

This commit is contained in:
Adrian Ulrich 2014-10-17 14:36:58 +02:00
parent 61663414b7
commit 744c91adbc
4 changed files with 96 additions and 57 deletions

View File

@ -1,29 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2011 Christopher Eby <kreed@kreed.org>
Copyright (C) 2014 Adrian Ulrich <adrian@blinkenlights.ch>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<ch.blinkenlights.android.vanilla.DragListView
<com.mobeta.android.dslv.DragSortListView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:dslv="http://schemas.android.com/apk/res-auto"
android:id="@+id/list"
android:fastScrollEnabled="true"
android:divider="@null"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
android:layout_height="fill_parent"
dslv:drag_enabled="false"
dslv:drag_start_mode="onMove"
dslv:drag_handle_id="@+id/dragger"/>

View File

@ -1,27 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2012 Christopher Eby <kreed@kreed.org>
Copyright (C) 2014 Adrian Ulrich <adrian@blinkenlights.ch>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<ch.blinkenlights.android.vanilla.DragTextView
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:singleLine="true"
android:textColor="?android:textColorPrimary"
android:gravity="left|center_vertical" />
android:background="@drawable/selectable_item_bg"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<View
android:id="@+id/dragger"
android:layout_width="20dip"
android:layout_height="fill_parent"
android:background="@android:color/holo_blue_dark" />
<TextView
android:id="@+id/text"
android:maxLines="2"
android:textColor="?android:textColorPrimary"
android:gravity="left|center_vertical"
android:layout_width="wrap_content"
android:layout_height="44dip"
android:paddingTop="2dip"
android:paddingBottom="2dip"
android:paddingLeft="6dip" />
</LinearLayout>

View File

@ -37,6 +37,7 @@ import android.view.View;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.Button;
import com.mobeta.android.dslv.DragSortListView;
/**
* The playlist activity where playlist songs can be viewed and reordered.
@ -58,7 +59,7 @@ public class PlaylistActivity extends Activity
* An event loop running on a worker thread.
*/
private Looper mLooper;
private DragListView mListView;
private DragSortListView mListView;
private PlaylistAdapter mAdapter;
/**
@ -97,9 +98,10 @@ public class PlaylistActivity extends Activity
setContentView(R.layout.playlist_activity);
DragListView view = (DragListView)findViewById(R.id.list);
DragSortListView view = (DragSortListView)findViewById(R.id.list);
view.setOnItemClickListener(this);
view.setOnCreateContextMenuListener(this);
view.setDropListener(onDrop);
mListView = view;
View header = LayoutInflater.from(this).inflate(R.layout.playlist_buttons, null);
@ -108,7 +110,6 @@ public class PlaylistActivity extends Activity
mDeleteButton = (Button)header.findViewById(R.id.delete);
mDeleteButton.setOnClickListener(this);
view.addHeaderView(header, null, false);
mLooper = thread.getLooper();
mAdapter = new PlaylistAdapter(this, mLooper);
view.setAdapter(mAdapter);
@ -150,7 +151,7 @@ public class PlaylistActivity extends Activity
*/
public void setEditing(boolean editing)
{
mListView.setEditable(editing);
mListView.setDragEnabled(editing);
mAdapter.setEditable(editing);
int visible = editing ? View.GONE : View.VISIBLE;
mDeleteButton.setVisibility(visible);
@ -190,7 +191,7 @@ public class PlaylistActivity extends Activity
Intent intent = new Intent();
intent.putExtra("id", info.id);
intent.putExtra("position", info.position);
intent.putExtra("audioId", (Long)info.targetView.getTag());
intent.putExtra("audioId", (Long)info.targetView.findViewById(R.id.text).getTag());
menu.add(0, MENU_PLAY, 0, R.string.play).setIntent(intent);
menu.add(0, MENU_PLAY_ALL, 0, R.string.play_all).setIntent(intent);
@ -207,7 +208,7 @@ public class PlaylistActivity extends Activity
int pos = intent.getIntExtra("position", -1);
if (itemId == MENU_REMOVE) {
mAdapter.remove(pos - mListView.getHeaderViewsCount());
mAdapter.removeItem(pos - mListView.getHeaderViewsCount());
} else {
performAction(itemId, pos, intent.getLongExtra("audioId", -1));
}
@ -277,4 +278,18 @@ public class PlaylistActivity extends Activity
return super.onOptionsItemSelected(item);
}
}
/**
* Fired from adapter listview if user moved an item
* @param from the item index that was dragged
* @param to the index where the item was dropped
*/
private DragSortListView.DropListener onDrop =
new DragSortListView.DropListener() {
@Override
public void drop(int from, int to) {
mAdapter.moveItem(from, to);
}
};
}

View File

@ -24,10 +24,8 @@ package ch.blinkenlights.android.vanilla;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
@ -38,11 +36,13 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.TextView;
import android.provider.MediaStore.Audio.Playlists.Members;
/**
* CursorAdapter backed by MediaStore playlists.
*/
public class PlaylistAdapter extends CursorAdapter implements Handler.Callback, DragListView.DragAdapter {
public class PlaylistAdapter extends CursorAdapter implements Handler.Callback {
private static final String[] PROJECTION = new String[] {
MediaStore.Audio.Playlists.Members._ID,
MediaStore.Audio.Playlists.Members.TITLE,
@ -55,7 +55,6 @@ public class PlaylistAdapter extends CursorAdapter implements Handler.Callback,
private final Handler mWorkerHandler;
private final Handler mUiHandler;
private final LayoutInflater mInflater;
private final Drawable mExpander;
private long mPlaylistId;
@ -75,7 +74,6 @@ public class PlaylistAdapter extends CursorAdapter implements Handler.Callback,
mUiHandler = new Handler(this);
mWorkerHandler = new Handler(worker, this);
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mExpander = context.getResources().getDrawable(R.drawable.grabber);
}
/**
@ -107,9 +105,10 @@ public class PlaylistAdapter extends CursorAdapter implements Handler.Callback,
@Override
public void bindView(View view, Context context, Cursor cursor)
{
TextView textView = (TextView)view;
View dragger = ((View)view.findViewById(R.id.dragger));
dragger.setVisibility( mEditable ? View.VISIBLE : View.INVISIBLE );
TextView textView = ((TextView)view.findViewById(R.id.text));
textView.setText(cursor.getString(1));
textView.setCompoundDrawablesWithIntrinsicBounds(mEditable ? mExpander : null, null, null, null);
textView.setTag(cursor.getLong(3));
}
@ -162,8 +161,21 @@ public class PlaylistAdapter extends CursorAdapter implements Handler.Callback,
return query.runQuery(resolver);
}
@Override
public void move(int from, int to)
/**
* Moves a song in the playlist
* @param from original position of item
* @param to destination of item
**/
public void moveItem(int from, int to) {
if (from == to)
return;
android.provider.MediaStore.Audio.Playlists.Members.moveItem(mContext.getContentResolver(), mPlaylistId , from, to);
mUiHandler.sendEmptyMessage(MSG_RUN_QUERY);
}
/* fixme: does the move-after-delete bug still exist in 4.x?
public void moveItem(int from, int to)
{
if (from == to)
// easy mode
@ -215,13 +227,14 @@ public class PlaylistAdapter extends CursorAdapter implements Handler.Callback,
changeCursor(runQuery(resolver));
}
@Override
public void remove(int position)
*/
public void removeItem(int position)
{
ContentResolver resolver = mContext.getContentResolver();
Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", mPlaylistId);
resolver.delete(ContentUris.withAppendedId(uri, getItemId(position)), null, null);
changeCursor(runQuery(resolver));
mUiHandler.sendEmptyMessage(MSG_RUN_QUERY);
}
}