First snapshot (beta 0.9)
- playlists working (not all features added yet) - minor fixes and improvements
This commit is contained in:
parent
de15a34365
commit
11ee05ce64
30 changed files with 1055 additions and 126 deletions
|
|
@ -17,14 +17,14 @@ repositories {
|
|||
|
||||
android {
|
||||
compileSdkVersion 22
|
||||
buildToolsVersion "21.1.2"
|
||||
buildToolsVersion "22"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.kabouzeid.gramophone"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 22
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
versionName "0.9b"
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
|
|
|
|||
|
|
@ -36,34 +36,37 @@ MERGED from com.crashlytics.sdk.android:crashlytics:2.2.1:9:5
|
|||
ADDED from AndroidManifest.xml:9:22
|
||||
application
|
||||
ADDED from AndroidManifest.xml:11:5
|
||||
MERGED from com.android.support:appcompat-v7:21.0.3:16:5
|
||||
MERGED from com.android.support:support-v4:21.0.3:16:5
|
||||
MERGED from com.android.support:gridlayout-v7:21.0.3:16:5
|
||||
MERGED from com.android.support:support-v4:21.0.3:16:5
|
||||
MERGED from com.android.support:recyclerview-v7:21.0.3:17:5
|
||||
MERGED from com.android.support:support-v4:21.0.3:16:5
|
||||
MERGED from com.android.support:palette-v7:21.0.3:16:5
|
||||
MERGED from com.android.support:support-v4:21.0.3:16:5
|
||||
MERGED from com.android.support:support-v13:21.0.3:16:5
|
||||
MERGED from com.android.support:support-v4:21.0.3:16:5
|
||||
MERGED from com.afollestad:material-dialogs:0.6.4.1:12:5
|
||||
MERGED from com.android.support:appcompat-v7:22.0.0:22:5
|
||||
MERGED from com.android.support:support-v4:22.0.0:22:5
|
||||
MERGED from com.android.support:recyclerview-v7:22.0.0:22:5
|
||||
MERGED from com.android.support:support-v4:22.0.0:22:5
|
||||
MERGED from com.android.support:appcompat-v7:22.0.0:22:5
|
||||
MERGED from com.android.support:support-v4:22.0.0:22:5
|
||||
MERGED from com.android.support:recyclerview-v7:22.0.0:22:5
|
||||
MERGED from com.android.support:support-v4:22.0.0:22:5
|
||||
MERGED from com.android.support:gridlayout-v7:22.0.0:22:5
|
||||
MERGED from com.android.support:support-v4:22.0.0:22:5
|
||||
MERGED from com.android.support:palette-v7:22.0.0:22:5
|
||||
MERGED from com.android.support:support-v4:22.0.0:22:5
|
||||
MERGED from com.android.support:support-v13:22.0.0:22:5
|
||||
MERGED from com.android.support:support-v4:22.0.0:22:5
|
||||
MERGED from com.android.support:cardview-v7:22.0.0:22:5
|
||||
MERGED from com.nhaarman.listviewanimations:lib-core:3.1.0:26:5
|
||||
MERGED from com.nhaarman.listviewanimations:lib-manipulation:3.1.0:26:5
|
||||
MERGED from com.nhaarman.listviewanimations:lib-core-slh:3.1.0:26:5
|
||||
MERGED from com.melnykov:floatingactionbutton:1.2.0:12:5
|
||||
MERGED from com.android.support:recyclerview-v7:21.0.3:17:5
|
||||
MERGED from com.android.support:support-v4:21.0.3:16:5
|
||||
MERGED from com.android.support:recyclerview-v7:21.0.3:17:5
|
||||
MERGED from com.android.support:support-v4:21.0.3:16:5
|
||||
MERGED from com.afollestad:material-dialogs:0.6.3.0:12:5
|
||||
MERGED from com.android.support:appcompat-v7:21.0.3:16:5
|
||||
MERGED from com.android.support:support-v4:21.0.3:16:5
|
||||
MERGED from com.android.support:recyclerview-v7:22.0.0:22:5
|
||||
MERGED from com.android.support:support-v4:22.0.0:22:5
|
||||
MERGED from com.android.support:recyclerview-v7:22.0.0:22:5
|
||||
MERGED from com.android.support:support-v4:22.0.0:22:5
|
||||
MERGED from com.crashlytics.sdk.android:crashlytics:2.2.1:11:5
|
||||
MERGED from com.crashlytics.sdk.android:answers:1.1.1:9:5
|
||||
MERGED from io.fabric.sdk.android:fabric:1.1.1:9:5
|
||||
MERGED from io.fabric.sdk.android:fabric:1.1.1:9:5
|
||||
MERGED from com.crashlytics.sdk.android:beta:1.1.1:9:5
|
||||
MERGED from io.fabric.sdk.android:fabric:1.1.1:9:5
|
||||
MERGED from com.android.support:support-v4:21.0.3:16:5
|
||||
MERGED from com.android.support:support-v4:22.0.0:22:5
|
||||
android:label
|
||||
ADDED from AndroidManifest.xml:15:9
|
||||
android:allowBackup
|
||||
|
|
@ -74,7 +77,7 @@ MERGED from com.android.support:support-v4:21.0.3:16:5
|
|||
ADDED from AndroidManifest.xml:16:9
|
||||
android:name
|
||||
ADDED from AndroidManifest.xml:12:9
|
||||
activity#gramophone.ui.activities.MainActivity
|
||||
activity#com.kabouzeid.gramophone.ui.activities.MainActivity
|
||||
ADDED from AndroidManifest.xml:17:9
|
||||
android:label
|
||||
ADDED from AndroidManifest.xml:19:13
|
||||
|
|
@ -90,27 +93,27 @@ category#android.intent.category.LAUNCHER
|
|||
ADDED from AndroidManifest.xml:23:17
|
||||
android:name
|
||||
ADDED from AndroidManifest.xml:23:27
|
||||
activity#gramophone.ui.activities.AlbumDetailActivity
|
||||
activity#com.kabouzeid.gramophone.ui.activities.AlbumDetailActivity
|
||||
ADDED from AndroidManifest.xml:26:9
|
||||
android:name
|
||||
ADDED from AndroidManifest.xml:26:19
|
||||
activity#gramophone.ui.activities.ArtistDetailActivity
|
||||
activity#com.kabouzeid.gramophone.ui.activities.ArtistDetailActivity
|
||||
ADDED from AndroidManifest.xml:28:9
|
||||
android:name
|
||||
ADDED from AndroidManifest.xml:28:19
|
||||
activity#gramophone.ui.activities.MusicControllerActivity
|
||||
activity#com.kabouzeid.gramophone.ui.activities.MusicControllerActivity
|
||||
ADDED from AndroidManifest.xml:30:9
|
||||
android:parentActivityName
|
||||
ADDED from AndroidManifest.xml:32:13
|
||||
android:name
|
||||
ADDED from AndroidManifest.xml:31:13
|
||||
service#gramophone.service.MusicService
|
||||
service#com.kabouzeid.gramophone.service.MusicService
|
||||
ADDED from AndroidManifest.xml:35:9
|
||||
android:enabled
|
||||
ADDED from AndroidManifest.xml:37:13
|
||||
android:name
|
||||
ADDED from AndroidManifest.xml:36:13
|
||||
receiver#gramophone.service.MediaButtonIntentReceiver
|
||||
receiver#com.kabouzeid.gramophone.service.MediaButtonIntentReceiver
|
||||
ADDED from AndroidManifest.xml:40:9
|
||||
android:name
|
||||
ADDED from AndroidManifest.xml:40:19
|
||||
|
|
@ -126,7 +129,7 @@ ADDED from AndroidManifest.xml:46:9
|
|||
ADDED from AndroidManifest.xml:48:13
|
||||
android:name
|
||||
ADDED from AndroidManifest.xml:47:13
|
||||
activity#gramophone.ui.activities.tageditor.SongTagEditorActivity
|
||||
activity#com.kabouzeid.gramophone.ui.activities.tageditor.SongTagEditorActivity
|
||||
ADDED from AndroidManifest.xml:50:9
|
||||
android:label
|
||||
ADDED from AndroidManifest.xml:52:13
|
||||
|
|
@ -134,42 +137,67 @@ ADDED from AndroidManifest.xml:50:9
|
|||
ADDED from AndroidManifest.xml:53:13
|
||||
android:name
|
||||
ADDED from AndroidManifest.xml:51:13
|
||||
activity#gramophone.ui.activities.tageditor.AlbumTagEditorActivity
|
||||
activity#com.kabouzeid.gramophone.ui.activities.tageditor.AlbumTagEditorActivity
|
||||
ADDED from AndroidManifest.xml:55:9
|
||||
android:label
|
||||
ADDED from AndroidManifest.xml:57:13
|
||||
android:name
|
||||
ADDED from AndroidManifest.xml:56:13
|
||||
activity#gramophone.ui.activities.SearchActivity
|
||||
activity#com.kabouzeid.gramophone.ui.activities.SearchActivity
|
||||
ADDED from AndroidManifest.xml:59:9
|
||||
android:label
|
||||
ADDED from AndroidManifest.xml:61:13
|
||||
android:name
|
||||
ADDED from AndroidManifest.xml:60:13
|
||||
receiver#com.kabouzeid.gramophone.widget.MusicPlayerWidget
|
||||
ADDED from AndroidManifest.xml:64:9
|
||||
android:name
|
||||
ADDED from AndroidManifest.xml:64:19
|
||||
intent-filter#android.appwidget.action.APPWIDGET_UPDATE
|
||||
ADDED from AndroidManifest.xml:65:13
|
||||
action#android.appwidget.action.APPWIDGET_UPDATE
|
||||
ADDED from AndroidManifest.xml:66:17
|
||||
android:name
|
||||
ADDED from AndroidManifest.xml:66:25
|
||||
meta-data#android.appwidget.provider
|
||||
ADDED from AndroidManifest.xml:69:13
|
||||
android:resource
|
||||
ADDED from AndroidManifest.xml:71:17
|
||||
android:name
|
||||
ADDED from AndroidManifest.xml:70:17
|
||||
activity#com.kabouzeid.gramophone.ui.activities.PlaylistDetailActivity
|
||||
ADDED from AndroidManifest.xml:74:9
|
||||
android:label
|
||||
ADDED from AndroidManifest.xml:76:13
|
||||
android:name
|
||||
ADDED from AndroidManifest.xml:75:13
|
||||
uses-sdk
|
||||
INJECTED from AndroidManifest.xml:0:0 reason: use-sdk injection requested
|
||||
MERGED from com.android.support:appcompat-v7:21.0.3:15:5
|
||||
MERGED from com.android.support:support-v4:21.0.3:15:5
|
||||
MERGED from com.android.support:gridlayout-v7:21.0.3:15:5
|
||||
MERGED from com.android.support:support-v4:21.0.3:15:5
|
||||
MERGED from com.android.support:recyclerview-v7:21.0.3:15:5
|
||||
MERGED from com.android.support:support-v4:21.0.3:15:5
|
||||
MERGED from com.android.support:palette-v7:21.0.3:15:5
|
||||
MERGED from com.android.support:support-v4:21.0.3:15:5
|
||||
MERGED from com.android.support:support-v13:21.0.3:15:5
|
||||
MERGED from com.android.support:support-v4:21.0.3:15:5
|
||||
MERGED from com.afollestad:material-dialogs:0.6.4.1:8:5
|
||||
MERGED from com.android.support:appcompat-v7:22.0.0:20:5
|
||||
MERGED from com.android.support:support-v4:22.0.0:20:5
|
||||
MERGED from com.android.support:recyclerview-v7:22.0.0:20:5
|
||||
MERGED from com.android.support:support-v4:22.0.0:20:5
|
||||
MERGED from com.android.support:appcompat-v7:22.0.0:20:5
|
||||
MERGED from com.android.support:support-v4:22.0.0:20:5
|
||||
MERGED from com.android.support:recyclerview-v7:22.0.0:20:5
|
||||
MERGED from com.android.support:support-v4:22.0.0:20:5
|
||||
MERGED from com.android.support:gridlayout-v7:22.0.0:20:5
|
||||
MERGED from com.android.support:support-v4:22.0.0:20:5
|
||||
MERGED from com.android.support:palette-v7:22.0.0:20:5
|
||||
MERGED from com.android.support:support-v4:22.0.0:20:5
|
||||
MERGED from com.android.support:support-v13:22.0.0:20:5
|
||||
MERGED from com.android.support:support-v4:22.0.0:20:5
|
||||
MERGED from com.android.support:cardview-v7:22.0.0:20:5
|
||||
MERGED from com.nhaarman.listviewanimations:lib-core:3.1.0:22:5
|
||||
MERGED from com.nhaarman.listviewanimations:lib-manipulation:3.1.0:22:5
|
||||
MERGED from com.nhaarman.listviewanimations:lib-core-slh:3.1.0:22:5
|
||||
MERGED from com.melnykov:floatingactionbutton:1.2.0:8:5
|
||||
MERGED from com.android.support:recyclerview-v7:21.0.3:15:5
|
||||
MERGED from com.android.support:support-v4:21.0.3:15:5
|
||||
MERGED from com.github.ksoichiro:android-observablescrollview:1.3.0:21:5
|
||||
MERGED from com.android.support:recyclerview-v7:21.0.3:15:5
|
||||
MERGED from com.android.support:support-v4:21.0.3:15:5
|
||||
MERGED from com.afollestad:material-dialogs:0.6.3.0:8:5
|
||||
MERGED from com.android.support:appcompat-v7:21.0.3:15:5
|
||||
MERGED from com.android.support:support-v4:21.0.3:15:5
|
||||
MERGED from com.android.support:recyclerview-v7:22.0.0:20:5
|
||||
MERGED from com.android.support:support-v4:22.0.0:20:5
|
||||
MERGED from com.github.ksoichiro:android-observablescrollview:1.5.0:21:5
|
||||
MERGED from com.android.support:recyclerview-v7:22.0.0:20:5
|
||||
MERGED from com.android.support:support-v4:22.0.0:20:5
|
||||
MERGED from com.crashlytics.sdk.android:crashlytics:2.2.1:7:5
|
||||
MERGED from com.crashlytics.sdk.android:answers:1.1.1:7:5
|
||||
MERGED from io.fabric.sdk.android:fabric:1.1.1:7:5
|
||||
|
|
@ -177,7 +205,7 @@ MERGED from io.fabric.sdk.android:fabric:1.1.1:7:5
|
|||
MERGED from com.crashlytics.sdk.android:beta:1.1.1:7:5
|
||||
MERGED from io.fabric.sdk.android:fabric:1.1.1:7:5
|
||||
MERGED from asia.ivity.android:drag-sort-listview:1.0:6:5
|
||||
MERGED from com.android.support:support-v4:21.0.3:15:5
|
||||
MERGED from com.android.support:support-v4:22.0.0:20:5
|
||||
android:targetSdkVersion
|
||||
INJECTED from AndroidManifest.xml:0:0
|
||||
INJECTED from AndroidManifest.xml:0:0
|
||||
|
|
@ -185,13 +213,14 @@ MERGED from com.android.support:support-v4:21.0.3:15:5
|
|||
INJECTED from AndroidManifest.xml:0:0
|
||||
INJECTED from AndroidManifest.xml:0:0
|
||||
activity#android.support.v7.widget.TestActivity
|
||||
ADDED from com.android.support:recyclerview-v7:21.0.3:18:9
|
||||
MERGED from com.android.support:recyclerview-v7:21.0.3:18:9
|
||||
MERGED from com.android.support:recyclerview-v7:21.0.3:18:9
|
||||
ADDED from com.android.support:recyclerview-v7:22.0.0:23:9
|
||||
MERGED from com.android.support:recyclerview-v7:22.0.0:23:9
|
||||
MERGED from com.android.support:recyclerview-v7:22.0.0:23:9
|
||||
MERGED from com.android.support:recyclerview-v7:22.0.0:23:9
|
||||
android:label
|
||||
ADDED from com.android.support:recyclerview-v7:21.0.3:18:19
|
||||
ADDED from com.android.support:recyclerview-v7:22.0.0:25:13
|
||||
android:name
|
||||
ADDED from com.android.support:recyclerview-v7:21.0.3:18:60
|
||||
ADDED from com.android.support:recyclerview-v7:22.0.0:24:13
|
||||
activity#com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.SwipeTouchListenerTestActivity
|
||||
ADDED from com.nhaarman.listviewanimations:lib-manipulation:3.1.0:27:9
|
||||
android:name
|
||||
|
|
|
|||
|
|
@ -10,8 +10,10 @@ import android.widget.ArrayAdapter;
|
|||
import android.widget.ImageView;
|
||||
import android.widget.PopupMenu;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.helper.AddToPlaylistDialogHelper;
|
||||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||
import com.kabouzeid.gramophone.helper.SongDetailDialogHelper;
|
||||
import com.kabouzeid.gramophone.loader.SongFilePathLoader;
|
||||
|
|
@ -62,6 +64,12 @@ public class PlayingQueueAdapter extends ArrayAdapter<Song> {
|
|||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_delete_from_disk:
|
||||
Toast.makeText(activity, "This feature is not available yet", Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
case R.id.action_add_to_playlist:
|
||||
AddToPlaylistDialogHelper.getDialog(activity, song).show();
|
||||
return true;
|
||||
case R.id.action_remove_from_playing_queue:
|
||||
MusicPlayerRemote.removeFromQueue(position);
|
||||
notifyDataSetChanged();
|
||||
|
|
|
|||
|
|
@ -8,10 +8,14 @@ import android.view.View;
|
|||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.kabouzeid.gramophone.App;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.model.DataBaseChangedEvent;
|
||||
import com.kabouzeid.gramophone.model.Playlist;
|
||||
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
||||
import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||
import com.kabouzeid.gramophone.util.PlaylistsUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -36,7 +40,7 @@ public class PlaylistAdapter extends RecyclerView.Adapter<PlaylistAdapter.ViewHo
|
|||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||
holder.playlistName.setText(dataSet.get(position).playlistName);
|
||||
holder.playlistName.setText(dataSet.get(position).name);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -44,20 +48,46 @@ public class PlaylistAdapter extends RecyclerView.Adapter<PlaylistAdapter.ViewHo
|
|||
return dataSet.size();
|
||||
}
|
||||
|
||||
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
|
||||
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
|
||||
public TextView playlistName;
|
||||
|
||||
public ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
playlistName = (TextView) itemView.findViewById(R.id.playlist_name);
|
||||
itemView.setOnClickListener(this);
|
||||
itemView.setOnLongClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Pair[] sharedViews = null;
|
||||
if (activity instanceof AbsFabActivity) sharedViews = ((AbsFabActivity)activity).getSharedViewsWithFab(sharedViews);
|
||||
NavigationUtil.goToPlaylist(activity, dataSet.get(getPosition()).id, sharedViews);
|
||||
if (activity instanceof AbsFabActivity)
|
||||
sharedViews = ((AbsFabActivity) activity).getSharedViewsWithFab(sharedViews);
|
||||
NavigationUtil.goToPlaylist(activity, dataSet.get(getAdapterPosition()).id, sharedViews);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View view) {
|
||||
final Playlist playlist = dataSet.get(getAdapterPosition());
|
||||
new MaterialDialog.Builder(activity)
|
||||
.title(activity.getResources().getString(R.string.delete_playlist) + playlist.name)
|
||||
.positiveText(activity.getResources().getString(R.string.ok))
|
||||
.negativeText(activity.getResources().getString(R.string.cancel))
|
||||
.callback(new MaterialDialog.ButtonCallback() {
|
||||
@Override
|
||||
public void onPositive(MaterialDialog dialog) {
|
||||
super.onPositive(dialog);
|
||||
dialog.dismiss();
|
||||
PlaylistsUtil.deletePlaylist(activity, playlist.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNegative(MaterialDialog dialog) {
|
||||
super.onNegative(dialog);
|
||||
dialog.dismiss();
|
||||
}
|
||||
}).show();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,8 +11,10 @@ import android.view.ViewGroup;
|
|||
import android.widget.ImageView;
|
||||
import android.widget.PopupMenu;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.helper.AddToPlaylistDialogHelper;
|
||||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||
import com.kabouzeid.gramophone.helper.SongDetailDialogHelper;
|
||||
import com.kabouzeid.gramophone.loader.SongFilePathLoader;
|
||||
|
|
@ -22,6 +24,7 @@ import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
|||
import com.kabouzeid.gramophone.ui.activities.tageditor.SongTagEditorActivity;
|
||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||
import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||
import com.kabouzeid.gramophone.util.PlaylistsUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
|
@ -75,7 +78,7 @@ public class AlbumSongAdapter extends RecyclerView.Adapter<AlbumSongAdapter.View
|
|||
itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
MusicPlayerRemote.openQueue(dataSet, getPosition(), true);
|
||||
MusicPlayerRemote.openQueue(dataSet, getAdapterPosition(), true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -88,18 +91,24 @@ public class AlbumSongAdapter extends RecyclerView.Adapter<AlbumSongAdapter.View
|
|||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_delete_from_disk:
|
||||
Toast.makeText(activity, "This feature is not available yet", Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
case R.id.action_add_to_playlist:
|
||||
AddToPlaylistDialogHelper.getDialog(activity, dataSet.get(getAdapterPosition())).show();
|
||||
return true;
|
||||
case R.id.action_play_next:
|
||||
MusicPlayerRemote.playNext(dataSet.get(getPosition()));
|
||||
MusicPlayerRemote.playNext(dataSet.get(getAdapterPosition()));
|
||||
return true;
|
||||
case R.id.action_add_to_current_playing:
|
||||
MusicPlayerRemote.enqueue(dataSet.get(getPosition()));
|
||||
MusicPlayerRemote.enqueue(dataSet.get(getAdapterPosition()));
|
||||
case R.id.action_tag_editor:
|
||||
Intent intent = new Intent(activity, SongTagEditorActivity.class);
|
||||
intent.putExtra(AppKeys.E_ID, dataSet.get(getPosition()).id);
|
||||
intent.putExtra(AppKeys.E_ID, dataSet.get(getAdapterPosition()).id);
|
||||
activity.startActivity(intent);
|
||||
return true;
|
||||
case R.id.action_details:
|
||||
String songFilePath = SongFilePathLoader.getSongFilePath(activity, dataSet.get(getPosition()).id);
|
||||
String songFilePath = SongFilePathLoader.getSongFilePath(activity, dataSet.get(getAdapterPosition()).id);
|
||||
File songFile = new File(songFilePath);
|
||||
SongDetailDialogHelper.getDialog(activity, songFile).show();
|
||||
return true;
|
||||
|
|
@ -107,13 +116,13 @@ public class AlbumSongAdapter extends RecyclerView.Adapter<AlbumSongAdapter.View
|
|||
Pair[] albumPairs = null;
|
||||
if (activity instanceof AbsFabActivity)
|
||||
albumPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(albumPairs);
|
||||
NavigationUtil.goToAlbum(activity, dataSet.get(getPosition()).albumId, albumPairs);
|
||||
NavigationUtil.goToAlbum(activity, dataSet.get(getAdapterPosition()).albumId, albumPairs);
|
||||
return true;
|
||||
case R.id.action_go_to_artist:
|
||||
Pair[] artistPairs = null;
|
||||
if (activity instanceof AbsFabActivity)
|
||||
artistPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(artistPairs);
|
||||
NavigationUtil.goToArtist(activity, dataSet.get(getPosition()).artistId, artistPairs);
|
||||
NavigationUtil.goToArtist(activity, dataSet.get(getAdapterPosition()).artistId, artistPairs);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -11,8 +11,10 @@ import android.widget.ArrayAdapter;
|
|||
import android.widget.ImageView;
|
||||
import android.widget.PopupMenu;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.helper.AddToPlaylistDialogHelper;
|
||||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||
import com.kabouzeid.gramophone.helper.SongDetailDialogHelper;
|
||||
import com.kabouzeid.gramophone.loader.SongFilePathLoader;
|
||||
|
|
@ -67,6 +69,12 @@ public class ArtistSongAdapter extends ArrayAdapter<Song> {
|
|||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_delete_from_disk:
|
||||
Toast.makeText(activity, "This feature is not available yet", Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
case R.id.action_add_to_playlist:
|
||||
AddToPlaylistDialogHelper.getDialog(activity, song).show();
|
||||
return true;
|
||||
case R.id.action_play_next:
|
||||
MusicPlayerRemote.playNext(song);
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -11,12 +11,15 @@ import android.view.ViewGroup;
|
|||
import android.widget.ImageView;
|
||||
import android.widget.PopupMenu;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.helper.AddToPlaylistDialogHelper;
|
||||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||
import com.kabouzeid.gramophone.helper.SongDetailDialogHelper;
|
||||
import com.kabouzeid.gramophone.loader.SongFilePathLoader;
|
||||
import com.kabouzeid.gramophone.misc.AppKeys;
|
||||
import com.kabouzeid.gramophone.misc.DragSortRecycler;
|
||||
import com.kabouzeid.gramophone.model.Playlist;
|
||||
import com.kabouzeid.gramophone.model.PlaylistSong;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
|
|
@ -97,6 +100,12 @@ public class PlaylistSongAdapter extends RecyclerView.Adapter<PlaylistSongAdapte
|
|||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_delete_from_disk:
|
||||
Toast.makeText(activity, "This feature is not available yet", Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
case R.id.action_add_to_playlist:
|
||||
AddToPlaylistDialogHelper.getDialog(activity, dataSet.get(getAdapterPosition())).show();
|
||||
return true;
|
||||
case R.id.action_delete_from_playlist:
|
||||
int position = getAdapterPosition();
|
||||
PlaylistsUtil.removeFromPlaylist(activity, dataSet.remove(position));
|
||||
|
|
@ -114,7 +123,7 @@ public class PlaylistSongAdapter extends RecyclerView.Adapter<PlaylistSongAdapte
|
|||
activity.startActivity(intent);
|
||||
return true;
|
||||
case R.id.action_details:
|
||||
String songFilePath = SongFilePathLoader.getSongFilePath(activity, dataSet.get(getPosition()).id);
|
||||
String songFilePath = SongFilePathLoader.getSongFilePath(activity, dataSet.get(getAdapterPosition()).id);
|
||||
File songFile = new File(songFilePath);
|
||||
SongDetailDialogHelper.getDialog(activity, songFile).show();
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -11,8 +11,10 @@ import android.view.ViewGroup;
|
|||
import android.widget.ImageView;
|
||||
import android.widget.PopupMenu;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.helper.AddToPlaylistDialogHelper;
|
||||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||
import com.kabouzeid.gramophone.helper.SongDetailDialogHelper;
|
||||
import com.kabouzeid.gramophone.loader.SongFilePathLoader;
|
||||
|
|
@ -93,6 +95,12 @@ public class SongAdapter extends RecyclerView.Adapter<SongAdapter.ViewHolder> {
|
|||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_delete_from_disk:
|
||||
Toast.makeText(activity, "This feature is not available yet", Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
case R.id.action_add_to_playlist:
|
||||
AddToPlaylistDialogHelper.getDialog(activity, dataSet.get(getAdapterPosition())).show();
|
||||
return true;
|
||||
case R.id.action_play_next:
|
||||
MusicPlayerRemote.playNext(dataSet.get(getPosition()));
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
package com.kabouzeid.gramophone.helper;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.loader.PlaylistLoader;
|
||||
import com.kabouzeid.gramophone.model.Playlist;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
import com.kabouzeid.gramophone.util.PlaylistsUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by karim on 17.03.15.
|
||||
*/
|
||||
public class AddToPlaylistDialogHelper {
|
||||
public static MaterialDialog getDialog(final Context context, final Song song) {
|
||||
List<Song> tmpSong = new ArrayList<>();
|
||||
tmpSong.add(song);
|
||||
return getDialog(context, tmpSong);
|
||||
}
|
||||
|
||||
public static MaterialDialog getDialog(final Context context, final List<Song> songs) {
|
||||
final List<Playlist> playlists = PlaylistLoader.getAllPlaylists(context);
|
||||
CharSequence[] playlistNames = new CharSequence[playlists.size() + 1];
|
||||
playlistNames[0] = context.getResources().getString(R.string.action_new_playlist);
|
||||
for (int i = 1; i < playlistNames.length; i++) {
|
||||
playlistNames[i] = playlists.get(i-1).name;
|
||||
}
|
||||
return new MaterialDialog.Builder(context)
|
||||
.items(playlistNames)
|
||||
.itemsCallback(new MaterialDialog.ListCallback() {
|
||||
@Override
|
||||
public void onSelection(MaterialDialog materialDialog, View view, int i, CharSequence charSequence) {
|
||||
if (i == 0) {
|
||||
materialDialog.dismiss();
|
||||
CreatePlaylistDialogHelper.getDialog(context, songs).show();
|
||||
} else {
|
||||
materialDialog.dismiss();
|
||||
PlaylistsUtil.addToPlaylist(context, songs, playlists.get(i - 1).id);
|
||||
}
|
||||
}
|
||||
})
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
package com.kabouzeid.gramophone.helper;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
import com.kabouzeid.gramophone.util.PlaylistsUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by karim on 17.03.15.
|
||||
*/
|
||||
public class CreatePlaylistDialogHelper {
|
||||
public static MaterialDialog getDialog(final Context context, final Song song) {
|
||||
List<Song> tmpSong = new ArrayList<>();
|
||||
tmpSong.add(song);
|
||||
return getDialog(context, tmpSong);
|
||||
}
|
||||
|
||||
public static MaterialDialog getDialog(final Context context, final List<Song> songs) {
|
||||
final EditText editText = new EditText(context);
|
||||
ViewGroup layout = (ViewGroup) LayoutInflater.from(context).inflate(R.layout.dialog_create_playlist, null);
|
||||
if (editText.getParent() != null) {((ViewGroup) editText.getParent()).removeView(editText);}
|
||||
layout.addView(editText, new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
return new MaterialDialog.Builder(context)
|
||||
.title(context.getResources().getString(R.string.action_new_playlist))
|
||||
.customView(layout, false)
|
||||
.positiveText(context.getResources().getString(R.string.ok))
|
||||
.negativeText(context.getResources().getString(R.string.cancel))
|
||||
.callback(new MaterialDialog.ButtonCallback() {
|
||||
@Override
|
||||
public void onPositive(MaterialDialog dialog) {
|
||||
super.onPositive(dialog);
|
||||
final String playlistName = editText.getText().toString();
|
||||
if (!playlistName.trim().equals("")) {
|
||||
dialog.dismiss();
|
||||
final int playlistId = PlaylistsUtil.createPlaylist(context, playlistName);
|
||||
if (playlistId != -1) {
|
||||
if (songs != null) {
|
||||
PlaylistsUtil.addToPlaylist(context, songs, playlistId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNegative(MaterialDialog dialog) {
|
||||
super.onNegative(dialog);
|
||||
dialog.dismiss();
|
||||
}
|
||||
}
|
||||
)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static MaterialDialog getDialog(final Context context) {
|
||||
return getDialog(context, (List<Song>) null);
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import com.afollestad.materialdialogs.MaterialDialog;
|
|||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.adapter.PlayingQueueAdapter;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
import com.kabouzeid.gramophone.util.PlaylistsUtil;
|
||||
import com.mobeta.android.dslv.DragSortListView;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -16,8 +17,8 @@ import java.util.List;
|
|||
* Created by karim on 24.01.15.
|
||||
*/
|
||||
public class PlayingQueueDialogHelper {
|
||||
public static MaterialDialog getDialog(Activity activity) {
|
||||
List<Song> playingQueue = MusicPlayerRemote.getPlayingQueue();
|
||||
public static MaterialDialog getDialog(final Activity activity) {
|
||||
final List<Song> playingQueue = MusicPlayerRemote.getPlayingQueue();
|
||||
if (playingQueue.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -26,7 +27,7 @@ public class PlayingQueueDialogHelper {
|
|||
.title(activity.getResources().getString(R.string.label_current_playing_queue))
|
||||
.customView(R.layout.dialog_playlist, false)
|
||||
.positiveText(activity.getResources().getString(R.string.close))
|
||||
.negativeText(activity.getResources().getString(R.string.save_as_playlist))
|
||||
.neutralText(activity.getResources().getString(R.string.save_as_playlist))
|
||||
.callback(new MaterialDialog.ButtonCallback() {
|
||||
@Override
|
||||
public void onPositive(MaterialDialog dialog) {
|
||||
|
|
@ -35,8 +36,10 @@ public class PlayingQueueDialogHelper {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onNegative(MaterialDialog dialog) {
|
||||
public void onNeutral(MaterialDialog dialog) {
|
||||
super.onNegative(dialog);
|
||||
dialog.dismiss();
|
||||
AddToPlaylistDialogHelper.getDialog(activity, playingQueue).show();
|
||||
}
|
||||
})
|
||||
.build();
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ public class LastFMAlbumInfoUtil {
|
|||
public static void downloadAlbumInfoJSON(final Context context, final String album, final String artist, final Response.Listener<JSONObject> callbackSuccess, final Response.ErrorListener callbackError) {
|
||||
App app = (App) context.getApplicationContext();
|
||||
String albumUrl = LastFMAlbumInfoUtil.getAlbumUrl(album, artist);
|
||||
JsonObjectRequest albumInfoJSONRequest = new JsonObjectRequest(0, albumUrl, null, new Response.Listener<JSONObject>() {
|
||||
JsonObjectRequest albumInfoJSONRequest = new JsonObjectRequest(0, albumUrl, (JSONObject)null, new Response.Listener<JSONObject>() {
|
||||
@Override
|
||||
public void onResponse(JSONObject response) {
|
||||
LastFMAlbumInfoUtil.saveAlbumJSONDataToCacheAndDisk(context, album, artist, response);
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ public class LastFMArtistBiographyLoader {
|
|||
private static void downloadArtistBio(final Context context, final String artist, final ArtistBioLoaderCallback callback) {
|
||||
App app = (App) context.getApplicationContext();
|
||||
String artistUrl = LastFMArtistInfoUtil.getArtistUrl(artist);
|
||||
JsonObjectRequest artistInfoJSONRequest = new JsonObjectRequest(0, artistUrl, null, new Response.Listener<JSONObject>() {
|
||||
JsonObjectRequest artistInfoJSONRequest = new JsonObjectRequest(0, artistUrl, (JSONObject)null, new Response.Listener<JSONObject>() {
|
||||
@Override
|
||||
public void onResponse(JSONObject response) {
|
||||
LastFMArtistInfoUtil.saveArtistJSONDataToCacheAndDisk(context, artist, response);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package com.kabouzeid.gramophone.lastfm.artist;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
|
||||
|
|
@ -101,7 +100,7 @@ public class LastFMArtistInfoUtil {
|
|||
public static void downloadArtistJSON(final Context context, final String artist, final Response.Listener<JSONObject> callback) {
|
||||
App app = (App) context.getApplicationContext();
|
||||
String artistUrl = LastFMArtistInfoUtil.getArtistUrl(artist);
|
||||
JsonObjectRequest artistInfoJSONRequest = new JsonObjectRequest(0, artistUrl, null, new Response.Listener<JSONObject>() {
|
||||
JsonObjectRequest artistInfoJSONRequest = new JsonObjectRequest(0, artistUrl, (JSONObject)null, new Response.Listener<JSONObject>() {
|
||||
@Override
|
||||
public void onResponse(JSONObject response) {
|
||||
LastFMArtistInfoUtil.saveArtistJSONDataToCacheAndDisk(context, artist, response);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,469 @@
|
|||
/*
|
||||
* DragSortRecycler
|
||||
*
|
||||
* Added drag and drop functionality to your RecyclerView
|
||||
*
|
||||
*
|
||||
* Copyright 2014 Emile Belanger.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.kabouzeid.gramophone.misc;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
|
||||
public class DragSortRecycler extends RecyclerView.ItemDecoration implements RecyclerView.OnItemTouchListener {
|
||||
|
||||
final String TAG = "DragSortRecycler";
|
||||
|
||||
final boolean DEBUG = false;
|
||||
|
||||
private int dragHandleWidth = 0;
|
||||
|
||||
private int selectedDragItemPos = -1;
|
||||
|
||||
private int fingerAnchorY;
|
||||
|
||||
private int fingerY;
|
||||
|
||||
private int fingerOffsetInViewY;
|
||||
|
||||
private float autoScrollWindow = 0.1f;
|
||||
private float autoScrollSpeed = 0.5f;
|
||||
|
||||
private BitmapDrawable floatingItem;
|
||||
private Rect floatingItemStatingBounds;
|
||||
private Rect floatingItemBounds;
|
||||
|
||||
|
||||
private float floatingItemAlpha = 0.5f;
|
||||
private int floatingItemBgColor = 0;
|
||||
|
||||
private int viewHandleId = -1;
|
||||
|
||||
|
||||
OnItemMovedListener moveInterface;
|
||||
|
||||
private boolean isDragging;
|
||||
@Nullable
|
||||
OnDragStateChangedListener dragStateChangedListener;
|
||||
|
||||
|
||||
|
||||
public interface OnItemMovedListener
|
||||
{
|
||||
public void onItemMoved(int from, int to);
|
||||
}
|
||||
|
||||
public interface OnDragStateChangedListener {
|
||||
public void onDragStart();
|
||||
public void onDragStop();
|
||||
}
|
||||
|
||||
private void debugLog(String log)
|
||||
{
|
||||
if (DEBUG)
|
||||
Log.d(TAG, log);
|
||||
}
|
||||
|
||||
public RecyclerView.OnScrollListener getScrollListener()
|
||||
{
|
||||
return scrollListener;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the item move interface
|
||||
*/
|
||||
public void setOnItemMovedListener(OnItemMovedListener swif)
|
||||
{
|
||||
moveInterface = swif;
|
||||
}
|
||||
|
||||
public void setViewHandleId(int id)
|
||||
{
|
||||
viewHandleId = id;
|
||||
}
|
||||
|
||||
public void setLeftDragArea(int w)
|
||||
{
|
||||
dragHandleWidth = w;
|
||||
}
|
||||
|
||||
public void setFloatingAlpha(float a)
|
||||
{
|
||||
floatingItemAlpha = a;
|
||||
}
|
||||
|
||||
public void setFloatingBgColor(int c)
|
||||
{
|
||||
floatingItemBgColor = c;
|
||||
}
|
||||
/*
|
||||
Set the window at top and bottom of list, must be between 0 and 0.5
|
||||
For example 0.1 uses the top and bottom 10% of the lists for scrolling
|
||||
*/
|
||||
public void setAutoScrollWindow(float w)
|
||||
{
|
||||
autoScrollWindow = w;
|
||||
}
|
||||
|
||||
/*
|
||||
Set the autoscroll speed, default is 0.5
|
||||
*/
|
||||
public void setAutoScrollSpeed(float speed)
|
||||
{
|
||||
autoScrollSpeed = speed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getItemOffsets(Rect outRect, View view, RecyclerView rv, RecyclerView.State state) {
|
||||
super.getItemOffsets(outRect, view, rv, state);
|
||||
|
||||
debugLog("getItemOffsets");
|
||||
|
||||
debugLog("View top = " + view.getTop());
|
||||
if (selectedDragItemPos != -1)
|
||||
{
|
||||
int itemPos = rv.getChildPosition(view);
|
||||
debugLog("itemPos =" + itemPos);
|
||||
|
||||
if(!canDragOver(itemPos)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Movement of finger
|
||||
float totalMovement = fingerY-fingerAnchorY;
|
||||
|
||||
if (itemPos == selectedDragItemPos)
|
||||
{
|
||||
view.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Make view visible incase invisible
|
||||
view.setVisibility(View.VISIBLE);
|
||||
|
||||
//Find middle of the floatingItem
|
||||
float floatMiddleY = floatingItemBounds.top + floatingItemBounds.height()/2;
|
||||
|
||||
//Moving down the list
|
||||
//These will auto-animate if the device continually sends touch motion events
|
||||
// if (totalMovment>0)
|
||||
{
|
||||
if ((itemPos > selectedDragItemPos) && (view.getTop() < floatMiddleY))
|
||||
{
|
||||
float amountUp = (floatMiddleY - view.getTop()) / (float)view.getHeight();
|
||||
// amountUp *= 0.5f;
|
||||
if (amountUp > 1)
|
||||
amountUp = 1;
|
||||
|
||||
outRect.top = -(int)(floatingItemBounds.height()*amountUp);
|
||||
outRect.bottom = (int)(floatingItemBounds.height()*amountUp);
|
||||
}
|
||||
|
||||
}//Moving up the list
|
||||
// else if (totalMovment < 0)
|
||||
{
|
||||
if((itemPos < selectedDragItemPos) && (view.getBottom() > floatMiddleY))
|
||||
{
|
||||
float amountDown = ((float)view.getBottom() - floatMiddleY) / (float)view.getHeight();
|
||||
// amountDown *= 0.5f;
|
||||
if (amountDown > 1)
|
||||
amountDown = 1;
|
||||
|
||||
outRect.top = (int)(floatingItemBounds.height()*amountDown);
|
||||
outRect.bottom = -(int)(floatingItemBounds.height()*amountDown);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
outRect.top = 0;
|
||||
outRect.bottom = 0;
|
||||
//Make view visible incase invisible
|
||||
view.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the new position by scanning through the items on
|
||||
* screen and finding the positional relationship.
|
||||
* This *seems* to work, another method would be to use
|
||||
* getItemOffsets, but I think that could miss items?..
|
||||
*/
|
||||
private int getNewPostion(RecyclerView rv)
|
||||
{
|
||||
int itemsOnScreen = rv.getLayoutManager().getChildCount();
|
||||
|
||||
float floatMiddleY = floatingItemBounds.top + floatingItemBounds.height()/2;
|
||||
|
||||
int above=0;
|
||||
int below = Integer.MAX_VALUE;
|
||||
for (int n=0;n < itemsOnScreen;n++) //Scan though items on screen, however they may not
|
||||
{ // be in order!
|
||||
|
||||
View view = rv.getLayoutManager().getChildAt(n);
|
||||
|
||||
if (view.getVisibility() != View.VISIBLE)
|
||||
continue;
|
||||
|
||||
int itemPos = rv.getChildPosition(view);
|
||||
|
||||
if (itemPos == selectedDragItemPos) //Don't check against itself!
|
||||
continue;
|
||||
|
||||
float viewMiddleY = view.getTop() + view.getHeight()/2;
|
||||
if (floatMiddleY > viewMiddleY) //Is above this item
|
||||
{
|
||||
if (itemPos > above)
|
||||
above = itemPos;
|
||||
}
|
||||
else if (floatMiddleY <= viewMiddleY) //Is below this item
|
||||
{
|
||||
if (itemPos < below)
|
||||
below = itemPos;
|
||||
}
|
||||
}
|
||||
debugLog("above = " + above + " below = " + below);
|
||||
|
||||
if (below != Integer.MAX_VALUE) {
|
||||
if (below < selectedDragItemPos) //Need to count itself
|
||||
below++;
|
||||
return below - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (above < selectedDragItemPos)
|
||||
above++;
|
||||
|
||||
return above;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
|
||||
debugLog("onInterceptTouchEvent");
|
||||
|
||||
//if (e.getAction() == MotionEvent.ACTION_DOWN)
|
||||
{
|
||||
View itemView = rv.findChildViewUnder(e.getX(), e.getY());
|
||||
|
||||
if (itemView==null)
|
||||
return false;
|
||||
|
||||
boolean dragging = false;
|
||||
|
||||
if ((dragHandleWidth > 0 ) && (e.getX() < dragHandleWidth))
|
||||
{
|
||||
dragging = true;
|
||||
}
|
||||
else if (viewHandleId != -1)
|
||||
{
|
||||
//Find the handle in the list item
|
||||
View handleView = itemView.findViewById(viewHandleId);
|
||||
|
||||
if (handleView == null)
|
||||
{
|
||||
Log.e(TAG, "The view ID " + viewHandleId + " was not found in the RecycleView item");
|
||||
return false;
|
||||
}
|
||||
|
||||
//View should be visible to drag
|
||||
if(handleView.getVisibility()!=View.VISIBLE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//We need to find the relative position of the handle to the parent view
|
||||
//Then we can work out if the touch is within the handle
|
||||
int[] parentItemPos = new int[2];
|
||||
itemView.getLocationInWindow(parentItemPos);
|
||||
|
||||
int[] handlePos = new int[2];
|
||||
handleView.getLocationInWindow(handlePos);
|
||||
|
||||
int xRel = handlePos[0] - parentItemPos[0];
|
||||
int yRel = handlePos[1] - parentItemPos[1];
|
||||
|
||||
Rect touchBounds = new Rect(itemView.getLeft() + xRel, itemView.getTop() + yRel,
|
||||
itemView.getLeft() + xRel + handleView.getWidth(),
|
||||
itemView.getTop() + yRel + handleView.getHeight()
|
||||
);
|
||||
|
||||
if (touchBounds.contains((int)e.getX(), (int)e.getY()))
|
||||
dragging = true;
|
||||
|
||||
debugLog("parentItemPos = " + parentItemPos[0] + " " + parentItemPos[1]);
|
||||
debugLog("handlePos = " + handlePos[0] + " " + handlePos[1]);
|
||||
}
|
||||
|
||||
|
||||
if (dragging)
|
||||
{
|
||||
debugLog("Started Drag");
|
||||
|
||||
setIsDragging(true);
|
||||
|
||||
floatingItem = createFloatingBitmap(itemView);
|
||||
|
||||
fingerAnchorY = (int)e.getY();
|
||||
fingerOffsetInViewY = fingerAnchorY - itemView.getTop();
|
||||
fingerY = fingerAnchorY;
|
||||
|
||||
selectedDragItemPos = rv.getChildPosition(itemView);
|
||||
debugLog("selectedDragItemPos = " + selectedDragItemPos);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
|
||||
debugLog("onTouchEvent");
|
||||
|
||||
if ((e.getAction() == MotionEvent.ACTION_UP) ||
|
||||
(e.getAction() == MotionEvent.ACTION_CANCEL))
|
||||
{
|
||||
if ((e.getAction() == MotionEvent.ACTION_UP) && selectedDragItemPos != -1)
|
||||
{
|
||||
int newPos = getNewPostion(rv);
|
||||
if (moveInterface != null)
|
||||
moveInterface.onItemMoved(selectedDragItemPos, newPos);
|
||||
}
|
||||
|
||||
setIsDragging(false);
|
||||
selectedDragItemPos = -1;
|
||||
floatingItem = null;
|
||||
rv.invalidateItemDecorations();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
fingerY = (int)e.getY();
|
||||
|
||||
if (floatingItem!=null)
|
||||
{
|
||||
floatingItemBounds.top = fingerY - fingerOffsetInViewY;
|
||||
|
||||
if (floatingItemBounds.top < -floatingItemStatingBounds.height()/2) //Allow half the view out the top
|
||||
floatingItemBounds.top = -floatingItemStatingBounds.height()/2;
|
||||
|
||||
floatingItemBounds.bottom = floatingItemBounds.top + floatingItemStatingBounds.height();
|
||||
|
||||
floatingItem.setBounds(floatingItemBounds);
|
||||
}
|
||||
|
||||
//Do auto scrolling at end of list
|
||||
float scrollAmount=0;
|
||||
if (fingerY > (rv.getHeight() * (1-autoScrollWindow)))
|
||||
{
|
||||
scrollAmount = (fingerY - (rv.getHeight() * (1-autoScrollWindow)));
|
||||
}
|
||||
else if (fingerY < (rv.getHeight() * autoScrollWindow))
|
||||
{
|
||||
scrollAmount = (fingerY - (rv.getHeight() * autoScrollWindow));
|
||||
}
|
||||
debugLog("Scroll: " + scrollAmount);
|
||||
|
||||
scrollAmount *= autoScrollSpeed;
|
||||
rv.scrollBy(0, (int)scrollAmount);
|
||||
|
||||
rv.invalidateItemDecorations();// Redraw
|
||||
}
|
||||
|
||||
private void setIsDragging(final boolean dragging) {
|
||||
if(dragging != isDragging) {
|
||||
isDragging = dragging;
|
||||
if(dragStateChangedListener != null) {
|
||||
if (isDragging) {
|
||||
dragStateChangedListener.onDragStart();
|
||||
} else {
|
||||
dragStateChangedListener.onDragStop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnDragStateChangedListener(final OnDragStateChangedListener dragStateChangedListener) {
|
||||
this.dragStateChangedListener = dragStateChangedListener;
|
||||
}
|
||||
|
||||
|
||||
Paint bgColor = new Paint();
|
||||
@Override
|
||||
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
|
||||
if (floatingItem != null) {
|
||||
floatingItem.setAlpha((int)(255 * floatingItemAlpha));
|
||||
bgColor.setColor(floatingItemBgColor);
|
||||
c.drawRect(floatingItemBounds,bgColor);
|
||||
floatingItem.draw(c);
|
||||
}
|
||||
}
|
||||
|
||||
RecyclerView.OnScrollListener scrollListener = new RecyclerView.OnScrollListener() {
|
||||
@Override
|
||||
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
|
||||
super.onScrollStateChanged(recyclerView, newState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
||||
super.onScrolled(recyclerView, dx, dy);
|
||||
debugLog("Scrolled: " + dx + " " + dy);
|
||||
fingerAnchorY -= dy;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param position
|
||||
* @return True if we can drag the item over this position, False if not.
|
||||
*/
|
||||
protected boolean canDragOver(int position) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private BitmapDrawable createFloatingBitmap(View v)
|
||||
{
|
||||
floatingItemStatingBounds = new Rect(v.getLeft(), v.getTop(),v.getRight(), v.getBottom());
|
||||
floatingItemBounds = new Rect(floatingItemStatingBounds);
|
||||
|
||||
Bitmap bitmap = Bitmap.createBitmap(floatingItemStatingBounds.width(),
|
||||
floatingItemStatingBounds.height(), Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
v.draw(canvas);
|
||||
|
||||
BitmapDrawable retDrawable = new BitmapDrawable(v.getResources(), bitmap);
|
||||
retDrawable.setBounds(floatingItemBounds);
|
||||
|
||||
return retDrawable;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.kabouzeid.gramophone.model;
|
||||
|
||||
/**
|
||||
* Created by karim on 17.03.15.
|
||||
*/
|
||||
public class DataBaseChangedEvent {
|
||||
public static final int PLAYLISTS_CHANGED = 0;
|
||||
public static final int ALBUMS_CHANGED = 1;
|
||||
public static final int ARTISTS_CHANGED = 2;
|
||||
public static final int SONGS_CHANGED = 3;
|
||||
public static final int DATABASE_CHANGED = 4;
|
||||
|
||||
private int action;
|
||||
|
||||
public DataBaseChangedEvent(int action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public int getAction() {
|
||||
return action;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,15 +2,15 @@ package com.kabouzeid.gramophone.model;
|
|||
|
||||
public class Playlist {
|
||||
public int id;
|
||||
public String playlistName;
|
||||
public String name;
|
||||
|
||||
public Playlist(final int id, final String playlistName) {
|
||||
public Playlist(final int id, final String name) {
|
||||
this.id = id;
|
||||
this.playlistName = playlistName;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Playlist() {
|
||||
this.id = -1;
|
||||
this.playlistName = "";
|
||||
this.name = "";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import android.view.MenuItem;
|
|||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableRecyclerView;
|
||||
import com.kabouzeid.gramophone.App;
|
||||
|
|
@ -264,6 +265,7 @@ public class AlbumDetailActivity extends AbsFabActivity {
|
|||
NavigationUtil.openPlayingQueueDialog(this);
|
||||
return true;
|
||||
case R.id.action_settings:
|
||||
Toast.makeText(this, "This feature is not available yet", Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
case R.id.action_current_playing:
|
||||
NavigationUtil.openCurrentPlayingIfPossible(this, getSharedViewsWithFab(null));
|
||||
|
|
|
|||
|
|
@ -326,6 +326,7 @@ public class ArtistDetailActivity extends AbsFabActivity {
|
|||
Toast.makeText(ArtistDetailActivity.this, getResources().getString(R.string.updating), Toast.LENGTH_SHORT).show();
|
||||
setUpArtistImageAndApplyPalette(true);
|
||||
case R.id.action_settings:
|
||||
Toast.makeText(this, "This feature is not available yet", Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
case R.id.action_current_playing:
|
||||
NavigationUtil.openCurrentPlayingIfPossible(this, getSharedViewsWithFab(null));
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import com.afollestad.materialdialogs.MaterialDialog;
|
|||
import com.google.samples.apps.iosched.ui.widget.SlidingTabLayout;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.helper.AboutDeveloperDialogHelper;
|
||||
import com.kabouzeid.gramophone.helper.CreatePlaylistDialogHelper;
|
||||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||
import com.kabouzeid.gramophone.helper.PlayingQueueDialogHelper;
|
||||
import com.kabouzeid.gramophone.interfaces.KabViewsDisableAble;
|
||||
|
|
@ -58,6 +59,7 @@ public class MainActivity extends AbsFabActivity
|
|||
private MainActivityViewPagerAdapter viewPagerAdapter;
|
||||
private ViewPager viewPager;
|
||||
private SlidingTabLayout slidingTabLayout;
|
||||
private int currentPage = -1;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
|
@ -78,6 +80,7 @@ public class MainActivity extends AbsFabActivity
|
|||
viewPagerAdapter = new MainActivityViewPagerAdapter(this);
|
||||
viewPager.setAdapter(viewPagerAdapter);
|
||||
int startPosition = PreferenceUtils.getInstace(this).getStartPage();
|
||||
currentPage = startPosition;
|
||||
viewPager.setCurrentItem(startPosition);
|
||||
navigationDrawerFragment.setItemChecked(startPosition);
|
||||
|
||||
|
|
@ -93,6 +96,8 @@ public class MainActivity extends AbsFabActivity
|
|||
public void onPageSelected(final int position) {
|
||||
PreferenceUtils.getInstace(MainActivity.this).setStartPage(position);
|
||||
navigationDrawerFragment.setItemChecked(position);
|
||||
currentPage = position;
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -210,7 +215,14 @@ public class MainActivity extends AbsFabActivity
|
|||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.drawer, menu);
|
||||
switch (currentPage){
|
||||
case 3:
|
||||
getMenuInflater().inflate(R.menu.menu_playlists, menu);
|
||||
break;
|
||||
default:
|
||||
getMenuInflater().inflate(R.menu.drawer, menu);
|
||||
break;
|
||||
}
|
||||
restoreActionBar();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -229,10 +241,17 @@ public class MainActivity extends AbsFabActivity
|
|||
}
|
||||
int id = item.getItemId();
|
||||
switch (id) {
|
||||
case R.id.action_licenses:
|
||||
Toast.makeText(this, "This feature is not available yet", Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
case R.id.action_new_playlist:
|
||||
CreatePlaylistDialogHelper.getDialog(this).show();
|
||||
return true;
|
||||
case R.id.action_search:
|
||||
startActivity(new Intent(MainActivity.this, SearchActivity.class));
|
||||
return true;
|
||||
case R.id.action_settings:
|
||||
Toast.makeText(this, "This feature is not available yet", Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
case R.id.action_about:
|
||||
AboutDeveloperDialogHelper.getDialog(this).show();
|
||||
|
|
@ -277,7 +296,7 @@ public class MainActivity extends AbsFabActivity
|
|||
context.getResources().getString(R.string.songs),
|
||||
context.getResources().getString(R.string.albums),
|
||||
context.getResources().getString(R.string.artists),
|
||||
context.getResources().getString(R.string.playlists)
|
||||
context.getResources().getString(R.string.playlists) + " BETA"
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,10 +18,9 @@ import android.widget.SeekBar;
|
|||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.helper.AddToPlaylistDialogHelper;
|
||||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||
import com.kabouzeid.gramophone.helper.PlayingQueueDialogHelper;
|
||||
import com.kabouzeid.gramophone.helper.SongDetailDialogHelper;
|
||||
import com.kabouzeid.gramophone.lastfm.artist.LastFMArtistImageUrlLoader;
|
||||
import com.kabouzeid.gramophone.loader.SongFilePathLoader;
|
||||
|
|
@ -388,6 +387,12 @@ public class MusicControllerActivity extends AbsFabActivity {
|
|||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
switch (id) {
|
||||
case R.id.action_settings:
|
||||
Toast.makeText(this, "This feature is not available yet", Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
case R.id.action_add_to_playlist:
|
||||
AddToPlaylistDialogHelper.getDialog(this, song).show();
|
||||
return true;
|
||||
case android.R.id.home:
|
||||
super.onBackPressed();
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -12,10 +12,12 @@ import com.kabouzeid.gramophone.adapter.songadapter.PlaylistSongAdapter;
|
|||
import com.kabouzeid.gramophone.loader.PlaylistLoader;
|
||||
import com.kabouzeid.gramophone.loader.PlaylistSongLoader;
|
||||
import com.kabouzeid.gramophone.misc.AppKeys;
|
||||
import com.kabouzeid.gramophone.misc.DragSortRecycler;
|
||||
import com.kabouzeid.gramophone.model.Playlist;
|
||||
import com.kabouzeid.gramophone.model.PlaylistSong;
|
||||
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
||||
import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||
import com.kabouzeid.gramophone.util.PlaylistsUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -34,10 +36,27 @@ public class PlaylistDetailActivity extends AbsFabActivity {
|
|||
setUpToolBar();
|
||||
|
||||
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
|
||||
List<PlaylistSong> songs = PlaylistSongLoader.getPlaylistSongList(this, playlist.id);
|
||||
PlaylistSongAdapter adapter = new PlaylistSongAdapter(this, songs);
|
||||
final List<PlaylistSong> songs = PlaylistSongLoader.getPlaylistSongList(this, playlist.id);
|
||||
final PlaylistSongAdapter adapter = new PlaylistSongAdapter(this, songs);
|
||||
recyclerView.setLayoutManager(new GridLayoutManager(this, 1));
|
||||
recyclerView.setAdapter(adapter);
|
||||
|
||||
DragSortRecycler dragSortRecycler = new DragSortRecycler();
|
||||
dragSortRecycler.setViewHandleId(R.id.album_art);
|
||||
|
||||
dragSortRecycler.setOnItemMovedListener(new DragSortRecycler.OnItemMovedListener() {
|
||||
@Override
|
||||
public void onItemMoved(int from, int to) {
|
||||
PlaylistSong song = songs.remove(from);
|
||||
songs.add(to, song);
|
||||
adapter.notifyDataSetChanged();
|
||||
PlaylistsUtil.moveItem(PlaylistDetailActivity.this, playlist.id, from, to);
|
||||
}
|
||||
});
|
||||
|
||||
recyclerView.addItemDecoration(dragSortRecycler);
|
||||
recyclerView.addOnItemTouchListener(dragSortRecycler);
|
||||
recyclerView.setOnScrollListener(dragSortRecycler.getScrollListener());
|
||||
}
|
||||
|
||||
private void getIntentExtras() {
|
||||
|
|
@ -51,7 +70,7 @@ public class PlaylistDetailActivity extends AbsFabActivity {
|
|||
|
||||
private void setUpToolBar() {
|
||||
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
|
||||
getSupportActionBar().setTitle(playlist.playlistName);
|
||||
getSupportActionBar().setTitle(playlist.name);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,20 +2,19 @@ package com.kabouzeid.gramophone.ui.fragments.mainactivityfragments;
|
|||
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.app.Fragment;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.kabouzeid.gramophone.App;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.adapter.PlaylistAdapter;
|
||||
import com.kabouzeid.gramophone.adapter.songadapter.SongAdapter;
|
||||
import com.kabouzeid.gramophone.loader.PlaylistLoader;
|
||||
import com.kabouzeid.gramophone.loader.SongLoader;
|
||||
import com.kabouzeid.gramophone.model.DataBaseChangedEvent;
|
||||
import com.kabouzeid.gramophone.model.Playlist;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -37,12 +36,27 @@ public class PlaylistViewFragment extends AbsMainActivityFragment {
|
|||
}
|
||||
|
||||
private void setUpRecyclerView() {
|
||||
List<Playlist> playlists = PlaylistLoader.getAllPlaylists(getActivity());
|
||||
PlaylistAdapter adapter = new PlaylistAdapter(getActivity(), playlists);
|
||||
|
||||
recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 1));
|
||||
recyclerView.setAdapter(adapter);
|
||||
recyclerView.setPadding(0, getTopPadding(), 0, getBottomPadding());
|
||||
setUpAdapter();
|
||||
}
|
||||
|
||||
private void setUpAdapter(){
|
||||
if(recyclerView != null) {
|
||||
List<Playlist> playlists = PlaylistLoader.getAllPlaylists(getActivity());
|
||||
PlaylistAdapter adapter = new PlaylistAdapter(getActivity(), playlists);
|
||||
recyclerView.setAdapter(adapter);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onDataBaseEvent(DataBaseChangedEvent event) {
|
||||
switch (event.getAction()) {
|
||||
case DataBaseChangedEvent.PLAYLISTS_CHANGED:
|
||||
case DataBaseChangedEvent.DATABASE_CHANGED:
|
||||
setUpAdapter();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -56,4 +70,16 @@ public class PlaylistViewFragment extends AbsMainActivityFragment {
|
|||
super.disableViews();
|
||||
recyclerView.setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
App.bus.register(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
App.bus.unregister(this);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,9 +5,13 @@ import android.content.ContentValues;
|
|||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.provider.BaseColumns;
|
||||
import android.provider.MediaStore;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.kabouzeid.gramophone.App;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.model.DataBaseChangedEvent;
|
||||
import com.kabouzeid.gramophone.model.PlaylistSong;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
|
||||
|
|
@ -18,6 +22,9 @@ import java.util.List;
|
|||
* Created by karim on 16.03.15.
|
||||
*/
|
||||
public class PlaylistsUtil {
|
||||
public static final String MUSIC_ONLY_SELECTION = MediaStore.Audio.AudioColumns.IS_MUSIC + "=1"
|
||||
+ " AND " + MediaStore.Audio.AudioColumns.TITLE + " != ''"; //$NON-NLS-2$
|
||||
|
||||
public static int createPlaylist(final Context context, final String name) {
|
||||
if (name != null && name.length() > 0) {
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
|
|
@ -32,55 +39,93 @@ public class PlaylistsUtil {
|
|||
values.put(MediaStore.Audio.PlaylistsColumns.NAME, name);
|
||||
final Uri uri = resolver.insert(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,
|
||||
values);
|
||||
return Integer.parseInt(uri.getLastPathSegment());
|
||||
cursor.close();
|
||||
if (uri != null) {
|
||||
Toast.makeText(context, context.getResources().getString(R.string.created_playlist) + name, Toast.LENGTH_SHORT).show();
|
||||
App.bus.post(new DataBaseChangedEvent(DataBaseChangedEvent.PLAYLISTS_CHANGED));
|
||||
return Integer.parseInt(uri.getLastPathSegment());
|
||||
}
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
Toast.makeText(context, context.getResources().getString(R.string.create_playlist_failed) + name, Toast.LENGTH_SHORT).show();
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static void deletePlaylist(final Context context, final int playlistId) {
|
||||
public static void clearPlaylist(final Context context, final int playlistId) {
|
||||
final Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId);
|
||||
context.getContentResolver().delete(uri, null, null);
|
||||
}
|
||||
|
||||
public static void addToPlaylist(final Context context, final Song song, final long playlistId) {
|
||||
public static void deletePlaylist(final Context context, final int playlistId) {
|
||||
final Uri uri = MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI;
|
||||
String where = MediaStore.Audio.Playlists._ID + "=?";
|
||||
String[] whereVal = {String.valueOf(playlistId)};
|
||||
context.getContentResolver().delete(uri, where, whereVal);
|
||||
Toast.makeText(context, context.getResources().getString(R.string.deleted_playlist) + getNameForPlaylist(context, playlistId), Toast.LENGTH_SHORT).show();
|
||||
App.bus.post(new DataBaseChangedEvent(DataBaseChangedEvent.PLAYLISTS_CHANGED));
|
||||
}
|
||||
|
||||
public static void addToPlaylist(final Context context, final Song song, final int playlistId) {
|
||||
List<Song> helperList = new ArrayList<>();
|
||||
helperList.add(song);
|
||||
addToPlaylist(context, helperList, playlistId);
|
||||
}
|
||||
|
||||
public static void addToPlaylist(final Context context, final List<Song> songs, final long playlistId) {
|
||||
public static void addToPlaylist(final Context context, final List<Song> songs, final int playlistId) {
|
||||
final int size = songs.size();
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
|
||||
final String[] projection = new String[]{
|
||||
MediaStore.Audio.PlaylistsColumns.NAME
|
||||
"max(" + MediaStore.Audio.Playlists.Members.PLAY_ORDER + ")",
|
||||
};
|
||||
|
||||
final Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId);
|
||||
Cursor cursor = resolver.query(uri, projection, null, null, null);
|
||||
cursor.moveToFirst();
|
||||
final String playlistName = cursor.getString(0);
|
||||
cursor.close();
|
||||
Cursor cursor = null;
|
||||
int base = 0;
|
||||
|
||||
ContentValues[] contentValues = new ContentValues[songs.size()];
|
||||
for (int i = 0; i < songs.size(); i++) {
|
||||
contentValues[i] = new ContentValues();
|
||||
contentValues[i].put(MediaStore.Audio.Playlists.Members.AUDIO_ID, songs.get(i).id);
|
||||
try {
|
||||
cursor = resolver.query(uri, projection, null, null, null);
|
||||
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
base = cursor.getInt(0) + 1;
|
||||
}
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
resolver.bulkInsert(uri, contentValues);
|
||||
Toast.makeText(context, "Added " + contentValues.length + " songs to playlist " + playlistName, Toast.LENGTH_SHORT).show();
|
||||
//TODO add string resource
|
||||
int numinserted = 0;
|
||||
for (int offSet = 0; offSet < size; offSet += 1000) {
|
||||
numinserted += resolver.bulkInsert(uri, makeInsertItems(songs, offSet, 1000, base));
|
||||
}
|
||||
|
||||
Toast.makeText(context, context.getResources().getString(R.string.inserted_titles_to_playlist_1) + numinserted + context.getResources().getString(R.string.inserted_titles_to_playlist_2) + getNameForPlaylist(context, playlistId) + ".", Toast.LENGTH_SHORT).show();
|
||||
App.bus.post(new DataBaseChangedEvent(DataBaseChangedEvent.PLAYLISTS_CHANGED));
|
||||
}
|
||||
|
||||
public static ContentValues[] makeInsertItems(final List<Song> songs, final int offset, int len, final int base) {
|
||||
if (offset + len > songs.size()) {
|
||||
len = songs.size() - offset;
|
||||
}
|
||||
|
||||
ContentValues[] contentValues = new ContentValues[len];
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
contentValues[i] = new ContentValues();
|
||||
contentValues[i].put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, base + offset + i);
|
||||
contentValues[i].put(MediaStore.Audio.Playlists.Members.AUDIO_ID, songs.get(offset + i).id);
|
||||
}
|
||||
return contentValues;
|
||||
}
|
||||
|
||||
public static void removeFromPlaylist(final Context context, final PlaylistSong song) {
|
||||
Uri uri = MediaStore.Audio.Playlists.Members.getContentUri(
|
||||
"external", song.playlistId);
|
||||
String selection = MediaStore.Audio.Playlists.Members._ID+ " =?";
|
||||
String selection = MediaStore.Audio.Playlists.Members._ID + " =?";
|
||||
String[] selectionArgs = new String[]{String.valueOf(song.idInPlayList)};
|
||||
|
||||
context.getContentResolver().delete(uri, selection, selectionArgs);
|
||||
App.bus.post(new DataBaseChangedEvent(DataBaseChangedEvent.PLAYLISTS_CHANGED));
|
||||
}
|
||||
|
||||
public static void removeFromPlaylist(final Context context, final List<PlaylistSong> songs) {
|
||||
|
|
@ -95,5 +140,47 @@ public class PlaylistsUtil {
|
|||
selection = selection.substring(0, selection.length() - 2) + ")";
|
||||
|
||||
context.getContentResolver().delete(uri, selection, selectionArgs);
|
||||
App.bus.post(new DataBaseChangedEvent(DataBaseChangedEvent.PLAYLISTS_CHANGED));
|
||||
}
|
||||
|
||||
public static int getSongCountForPlaylist(final Context context, final long playlistId) {
|
||||
Cursor c = context.getContentResolver().query(
|
||||
MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId),
|
||||
new String[]{BaseColumns._ID}, MUSIC_ONLY_SELECTION, null, null);
|
||||
|
||||
if (c != null) {
|
||||
int count = 0;
|
||||
if (c.moveToFirst()) {
|
||||
count = c.getCount();
|
||||
}
|
||||
c.close();
|
||||
return count;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static void moveItem(final Context context, int playlistId, int from, int to) {
|
||||
MediaStore.Audio.Playlists.Members.moveItem(context.getContentResolver(),
|
||||
playlistId, from, to);
|
||||
}
|
||||
|
||||
public static String getNameForPlaylist(final Context context, final int id) {
|
||||
Cursor cursor = context.getContentResolver().query(
|
||||
MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,
|
||||
new String[]{MediaStore.Audio.PlaylistsColumns.NAME},
|
||||
BaseColumns._ID + "=?",
|
||||
new String[]{String.valueOf(id)},
|
||||
null);
|
||||
if (cursor != null) {
|
||||
try {
|
||||
if (cursor.moveToFirst()) {
|
||||
return cursor.getString(0);
|
||||
}
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
9
app/src/main/res/layout/dialog_create_playlist.xml
Normal file
9
app/src/main/res/layout/dialog_create_playlist.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="start"
|
||||
android:paddingLeft="@dimen/md_dialog_frame_margin"
|
||||
android:paddingRight="@dimen/md_dialog_frame_margin">
|
||||
</LinearLayout>
|
||||
|
|
@ -4,13 +4,13 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="4dp"
|
||||
android:elevation="3dp"
|
||||
android:foreground="?rect_selector">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="4dp"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@
|
|||
app:showAsAction="always"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_search"
|
||||
android:icon="@drawable/abc_ic_search_api_mtrl_alpha"
|
||||
android:title="@string/action_search"
|
||||
app:showAsAction="ifRoom"/>
|
||||
android:id="@+id/action_search"
|
||||
android:icon="@drawable/abc_ic_search_api_mtrl_alpha"
|
||||
android:title="@string/action_search"
|
||||
app:showAsAction="ifRoom"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_playing_queue"
|
||||
|
|
@ -29,8 +29,14 @@
|
|||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_about"
|
||||
android:orderInCategory="101"
|
||||
android:id="@+id/action_licenses"
|
||||
android:title="Open Source Licenses"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_about"
|
||||
android:orderInCategory="102"
|
||||
android:title="@string/action_about"
|
||||
app:showAsAction="never"/>
|
||||
</menu>
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/action_settings"
|
||||
android:orderInCategory="100"
|
||||
android:title="@string/action_settings"
|
||||
app:showAsAction="never"/>
|
||||
</menu>
|
||||
45
app/src/main/res/menu/menu_playlists.xml
Normal file
45
app/src/main/res/menu/menu_playlists.xml
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/action_current_playing"
|
||||
android:icon="@drawable/music_box"
|
||||
android:title="@string/action_current_playing"
|
||||
app:showAsAction="always"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_search"
|
||||
android:icon="@drawable/abc_ic_search_api_mtrl_alpha"
|
||||
android:title="@string/action_search"
|
||||
app:showAsAction="ifRoom"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_new_playlist"
|
||||
android:title="@string/action_new_playlist"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_playing_queue"
|
||||
android:icon="@drawable/ic_queue_music_white_24dp"
|
||||
android:title="@string/action_playing_queue"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_settings"
|
||||
android:icon="@drawable/settings"
|
||||
android:orderInCategory="100"
|
||||
android:title="@string/action_settings"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_licenses"
|
||||
android:orderInCategory="101"
|
||||
android:title="Open Source Licenses"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_about"
|
||||
android:orderInCategory="102"
|
||||
android:title="@string/action_about"
|
||||
app:showAsAction="never"/>
|
||||
</menu>
|
||||
|
|
@ -73,8 +73,16 @@
|
|||
<string name="loading">Loading…</string>
|
||||
<string name="added_title_to_playing_queue">Added 1 title to the playing queue.</string>
|
||||
<string name="added_titles_to_playing_queue_1">Added </string>
|
||||
<string name="added_titles_to_playing_queue_2"> titles to the playing queue.</string>
|
||||
<string name="added_titles_to_playing_queue_2">\u0020titles to the playing queue.</string>
|
||||
<string name="title_activity_playlist_detail">PlaylistDetailActivity</string>
|
||||
<string name="action_delete_from_playlist">Delete from playlist</string>
|
||||
<string name="inserted_titles_to_playlist_1">Inserted\u0020</string>
|
||||
<string name="inserted_titles_to_playlist_2">\u0020titles to playlist\u0020</string>
|
||||
<string name="action_new_playlist">New playlist</string>
|
||||
<string name="cancel">Cancel</string>
|
||||
<string name="created_playlist">Created playlist\u0020</string>
|
||||
<string name="deleted_playlist">Deleted playlist\u0020</string>
|
||||
<string name="create_playlist_failed">Could not create playlist\u0020</string>
|
||||
<string name="delete_playlist">Delete playlist\u0020</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue