aboutsummaryrefslogtreecommitdiff
path: root/app/src/main
diff options
context:
space:
mode:
authorScott Jackson <daneren2005@gmail.com>2015-06-09 17:46:37 -0700
committerScott Jackson <daneren2005@gmail.com>2015-06-09 17:46:37 -0700
commit9d4876f4874d034177c4f012932ca936d85e40ac (patch)
tree05a4db08bf5f8471d42dd2a1a8ba352d16b447b7 /app/src/main
parent6caaca0cecd9f4f60f695a68c72eb662b4a45b34 (diff)
parent9f8e9b89bb2d564bcaf00309b38ed9c4d970aeb9 (diff)
downloaddsub-9d4876f4874d034177c4f012932ca936d85e40ac.tar.gz
dsub-9d4876f4874d034177c4f012932ca936d85e40ac.tar.bz2
dsub-9d4876f4874d034177c4f012932ca936d85e40ac.zip
Merge branch 'SlideUpPanel2' into NavigationView
Conflicts: app/src/main/java/github/daneren2005/dsub/activity/SubsonicFragmentActivity.java
Diffstat (limited to 'app/src/main')
-rw-r--r--app/src/main/java/github/daneren2005/dsub/adapter/DownloadFileAdapter.java37
-rw-r--r--app/src/main/java/github/daneren2005/dsub/adapter/EntryAdapter.java82
-rw-r--r--app/src/main/java/github/daneren2005/dsub/adapter/SectionAdapter.java17
-rw-r--r--app/src/main/java/github/daneren2005/dsub/adapter/SettingsAdapter.java77
-rw-r--r--app/src/main/java/github/daneren2005/dsub/fragments/DownloadFragment.java25
-rw-r--r--app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java140
-rw-r--r--app/src/main/java/github/daneren2005/dsub/fragments/SelectListFragment.java163
-rw-r--r--app/src/main/java/github/daneren2005/dsub/fragments/SelectVideoFragment.java2
-rw-r--r--app/src/main/java/github/daneren2005/dsub/fragments/UserFragment.java99
-rw-r--r--app/src/main/java/github/daneren2005/dsub/service/DownloadService.java7
-rw-r--r--app/src/main/java/github/daneren2005/dsub/util/UserUtil.java12
-rw-r--r--app/src/main/java/github/daneren2005/dsub/view/SettingView.java55
-rw-r--r--app/src/main/res/layout/basic_choice_item.xml26
-rw-r--r--app/src/main/res/layout/create_user.xml5
-rw-r--r--app/src/main/res/layout/download_playlist.xml33
-rw-r--r--app/src/main/res/layout/select_album_header.xml6
-rw-r--r--app/src/main/res/layout/select_artist_header.xml5
-rw-r--r--app/src/main/res/layout/user_header.xml6
-rw-r--r--app/src/main/res/values/styles.xml17
19 files changed, 333 insertions, 481 deletions
diff --git a/app/src/main/java/github/daneren2005/dsub/adapter/DownloadFileAdapter.java b/app/src/main/java/github/daneren2005/dsub/adapter/DownloadFileAdapter.java
index be9b4cb9..7e926d51 100644
--- a/app/src/main/java/github/daneren2005/dsub/adapter/DownloadFileAdapter.java
+++ b/app/src/main/java/github/daneren2005/dsub/adapter/DownloadFileAdapter.java
@@ -24,26 +24,33 @@ import java.util.List;
import github.daneren2005.dsub.service.DownloadFile;
import github.daneren2005.dsub.view.SongView;
+import github.daneren2005.dsub.view.UpdateView;
-public class DownloadFileAdapter extends ArrayAdapter<DownloadFile> {
- Context context;
+public class DownloadFileAdapter extends SectionAdapter<DownloadFile> {
+ public static int VIEW_TYPE_DOWNLOAD_FILE = 1;
public DownloadFileAdapter(Context context, List<DownloadFile> entries) {
- super(context, android.R.layout.simple_list_item_1, entries);
- this.context = context;
+ super(context, entries);
+ }
+ public DownloadFileAdapter(Context context, List<DownloadFile> entries, OnItemClickedListener onItemClickedListener) {
+ super(context, entries);
+ this.onItemClickedListener = onItemClickedListener;
+ }
+
+ @Override
+ public UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) {
+ return new UpdateView.UpdateViewHolder(new SongView(context));
+ }
+
+ @Override
+ public void onBindViewHolder(UpdateView.UpdateViewHolder holder, DownloadFile item, int viewType) {
+ SongView songView = (SongView) holder.getUpdateView();
+ songView.setObject(item.getSong(), false);
+ songView.setDownloadFile(item);
}
@Override
- public View getView(int position, View convertView, ViewGroup parent) {
- SongView view;
- if (convertView != null && convertView instanceof SongView) {
- view = (SongView) convertView;
- } else {
- view = new SongView(context);
- }
- DownloadFile downloadFile = getItem(position);
- view.setObject(downloadFile.getSong(), false);
- view.setDownloadFile(downloadFile);
- return view;
+ public int getItemViewType(DownloadFile item) {
+ return VIEW_TYPE_DOWNLOAD_FILE;
}
}
diff --git a/app/src/main/java/github/daneren2005/dsub/adapter/EntryAdapter.java b/app/src/main/java/github/daneren2005/dsub/adapter/EntryAdapter.java
deleted file mode 100644
index 9cc96ae0..00000000
--- a/app/src/main/java/github/daneren2005/dsub/adapter/EntryAdapter.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic 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.
-
- Subsonic 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.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2010 (C) Sindre Mehus
- */
-package github.daneren2005.dsub.adapter;
-
-import android.content.Context;
-
-import java.util.List;
-
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import github.daneren2005.dsub.domain.MusicDirectory;
-import github.daneren2005.dsub.util.ImageLoader;
-import github.daneren2005.dsub.view.AlbumView;
-import github.daneren2005.dsub.view.ArtistEntryView;
-import github.daneren2005.dsub.view.SongView;
-
-/**
- * @author Sindre Mehus
- */
-public class EntryAdapter extends ArrayAdapter<MusicDirectory.Entry> {
- private final static String TAG = EntryAdapter.class.getSimpleName();
- private final Context activity;
- private final ImageLoader imageLoader;
- private final boolean checkable;
- private List<MusicDirectory.Entry> entries;
-
- public EntryAdapter(Context activity, ImageLoader imageLoader, List<MusicDirectory.Entry> entries, boolean checkable) {
- super(activity, android.R.layout.simple_list_item_1, entries);
- this.entries = entries;
- this.activity = activity;
- this.imageLoader = imageLoader;
- this.checkable = checkable;
- }
-
- public void removeAt(int position) {
- entries.remove(position);
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- MusicDirectory.Entry entry = getItem(position);
-
- if (entry.isDirectory()) {
- if(entry.isAlbum()) {
- AlbumView view;
- view = new AlbumView(activity, false);
- view.setObject(entry, imageLoader);
- return view;
- } else {
- ArtistEntryView view = new ArtistEntryView(activity);
- view.setObject(entry);
- return view;
- }
- } else {
- SongView view;
- if (convertView != null && convertView instanceof SongView) {
- view = (SongView) convertView;
- } else {
- view = new SongView(activity);
- }
- view.setObject(entry, checkable);
- return view;
- }
- }
-}
diff --git a/app/src/main/java/github/daneren2005/dsub/adapter/SectionAdapter.java b/app/src/main/java/github/daneren2005/dsub/adapter/SectionAdapter.java
index 8d9a8682..599870d7 100644
--- a/app/src/main/java/github/daneren2005/dsub/adapter/SectionAdapter.java
+++ b/app/src/main/java/github/daneren2005/dsub/adapter/SectionAdapter.java
@@ -224,6 +224,23 @@ public abstract class SectionAdapter<T> extends RecyclerView.Adapter<UpdateViewH
return null;
}
+ public int getItemPosition(T item) {
+ if(sections.size() == 1 && !singleSectionHeader) {
+ return sections.get(0).indexOf(item);
+ }
+
+ int subPosition = 0;
+ for(List<T> section: sections) {
+ subPosition += section.size() + 1;
+
+ int position = section.indexOf(item);
+ if(position != -1) {
+ return position + subPosition;
+ }
+ }
+
+ return -1;
+ }
public void setContextItem(UpdateView updateView, T item) {
contextView = updateView;
diff --git a/app/src/main/java/github/daneren2005/dsub/adapter/SettingsAdapter.java b/app/src/main/java/github/daneren2005/dsub/adapter/SettingsAdapter.java
index 45c3ead1..d99b294b 100644
--- a/app/src/main/java/github/daneren2005/dsub/adapter/SettingsAdapter.java
+++ b/app/src/main/java/github/daneren2005/dsub/adapter/SettingsAdapter.java
@@ -16,44 +16,83 @@
package github.daneren2005.dsub.adapter;
import android.content.Context;
+import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
import java.util.List;
import github.daneren2005.dsub.R;
import github.daneren2005.dsub.domain.User;
+import github.daneren2005.dsub.util.ImageLoader;
import github.daneren2005.dsub.view.SettingView;
+import github.daneren2005.dsub.view.UpdateView;
import static github.daneren2005.dsub.domain.User.Setting;
-public class SettingsAdapter extends ArrayAdapter<Setting> {
- private final Context context;
+public class SettingsAdapter extends SectionAdapter<Setting> {
+ public final int VIEW_TYPE_SETTING = 1;
+
+ private final User user;
private final boolean editable;
+ private final ImageLoader imageLoader;
- public SettingsAdapter(Context context, User user, boolean editable) {
- super(context, R.layout.basic_list_item, user.getSettings());
- this.context = context;
+ public SettingsAdapter(Context context, User user, ImageLoader imageLoader, boolean editable) {
+ super(context, user.getSettings(), imageLoader != null);
+ this.user = user;
+ this.imageLoader = imageLoader;
this.editable = editable;
+
+ List<Setting> settings = sections.get(0);
+ for(Setting setting: settings) {
+ if(setting.getValue()) {
+ addSelected(setting);
+ }
+ }
}
- public SettingsAdapter(Context context, List<Setting> settings, boolean editable) {
- super(context, R.layout.basic_list_item, settings);
- this.context = context;
- this.editable = editable;
+ public UpdateView.UpdateViewHolder onCreateHeaderHolder(ViewGroup parent) {
+ View header = LayoutInflater.from(context).inflate(R.layout.user_header, parent, false);
+ return new UpdateView.UpdateViewHolder(header, false);
}
+ public void onBindHeaderHolder(UpdateView.UpdateViewHolder holder, String description) {
+ View header = holder.getView();
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- Setting entry = getItem(position);
- SettingView view;
- if (convertView != null && convertView instanceof SettingView) {
- view = (SettingView) convertView;
+ ImageView coverArtView = (ImageView) header.findViewById(R.id.user_avatar);
+ imageLoader.loadAvatar(context, coverArtView, user.getUsername());
+
+ TextView usernameView = (TextView) header.findViewById(R.id.user_username);
+ usernameView.setText(user.getUsername());
+
+ final TextView emailView = (TextView) header.findViewById(R.id.user_email);
+ if(user.getEmail() != null) {
+ emailView.setText(user.getEmail());
} else {
- view = new SettingView(context);
+ emailView.setVisibility(View.GONE);
+ }
+ }
+
+ @Override
+ public UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) {
+ return new UpdateView.UpdateViewHolder(new SettingView(context));
+ }
+
+ @Override
+ public void onBindViewHolder(UpdateView.UpdateViewHolder holder, Setting item, int viewType) {
+ holder.getUpdateView().setObject(item, editable);
+ }
+
+ @Override
+ public int getItemViewType(Setting item) {
+ return VIEW_TYPE_SETTING;
+ }
+
+ @Override
+ public void setChecked(UpdateView updateView, boolean checked) {
+ if(updateView instanceof SettingView) {
+ ((SettingView) updateView).setChecked(checked);
}
- view.setObject(entry, editable);
- return view;
}
}
diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/DownloadFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/DownloadFragment.java
index 59229c3f..5a3d63ad 100644
--- a/app/src/main/java/github/daneren2005/dsub/fragments/DownloadFragment.java
+++ b/app/src/main/java/github/daneren2005/dsub/fragments/DownloadFragment.java
@@ -30,6 +30,7 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import github.daneren2005.dsub.R;
+import github.daneren2005.dsub.adapter.SectionAdapter;
import github.daneren2005.dsub.domain.MusicDirectory;
import github.daneren2005.dsub.service.DownloadFile;
import github.daneren2005.dsub.service.DownloadService;
@@ -38,13 +39,15 @@ import github.daneren2005.dsub.util.ProgressListener;
import github.daneren2005.dsub.util.SilentBackgroundTask;
import github.daneren2005.dsub.util.Util;
import github.daneren2005.dsub.adapter.DownloadFileAdapter;
+import github.daneren2005.dsub.view.UpdateView;
-public class DownloadFragment extends SelectListFragment<DownloadFile> {
+public class DownloadFragment extends SelectRecyclerFragment<DownloadFile> {
private long currentRevision;
private ScheduledExecutorService executorService;
public DownloadFragment() {
serialize = false;
+ pullToRefresh = false;
}
@Override
@@ -80,7 +83,7 @@ public class DownloadFragment extends SelectListFragment<DownloadFile> {
}
@Override
- public ArrayAdapter getAdapter(List<DownloadFile> objs) {
+ public SectionAdapter getAdapter(List<DownloadFile> objs) {
return new DownloadFileAdapter(context, objs);
}
@@ -91,9 +94,6 @@ public class DownloadFragment extends SelectListFragment<DownloadFile> {
return new ArrayList<DownloadFile>();
}
- listView.setOnScrollListener(null);
- refreshLayout.setEnabled(false);
-
List<DownloadFile> songList = new ArrayList<DownloadFile>();
songList.addAll(downloadService.getBackgroundDownloads());
currentRevision = downloadService.getDownloadListUpdateRevision();
@@ -106,7 +106,7 @@ public class DownloadFragment extends SelectListFragment<DownloadFile> {
}
@Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ public void onItemClicked(DownloadFile item) {
}
@@ -144,11 +144,13 @@ public class DownloadFragment extends SelectListFragment<DownloadFile> {
@Override
public void onCreateContextMenu(android.view.ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, view, menuInfo);
+ UpdateView targetView = adapter.getContextView();
+ menuInfo = new AdapterView.AdapterContextMenuInfo(targetView, 0, 0);
- AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
- Object selectedItem = ((DownloadFile) listView.getItemAtPosition(info.position)).getSong();
+ DownloadFile downloadFile = adapter.getContextItem();
+ MusicDirectory.Entry selectedItem = downloadFile.getSong();
onCreateContextMenu(menu, view, menuInfo, selectedItem);
- if(selectedItem instanceof MusicDirectory.Entry && !((MusicDirectory.Entry) selectedItem).isVideo() && !Util.isOffline(context)) {
+ if(!selectedItem.isVideo() && !Util.isOffline(context)) {
menu.removeItem(R.id.song_menu_remove_playlist);
}
@@ -161,9 +163,8 @@ public class DownloadFragment extends SelectListFragment<DownloadFile> {
return false;
}
- AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuItem.getMenuInfo();
- Object selectedItem = ((DownloadFile) listView.getItemAtPosition(info.position)).getSong();
-
+ DownloadFile downloadFile = adapter.getContextItem();
+ MusicDirectory.Entry selectedItem = downloadFile.getSong();
if(onContextItemSelected(menuItem, selectedItem)) {
return true;
}
diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java
index b9ef412c..851e9478 100644
--- a/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java
+++ b/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java
@@ -31,6 +31,9 @@ import android.os.Bundle;
import android.os.Handler;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.MediaRouteButton;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.helper.ItemTouchHelper;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Display;
@@ -55,6 +58,7 @@ import android.widget.TextView;
import android.widget.ViewFlipper;
import github.daneren2005.dsub.R;
import github.daneren2005.dsub.activity.SubsonicFragmentActivity;
+import github.daneren2005.dsub.adapter.SectionAdapter;
import github.daneren2005.dsub.audiofx.EqualizerController;
import github.daneren2005.dsub.domain.Bookmark;
import github.daneren2005.dsub.domain.PlayerState;
@@ -70,6 +74,7 @@ import github.daneren2005.dsub.util.Constants;
import github.daneren2005.dsub.util.SilentBackgroundTask;
import github.daneren2005.dsub.adapter.DownloadFileAdapter;
import github.daneren2005.dsub.view.FadeOutAnimation;
+import github.daneren2005.dsub.view.SongView;
import github.daneren2005.dsub.view.UpdateView;
import github.daneren2005.dsub.util.Util;
@@ -79,10 +84,9 @@ import github.daneren2005.dsub.util.*;
import github.daneren2005.dsub.view.AutoRepeatButton;
import java.util.ArrayList;
import java.util.concurrent.ScheduledFuture;
-import com.mobeta.android.dslv.*;
import github.daneren2005.dsub.activity.SubsonicActivity;
-public class NowPlayingFragment extends SubsonicFragment implements OnGestureListener {
+public class NowPlayingFragment extends SubsonicFragment implements OnGestureListener, SectionAdapter.OnItemClickedListener<DownloadFile> {
private static final String TAG = NowPlayingFragment.class.getSimpleName();
private static final int PERCENTAGE_OF_SCREEN_FOR_SWIPE = 10;
private static final int INCREMENT_TIME = 5000;
@@ -97,7 +101,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
private TextView emptyTextView;
private TextView songTitleTextView;
private ImageView albumArtImageView;
- private DragSortListView playlistView;
+ private RecyclerView playlistView;
private TextView positionTextView;
private TextView durationTextView;
private TextView statusTextView;
@@ -172,7 +176,6 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
durationTextView = (TextView)rootView.findViewById(R.id.download_duration);
statusTextView = (TextView)rootView.findViewById(R.id.download_status);
progressBar = (SeekBar)rootView.findViewById(R.id.download_progress_bar);
- playlistView = (DragSortListView)rootView.findViewById(R.id.download_list);
previousButton = (AutoRepeatButton)rootView.findViewById(R.id.download_previous);
nextButton = (AutoRepeatButton)rootView.findViewById(R.id.download_next);
pauseButton =rootView.findViewById(R.id.download_pause);
@@ -184,6 +187,45 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
rateGoodButton = (ImageButton) rootView.findViewById(R.id.download_rating_good);
toggleListButton =rootView.findViewById(R.id.download_toggle_list);
+ playlistView = (RecyclerView)rootView.findViewById(R.id.download_list);
+ setupLayoutManager(playlistView, false);
+ ItemTouchHelper touchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.LEFT) {
+ @Override
+ public boolean onMove(RecyclerView recyclerView, final RecyclerView.ViewHolder fromHolder, final RecyclerView.ViewHolder toHolder) {
+ new SilentBackgroundTask<Void>(context) {
+ private int from;
+ private int to;
+
+ @Override
+ protected Void doInBackground() throws Throwable {
+ from = fromHolder.getAdapterPosition();
+ to = toHolder.getAdapterPosition();
+ getDownloadService().swap(true, from, to);
+ return null;
+ }
+
+ @Override
+ protected void done(Void result) {
+ songListAdapter.notifyItemMoved(from, to);
+ }
+ }.execute();
+
+ return true;
+ }
+
+ @Override
+ public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
+ SongView songView = (SongView) ((UpdateView.UpdateViewHolder) viewHolder).getUpdateView();
+ DownloadFile downloadFile = songView.getDownloadFile();
+
+ DownloadService downloadService = getDownloadService();
+ downloadService.remove(downloadFile);
+ songListAdapter.removeItem(downloadFile);
+ currentRevision = downloadService.getDownloadListUpdateRevision();
+ }
+ });
+ touchHelper.attachToRecyclerView(playlistView);
+
starButton = (ImageButton)rootView.findViewById(R.id.download_star);
if(Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_MENU_STAR, true)) {
starButton.setOnClickListener(new OnClickListener() {
@@ -499,47 +541,6 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
}
}
});
- playlistView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
- warnIfStorageUnavailable();
- new SilentBackgroundTask<Void>(context) {
- @Override
- protected Void doInBackground() throws Throwable {
- getDownloadService().play(position);
- return null;
- }
-
- @Override
- protected void done(Void result) {
- onCurrentChanged();
- onProgressChanged();
- }
- }.execute();
- }
- });
- playlistView.setDropListener(new DragSortListView.DropListener() {
- @Override
- public void drop(final int from, final int to) {
- new SilentBackgroundTask<Void>(context) {
- @Override
- protected Void doInBackground() throws Throwable {
- getDownloadService().swap(true, from, to);
- onDownloadListChanged();
-
- return null;
- }
- }.execute();
- }
- });
- playlistView.setRemoveListener(new DragSortListView.RemoveListener() {
- @Override
- public void remove(int which) {
- getDownloadService().remove(which);
- onDownloadListChanged();
- }
- });
-
registerForContextMenu(playlistView);
if(Build.MODEL.equals("Nexus 4") || Build.MODEL.equals("GT-I9100")) {
@@ -606,10 +607,11 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
if(!primaryFragment) {
return;
}
+ UpdateView targetView = songListAdapter.getContextView();
+ menuInfo = new AdapterView.AdapterContextMenuInfo(targetView, 0, 0);
if (view == playlistView) {
- AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
- DownloadFile downloadFile = (DownloadFile) playlistView.getItemAtPosition(info.position);
+ DownloadFile downloadFile = songListAdapter.getContextItem();
android.view.MenuInflater inflater = context.getMenuInflater();
if(Util.isOffline(context)) {
@@ -634,8 +636,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
return false;
}
- AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuItem.getMenuInfo();
- DownloadFile downloadFile = (DownloadFile) playlistView.getItemAtPosition(info.position);
+ DownloadFile downloadFile = songListAdapter.getContextItem();
return menuItemSelected(menuItem.getItemId(), downloadFile) || super.onContextItemSelected(menuItem);
}
@@ -997,18 +998,18 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
return;
}
- for (int i = 0; i < songListAdapter.getCount(); i++) {
- if (currentPlaying == playlistView.getItemAtPosition(i)) {
- playlistView.setSelectionFromTop(i, 40);
- return;
- }
+ // Try to get position of current playing/downloading
+ int position = songListAdapter.getItemPosition(currentPlaying);
+ if(position == -1) {
+ DownloadFile currentDownloading = getDownloadService().getCurrentDownloading();
+ position = songListAdapter.getItemPosition(currentDownloading);
}
- DownloadFile currentDownloading = getDownloadService().getCurrentDownloading();
- for (int i = 0; i < songListAdapter.getCount(); i++) {
- if (currentDownloading == playlistView.getItemAtPosition(i)) {
- playlistView.setSelectionFromTop(i, 40);
- return;
- }
+
+ // If found, scroll to it
+ if(position != -1) {
+ // RecyclerView.scrollToPosition just puts it on the screen (ie: bottom if scrolled below it)
+ LinearLayoutManager layoutManager = (LinearLayoutManager) playlistView.getLayoutManager();
+ layoutManager.scrollToPositionWithOffset(position, 0);
}
}
@@ -1162,9 +1163,9 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
}
if(songListAdapter == null || refresh) {
- songList = new ArrayList<DownloadFile>();
+ songList = new ArrayList<>();
songList.addAll(list);
- playlistView.setAdapter(songListAdapter = new DownloadFileAdapter(context, songList));
+ playlistView.setAdapter(songListAdapter = new DownloadFileAdapter(context, songList, NowPlayingFragment.this));
} else {
songList.clear();
songList.addAll(list);
@@ -1590,4 +1591,19 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
+
+ @Override
+ public void onItemClicked(final DownloadFile item) {
+ warnIfStorageUnavailable();
+ new SilentBackgroundTask<Void>(context) {
+ @Override
+ protected Void doInBackground() throws Throwable {
+ getDownloadService().play(item);
+
+ onCurrentChanged();
+ onProgressChanged();
+ return null;
+ }
+ }.execute();
+ }
}
diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/SelectListFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/SelectListFragment.java
deleted file mode 100644
index 6f73f6e8..00000000
--- a/app/src/main/java/github/daneren2005/dsub/fragments/SelectListFragment.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic 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.
-
- Subsonic 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.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2010 (C) Sindre Mehus
- */
-package github.daneren2005.dsub.fragments;
-
-import android.os.Bundle;
-import android.support.v4.widget.SwipeRefreshLayout;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-import github.daneren2005.dsub.R;
-import github.daneren2005.dsub.service.MusicService;
-import github.daneren2005.dsub.service.MusicServiceFactory;
-import github.daneren2005.dsub.util.BackgroundTask;
-import github.daneren2005.dsub.util.Constants;
-import github.daneren2005.dsub.util.ProgressListener;
-import github.daneren2005.dsub.util.TabBackgroundTask;
-
-public abstract class SelectListFragment<T> extends SubsonicFragment implements AdapterView.OnItemClickListener {
- private static final String TAG = SelectListFragment.class.getSimpleName();
- protected ListView listView;
- protected ArrayAdapter adapter;
- protected BackgroundTask<List<T>> currentTask;
- protected List<T> objects;
- protected boolean serialize = true;
-
- @Override
- public void onCreate(Bundle bundle) {
- super.onCreate(bundle);
-
- if(bundle != null && serialize) {
- objects = (List<T>) bundle.getSerializable(Constants.FRAGMENT_LIST);
- }
- }
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- if(serialize) {
- outState.putSerializable(Constants.FRAGMENT_LIST, (Serializable) objects);
- }
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
- rootView = inflater.inflate(R.layout.abstract_list_fragment, container, false);
-
- refreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.refresh_layout);
- refreshLayout.setOnRefreshListener(this);
-
- listView = (ListView)rootView.findViewById(R.id.fragment_list);
- listView.setOnItemClickListener(this);
- setupScrollList(listView);
- registerForContextMenu(listView);
-
- if(objects == null) {
- refresh(false);
- } else {
- listView.setAdapter(adapter = getAdapter(objects));
- }
-
- return rootView;
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
- if(!primaryFragment) {
- return;
- }
-
- menuInflater.inflate(getOptionsMenu(), menu);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- return super.onOptionsItemSelected(item);
- }
-
- @Override
- protected void refresh(final boolean refresh) {
- int titleRes = getTitleResource();
- if(titleRes != 0) {
- setTitle(getTitleResource());
- }
- listView.setVisibility(View.GONE);
-
- // Cancel current running task before starting another one
- if(currentTask != null) {
- currentTask.cancel();
- }
-
- currentTask = new TabBackgroundTask<List<T>>(this) {
- @Override
- protected List<T> doInBackground() throws Throwable {
- MusicService musicService = MusicServiceFactory.getMusicService(context);
-
- objects = new ArrayList<T>();
-
- try {
- objects = getObjects(musicService, refresh, this);
- } catch (Exception x) {
- Log.e(TAG, "Failed to load", x);
- }
-
- return objects;
- }
-
- @Override
- protected void done(List<T> result) {
- if (result != null && !result.isEmpty()) {
- // Toggle fast scroll to get around issue when length of list changes
- listView.setFastScrollEnabled(false);
- listView.setAdapter(adapter = getAdapter(result));
- listView.setFastScrollEnabled(true);
-
- onFinishRefresh();
- listView.setVisibility(View.VISIBLE);
- } else {
- setEmpty(true);
- }
-
- currentTask = null;
- }
- };
- currentTask.execute();
- }
-
- public abstract int getOptionsMenu();
- public abstract ArrayAdapter getAdapter(List<T> objs);
- public abstract List<T> getObjects(MusicService musicService, boolean refresh, ProgressListener listener) throws Exception;
- public abstract int getTitleResource();
-
- public void onFinishRefresh() {
-
- }
-}
diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/SelectVideoFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/SelectVideoFragment.java
index e91a163c..bf25db77 100644
--- a/app/src/main/java/github/daneren2005/dsub/fragments/SelectVideoFragment.java
+++ b/app/src/main/java/github/daneren2005/dsub/fragments/SelectVideoFragment.java
@@ -19,7 +19,6 @@ import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
import java.util.List;
@@ -29,7 +28,6 @@ import github.daneren2005.dsub.adapter.SectionAdapter;
import github.daneren2005.dsub.domain.MusicDirectory;
import github.daneren2005.dsub.service.MusicService;
import github.daneren2005.dsub.util.ProgressListener;
-import github.daneren2005.dsub.adapter.EntryAdapter;
import github.daneren2005.dsub.view.UpdateView;
public class SelectVideoFragment extends SelectRecyclerFragment<MusicDirectory.Entry> {
diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/UserFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/UserFragment.java
index 00c7c603..25196d66 100644
--- a/app/src/main/java/github/daneren2005/dsub/fragments/UserFragment.java
+++ b/app/src/main/java/github/daneren2005/dsub/fragments/UserFragment.java
@@ -15,71 +15,30 @@
package github.daneren2005.dsub.fragments;
-import android.app.Activity;
import android.os.Bundle;
-import android.support.v4.widget.SwipeRefreshLayout;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.TextView;
+
+import java.util.List;
import github.daneren2005.dsub.R;
-import github.daneren2005.dsub.activity.SubsonicActivity;
+import github.daneren2005.dsub.adapter.SectionAdapter;
import github.daneren2005.dsub.domain.ServerInfo;
import github.daneren2005.dsub.domain.User;
+import github.daneren2005.dsub.service.MusicService;
import github.daneren2005.dsub.util.Constants;
-import github.daneren2005.dsub.util.ImageLoader;
+import github.daneren2005.dsub.util.ProgressListener;
import github.daneren2005.dsub.util.UserUtil;
import github.daneren2005.dsub.adapter.SettingsAdapter;
-public class UserFragment extends SubsonicFragment{
- private ListView listView;
+public class UserFragment extends SelectRecyclerFragment<User.Setting>{
private User user;
@Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
- rootView = inflater.inflate(R.layout.abstract_list_fragment, container, false);
-
- refreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.refresh_layout);
- refreshLayout.setEnabled(false);
-
+ public void onCreate(Bundle bundle) {
+ super.onCreate(bundle);
Bundle args = getArguments();
user = (User) args.getSerializable(Constants.INTENT_EXTRA_NAME_ID);
-
- listView = (ListView)rootView.findViewById(R.id.fragment_list);
- createHeader();
- listView.setAdapter(new SettingsAdapter(context, user.getSettings(), UserUtil.isCurrentAdmin() && ServerInfo.checkServerVersion(context, "1.10")));
-
- setTitle(user.getUsername());
-
- return rootView;
- }
-
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
- ((SubsonicActivity) activity).supportInvalidateOptionsMenu();
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
- // For some reason this is called before onAttach
- if(!primaryFragment || context == null) {
- return;
- }
-
- if(UserUtil.isCurrentAdmin() && ServerInfo.checkServerVersion(context, "1.10")) {
- menuInflater.inflate(R.menu.user, menu);
- } else if(UserUtil.isCurrentRole(User.SETTINGS)) {
- menuInflater.inflate(R.menu.user_user, menu);
- } else {
- menuInflater.inflate(R.menu.empty, menu);
- }
+ pullToRefresh = false;
}
@Override
@@ -103,23 +62,35 @@ public class UserFragment extends SubsonicFragment{
return false;
}
- private void createHeader() {
- View header = LayoutInflater.from(context).inflate(R.layout.user_header, listView, false);
+ @Override
+ public int getOptionsMenu() {
+ if(UserUtil.isCurrentAdmin() && ServerInfo.checkServerVersion(context, "1.10")) {
+ return R.menu.user;
+ } else if(UserUtil.isCurrentRole(User.SETTINGS)) {
+ return R.menu.user_user;
+ } else {
+ return R.menu.empty;
+ }
+ }
+
+ @Override
+ public SectionAdapter<User.Setting> getAdapter(List<User.Setting> objs) {
+ return new SettingsAdapter(context, user, getImageLoader(), UserUtil.isCurrentAdmin() && ServerInfo.checkServerVersion(context, "1.10"));
+ }
- final ImageLoader imageLoader = getImageLoader();
- ImageView coverArtView = (ImageView) header.findViewById(R.id.user_avatar);
- imageLoader.loadAvatar(context, coverArtView, user.getUsername());
+ @Override
+ public List<User.Setting> getObjects(MusicService musicService, boolean refresh, ProgressListener listener) throws Exception {
+ return user.getSettings();
+ }
- TextView usernameView = (TextView) header.findViewById(R.id.user_username);
- usernameView.setText(user.getUsername());
+ @Override
+ public int getTitleResource() {
+ setTitle(user.getUsername());
+ return 0;
+ }
- final TextView emailView = (TextView) header.findViewById(R.id.user_email);
- if(user.getEmail() != null) {
- emailView.setText(user.getEmail());
- } else {
- emailView.setVisibility(View.GONE);
- }
+ @Override
+ public void onItemClicked(User.Setting item) {
- listView.addHeaderView(header);
}
}
diff --git a/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java b/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java
index c0268933..40521051 100644
--- a/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java
+++ b/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java
@@ -886,6 +886,9 @@ public class DownloadService extends Service {
public synchronized void play(int index) {
play(index, true);
}
+ public synchronized void play(DownloadFile downloadFile) {
+ play(downloadList.indexOf(downloadFile));
+ }
private synchronized void play(int index, boolean start) {
play(index, start, 0);
}
@@ -1818,6 +1821,10 @@ public class DownloadService extends Service {
applyReplayGain(mediaPlayer, currentPlaying);
}
+ public synchronized void swap(boolean mainList, DownloadFile from, DownloadFile to) {
+ List<DownloadFile> list = mainList ? downloadList : backgroundDownloadList;
+ swap(mainList, list.indexOf(from), list.indexOf(to));
+ }
public synchronized void swap(boolean mainList, int from, int to) {
List<DownloadFile> list = mainList ? downloadList : backgroundDownloadList;
int max = list.size();
diff --git a/app/src/main/java/github/daneren2005/dsub/util/UserUtil.java b/app/src/main/java/github/daneren2005/dsub/util/UserUtil.java
index 5c5f1543..fb2de05e 100644
--- a/app/src/main/java/github/daneren2005/dsub/util/UserUtil.java
+++ b/app/src/main/java/github/daneren2005/dsub/util/UserUtil.java
@@ -21,8 +21,11 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.support.v7.app.ActionBarActivity;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
+import android.view.WindowManager;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
@@ -183,6 +186,7 @@ public final class UserUtil {
.setCancelable(true);
AlertDialog dialog = builder.create();
+ dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
dialog.show();
}
}
@@ -248,7 +252,6 @@ public final class UserUtil {
protected Void doInBackground() throws Throwable {
MusicService musicService = MusicServiceFactory.getMusicService(context);
musicService.updateUser(user, context, null);
- user.setSettings(user.getSettings());
return null;
}
@@ -378,8 +381,11 @@ public final class UserUtil {
final TextView usernameView = (TextView) layout.findViewById(R.id.username);
final TextView emailView = (TextView) layout.findViewById(R.id.email);
final TextView passwordView = (TextView) layout.findViewById(R.id.password);
- final ListView listView = (ListView) layout.findViewById(R.id.settings_list);
- listView.setAdapter(new SettingsAdapter(context, user, true));
+ final RecyclerView recyclerView = (RecyclerView) layout.findViewById(R.id.settings_list);
+ LinearLayoutManager layoutManager = new LinearLayoutManager(context);
+ layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
+ recyclerView.setLayoutManager(layoutManager);
+ recyclerView.setAdapter(new SettingsAdapter(context, user, null, true));
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.menu_add_user)
diff --git a/app/src/main/java/github/daneren2005/dsub/view/SettingView.java b/app/src/main/java/github/daneren2005/dsub/view/SettingView.java
index 1c78706e..63b2c844 100644
--- a/app/src/main/java/github/daneren2005/dsub/view/SettingView.java
+++ b/app/src/main/java/github/daneren2005/dsub/view/SettingView.java
@@ -17,8 +17,9 @@ package github.daneren2005.dsub.view;
import android.content.Context;
import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.CheckedTextView;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.TextView;
import github.daneren2005.dsub.R;
import github.daneren2005.dsub.domain.User;
@@ -26,16 +27,28 @@ import github.daneren2005.dsub.domain.User;
import static github.daneren2005.dsub.domain.User.Setting;
public class SettingView extends UpdateView {
- Setting setting;
+ private final TextView titleView;
+ private final CheckBox checkBox;
- CheckedTextView view;
+ private Setting setting;
+ private boolean enabled = false;
public SettingView(Context context) {
super(context, false);
this.context = context;
- LayoutInflater.from(context).inflate(android.R.layout.simple_list_item_multiple_choice, this, true);
+ LayoutInflater.from(context).inflate(R.layout.basic_choice_item, this, true);
- view = (CheckedTextView) findViewById(android.R.id.text1);
+ titleView = (TextView) findViewById(R.id.item_name);
+ checkBox = (CheckBox) findViewById(R.id.item_checkbox);
+ checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if(setting != null) {
+ setting.setValue(isChecked);
+ }
+ }
+ });
+ checkBox.setClickable(false);
}
protected void setObjectImpl(Object obj, Object editable) {
@@ -74,29 +87,29 @@ public class SettingView extends UpdateView {
res = R.string.admin_role_lastfm;
} else {
// Last resort to display the raw value
- view.setText(name);
+ titleView.setText(name);
}
if(res != -1) {
- view.setText(res);
+ titleView.setText(res);
}
if(setting.getValue()) {
- view.setChecked(setting.getValue());
+ checkBox.setChecked(setting.getValue());
} else {
- view.setChecked(false);
+ checkBox.setChecked(false);
}
- if((Boolean) editable) {
- view.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- view.toggle();
- setting.setValue(view.isChecked());
- }
- });
- } else {
- view.setOnClickListener(null);
- }
+ enabled = (Boolean) editable;
+ checkBox.setEnabled(enabled);
+ }
+
+ @Override
+ public boolean isCheckable() {
+ return this.enabled;
+ }
+
+ public void setChecked(boolean checked) {
+ checkBox.setChecked(checked);
}
}
diff --git a/app/src/main/res/layout/basic_choice_item.xml b/app/src/main/res/layout/basic_choice_item.xml
new file mode 100644
index 00000000..00a45be4
--- /dev/null
+++ b/app/src/main/res/layout/basic_choice_item.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:background="?attr/selectableItemBackground">
+
+ <TextView
+ android:id="@+id/item_name"
+ android:layout_width="0dip"
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:layout_weight="1"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:gravity="left|center_vertical"
+ android:paddingLeft="6dip"
+ android:paddingRight="6dip"
+ android:background="@android:color/transparent"/>
+
+ <CheckBox
+ android:id="@+id/item_checkbox"
+ android:layout_width="wrap_content"
+ android:layout_height="fill_parent"
+ android:layout_gravity="right|center_vertical"
+ android:checkMark="?android:attr/listChoiceIndicatorMultiple"
+ style="@style/MoreButton"/>
+</LinearLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/create_user.xml b/app/src/main/res/layout/create_user.xml
index eac6e5cb..e2f6c4eb 100644
--- a/app/src/main/res/layout/create_user.xml
+++ b/app/src/main/res/layout/create_user.xml
@@ -67,11 +67,10 @@
android:layout_marginLeft="4dp" />
</LinearLayout>
- <ListView
+ <android.support.v7.widget.RecyclerView
android:id="@+id/settings_list"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1.0"
- android:fastScrollEnabled="true"/>
-
+ android:scrollbars="vertical"/>
</LinearLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/download_playlist.xml b/app/src/main/res/layout/download_playlist.xml
index 8a73ef3b..afb46081 100644
--- a/app/src/main/res/layout/download_playlist.xml
+++ b/app/src/main/res/layout/download_playlist.xml
@@ -1,31 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
-
<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:layout_weight="1">
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:layout_weight="1">
<View
- android:layout_width="fill_parent"
- android:layout_height="1px"
- android:background="@color/dividerColor"/>
+ android:layout_width="fill_parent"
+ android:layout_height="1px"
+ android:background="@color/dividerColor"/>
<TextView
- android:id="@+id/download_empty"
- android:text="@string/download.empty"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:padding="10dip"/>
+ android:id="@+id/download_empty"
+ android:text="@string/download.empty"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:padding="10dip"/>
- <com.mobeta.android.dslv.DragSortListView
- style="@style/DragDropListView"
+ <android.support.v7.widget.RecyclerView
android:id="@+id/download_list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
- android:cacheColorHint="#00000000"
- android:fastScrollEnabled="true"/>
+ android:scrollbars="vertical"/>
</LinearLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/select_album_header.xml b/app/src/main/res/layout/select_album_header.xml
index d028a476..e3a09443 100644
--- a/app/src/main/res/layout/select_album_header.xml
+++ b/app/src/main/res/layout/select_album_header.xml
@@ -148,6 +148,12 @@
android:textAppearance="?android:attr/textAppearanceMedium"/>
</LinearLayout>
</FrameLayout>
+
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1px"
+ android:background="@color/dividerColor"
+ android:layout_gravity="bottom"/>
</FrameLayout>
diff --git a/app/src/main/res/layout/select_artist_header.xml b/app/src/main/res/layout/select_artist_header.xml
index 0ac9e6a6..168120d9 100644
--- a/app/src/main/res/layout/select_artist_header.xml
+++ b/app/src/main/res/layout/select_artist_header.xml
@@ -42,4 +42,9 @@
</LinearLayout>
</LinearLayout>
+
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1px"
+ android:background="@color/dividerColor"/>
</LinearLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/user_header.xml b/app/src/main/res/layout/user_header.xml
index 0b303afe..a9ff4bee 100644
--- a/app/src/main/res/layout/user_header.xml
+++ b/app/src/main/res/layout/user_header.xml
@@ -52,6 +52,12 @@
android:autoLink="email"/>
</LinearLayout>
+
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1px"
+ android:background="@color/dividerColor"
+ android:layout_alignParentBottom="true"/>
</RelativeLayout>
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index c4a53b99..cfe446f3 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -59,23 +59,6 @@
<item name="android:paddingLeft">16dip</item>
</style>
- <style name="DragDropListView">
- <item name="drag_enabled">true</item>
- <item name="collapsed_height">1dp</item>
- <item name="drag_scroll_start">1.0</item>
- <item name="max_drag_scroll_speed">2.0</item>
- <item name="float_alpha">0.6</item>
- <item name="slide_shuffle_speed">0.3</item>
- <item name="track_drag_sort">false</item>
- <item name="use_default_controller">true</item>
- <item name="drag_handle_id">@id/drag_handle</item>
- <item name="sort_enabled">true</item>
- <item name="remove_enabled">false</item>
- <item name="remove_mode">flingRemove</item>
- <item name="drag_start_mode">onLongPress</item>
- <item name="float_background_color">@android:color/transparent</item>
- </style>
-
<style name="MainAlbumButton">
<item name="android:drawablePadding">6dip</item>
<item name="android:layout_width">fill_parent</item>