Add fastscroll to lists with RecyclerView
This commit is contained in:
parent
6446ed7ad6
commit
f7a63ae9a7
|
@ -113,6 +113,7 @@ dependencies {
|
|||
implementation 'org.jmdns:jmdns:3.5.1'
|
||||
implementation 'at.blogc:expandabletextview:1.0.3'
|
||||
implementation 'com.sothree.slidinguppanel:library:3.3.1'
|
||||
implementation 'com.simplecityapps:recyclerview-fastscroll:1.0.20'
|
||||
|
||||
androidTestImplementation 'com.android.support.test:runner:1.0.1'
|
||||
androidTestImplementation 'com.android.support.test:rules:1.0.1'
|
||||
|
|
|
@ -20,11 +20,15 @@ import android.database.Cursor;
|
|||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
|
||||
abstract public class RecyclerViewCursorAdapter extends RecyclerView.Adapter<RecyclerViewCursorAdapter.CursorViewHolder> {
|
||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView;
|
||||
|
||||
private boolean dataValid;
|
||||
abstract public class RecyclerViewCursorAdapter
|
||||
extends RecyclerView.Adapter<RecyclerViewCursorAdapter.CursorViewHolder>
|
||||
implements FastScrollRecyclerView.SectionedAdapter {
|
||||
|
||||
protected boolean dataValid;
|
||||
private int rowIDColumn;
|
||||
private Cursor cursor;
|
||||
protected Cursor cursor;
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(CursorViewHolder holder, int position) {
|
||||
|
@ -59,6 +63,25 @@ abstract public class RecyclerViewCursorAdapter extends RecyclerView.Adapter<Rec
|
|||
return cursor.getLong(rowIDColumn);
|
||||
}
|
||||
|
||||
public String getSectionName(int position) {
|
||||
if (!dataValid) {
|
||||
throw new IllegalStateException("Cursor is in an invalid state.");
|
||||
}
|
||||
if (!cursor.moveToPosition(position)) {
|
||||
throw new IllegalStateException("Could not move cursor to position " + position);
|
||||
}
|
||||
|
||||
return cursor.getString(getSectionColumnIdx()).substring(0, 1).toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Should return the cursor column index that contains the corresponding field to be used
|
||||
* on the fastscroller. Should be a string!
|
||||
*
|
||||
* @return Cursor column index of the field to show in the fastscroller
|
||||
*/
|
||||
abstract protected int getSectionColumnIdx();
|
||||
|
||||
public void swapCursor(Cursor newCursor) {
|
||||
if (newCursor == cursor) {
|
||||
return;
|
||||
|
|
|
@ -87,7 +87,7 @@ public class AlbumListFragment extends AbstractCursorListFragment {
|
|||
|
||||
/**
|
||||
* Use this to display all albums for a specific genre
|
||||
* @param genreId
|
||||
* @param genreId genre id
|
||||
*/
|
||||
public void setGenre(int genreId) {
|
||||
Bundle args = new Bundle();
|
||||
|
@ -216,12 +216,12 @@ public class AlbumListFragment extends AbstractCursorListFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
public void onAttach(Context ctx) {
|
||||
super.onAttach(ctx);
|
||||
try {
|
||||
listenerActivity = (OnAlbumSelectedListener) activity;
|
||||
listenerActivity = (OnAlbumSelectedListener) ctx;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(activity.toString() + " must implement OnAlbumSelectedListener");
|
||||
throw new ClassCastException(ctx.toString() + " must implement OnAlbumSelectedListener");
|
||||
}
|
||||
|
||||
setSupportsSearch(true);
|
||||
|
@ -317,6 +317,8 @@ public class AlbumListFragment extends AbstractCursorListFragment {
|
|||
popupMenu.show();
|
||||
}
|
||||
};
|
||||
|
||||
protected int getSectionColumnIdx() { return AlbumListQuery.TITLE; }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -94,12 +94,12 @@ public class ArtistListFragment extends AbstractCursorListFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
try {
|
||||
listenerActivity = (OnArtistSelectedListener) activity;
|
||||
listenerActivity = (OnArtistSelectedListener) context;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(activity.toString() + " must implement OnArtistSelectedListener");
|
||||
throw new ClassCastException(context.toString() + " must implement OnArtistSelectedListener");
|
||||
}
|
||||
setSupportsSearch(true);
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ public class ArtistListFragment extends AbstractCursorListFragment {
|
|||
@Override
|
||||
public CursorViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(fragment.getContext())
|
||||
.inflate(R.layout.grid_item_artist, parent, false);
|
||||
.inflate(R.layout.grid_item_artist, parent, false);
|
||||
|
||||
return new ViewHolder(view, fragment.getContext(), hostManager, artWidth, artHeight, artistlistItemMenuClickListener);
|
||||
}
|
||||
|
@ -186,6 +186,8 @@ public class ArtistListFragment extends AbstractCursorListFragment {
|
|||
popupMenu.show();
|
||||
}
|
||||
};
|
||||
|
||||
protected int getSectionColumnIdx() { return ArtistListQuery.ARTIST; }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -90,12 +90,12 @@ public class AudioGenresListFragment extends AbstractCursorListFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
public void onAttach(Context ctx) {
|
||||
super.onAttach(ctx);
|
||||
try {
|
||||
listenerActivity = (OnAudioGenreSelectedListener) activity;
|
||||
listenerActivity = (OnAudioGenreSelectedListener) ctx;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(activity.toString() + " must implement OnAudioGenreSelectedListener");
|
||||
throw new ClassCastException(ctx.toString() + " must implement OnAudioGenreSelectedListener");
|
||||
}
|
||||
setSupportsSearch(true);
|
||||
}
|
||||
|
@ -119,10 +119,10 @@ public class AudioGenresListFragment extends AbstractCursorListFragment {
|
|||
|
||||
String SORT = MediaContract.AudioGenres.TITLE + " COLLATE NOCASE ASC";
|
||||
|
||||
final int ID = 0;
|
||||
final int GENREID = 1;
|
||||
final int TITLE = 2;
|
||||
final int THUMBNAIL = 3;
|
||||
int ID = 0;
|
||||
int GENREID = 1;
|
||||
int TITLE = 2;
|
||||
int THUMBNAIL = 3;
|
||||
}
|
||||
|
||||
private class AudioGenresAdapter extends RecyclerViewCursorAdapter {
|
||||
|
@ -148,6 +148,8 @@ public class AudioGenresListFragment extends AbstractCursorListFragment {
|
|||
|
||||
return new ViewHolder(view, getContext(), hostManager, artWidth, artHeight, genrelistItemMenuClickListener);
|
||||
}
|
||||
|
||||
protected int getSectionColumnIdx() { return AudioGenreListQuery.TITLE; }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -89,12 +89,12 @@ public class MusicVideoListFragment extends AbstractCursorListFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
public void onAttach(Context ctx) {
|
||||
super.onAttach(ctx);
|
||||
try {
|
||||
listenerActivity = (OnMusicVideoSelectedListener) activity;
|
||||
listenerActivity = (OnMusicVideoSelectedListener) ctx;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(activity.toString() + " must implement OnMusicVideoSelectedListener");
|
||||
throw new ClassCastException(ctx.toString() + " must implement OnMusicVideoSelectedListener");
|
||||
}
|
||||
setSupportsSearch(true);
|
||||
}
|
||||
|
@ -159,6 +159,7 @@ public class MusicVideoListFragment extends AbstractCursorListFragment {
|
|||
.inflate(R.layout.grid_item_music_video, parent, false);
|
||||
return new ViewHolder(view, context, hostManager, artWidth, artHeight);
|
||||
}
|
||||
protected int getSectionColumnIdx() { return MusicVideosListQuery.TITLE; }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -153,9 +153,9 @@ public class SongsListFragment extends AbstractCursorListFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
public void onAttach(Context context) {
|
||||
setSupportsSearch(true);
|
||||
super.onAttach(activity);
|
||||
super.onAttach(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -272,6 +272,8 @@ public class SongsListFragment extends AbstractCursorListFragment {
|
|||
return new SongViewHolder(view, context, hostManager, artWidth, artHeight,
|
||||
contextMenuClickListener);
|
||||
}
|
||||
|
||||
protected int getSectionColumnIdx() { return SongsListQuery.TITLE; }
|
||||
}
|
||||
|
||||
private static class AlbumSongsAdapter extends RecyclerViewCursorAdapter {
|
||||
|
@ -290,6 +292,8 @@ public class SongsListFragment extends AbstractCursorListFragment {
|
|||
|
||||
return new AlbumViewHolder(view, contextMenuClickListener);
|
||||
}
|
||||
|
||||
protected int getSectionColumnIdx() { return AlbumSongsListQuery.TITLE; }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -45,6 +45,7 @@ import org.xbmc.kore.service.library.LibrarySyncService;
|
|||
import org.xbmc.kore.ui.AbstractCursorListFragment;
|
||||
import org.xbmc.kore.ui.AbstractFragment;
|
||||
import org.xbmc.kore.ui.RecyclerViewCursorAdapter;
|
||||
import org.xbmc.kore.ui.sections.audio.SongsListFragment;
|
||||
import org.xbmc.kore.utils.LogUtils;
|
||||
import org.xbmc.kore.utils.UIUtils;
|
||||
import org.xbmc.kore.utils.Utils;
|
||||
|
@ -129,12 +130,12 @@ public class MovieListFragment extends AbstractCursorListFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
public void onAttach(Context ctx) {
|
||||
super.onAttach(ctx);
|
||||
try {
|
||||
listenerActivity = (OnMovieSelectedListener) activity;
|
||||
listenerActivity = (OnMovieSelectedListener) ctx;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(activity.toString() + " must implement OnMovieSelectedListener");
|
||||
throw new ClassCastException(ctx.toString() + " must implement OnMovieSelectedListener");
|
||||
}
|
||||
setSupportsSearch(true);
|
||||
}
|
||||
|
@ -344,6 +345,8 @@ public class MovieListFragment extends AbstractCursorListFragment {
|
|||
|
||||
return new ViewHolder(view, getContext(), themeAccentColor, hostManager, artWidth, artHeight);
|
||||
}
|
||||
|
||||
protected int getSectionColumnIdx() { return MovieListQuery.TITLE; }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -47,6 +47,7 @@ import org.xbmc.kore.service.library.LibrarySyncService;
|
|||
import org.xbmc.kore.ui.AbstractCursorListFragment;
|
||||
import org.xbmc.kore.ui.AbstractFragment;
|
||||
import org.xbmc.kore.ui.RecyclerViewCursorAdapter;
|
||||
import org.xbmc.kore.ui.sections.audio.SongsListFragment;
|
||||
import org.xbmc.kore.utils.LogUtils;
|
||||
import org.xbmc.kore.utils.MediaPlayerUtils;
|
||||
import org.xbmc.kore.utils.UIUtils;
|
||||
|
@ -250,6 +251,8 @@ public class TVShowEpisodeListFragment extends AbstractCursorListFragment {
|
|||
contextlistItemMenuClickListener, hostManager,
|
||||
artWidth, artHeight);
|
||||
}
|
||||
|
||||
protected int getSectionColumnIdx() { return EpisodesListQuery.TITLE; }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -47,6 +47,7 @@ import org.xbmc.kore.service.library.LibrarySyncService;
|
|||
import org.xbmc.kore.ui.AbstractCursorListFragment;
|
||||
import org.xbmc.kore.ui.AbstractInfoFragment;
|
||||
import org.xbmc.kore.ui.RecyclerViewCursorAdapter;
|
||||
import org.xbmc.kore.ui.sections.audio.SongsListFragment;
|
||||
import org.xbmc.kore.utils.LogUtils;
|
||||
import org.xbmc.kore.utils.UIUtils;
|
||||
import org.xbmc.kore.utils.Utils;
|
||||
|
@ -133,12 +134,12 @@ public class TVShowListFragment extends AbstractCursorListFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
public void onAttach(Context ctx) {
|
||||
super.onAttach(ctx);
|
||||
try {
|
||||
listenerActivity = (OnTVShowSelectedListener) activity;
|
||||
listenerActivity = (OnTVShowSelectedListener) ctx;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(activity.toString() + " must implement OnTVShowSelectedListener");
|
||||
throw new ClassCastException(ctx.toString() + " must implement OnTVShowSelectedListener");
|
||||
}
|
||||
setSupportsSearch(true);
|
||||
}
|
||||
|
@ -354,6 +355,8 @@ public class TVShowListFragment extends AbstractCursorListFragment {
|
|||
|
||||
return viewHolder;
|
||||
}
|
||||
|
||||
protected int getSectionColumnIdx() { return TVShowListQuery.TITLE; }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,6 +26,8 @@ import android.support.v7.widget.RecyclerView;
|
|||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView;
|
||||
|
||||
/**
|
||||
* <p>A Recycler view using a grid layout that supports auto sizing and showing an empty view when the adapter
|
||||
* has no items.
|
||||
|
@ -40,7 +42,7 @@ import android.view.View;
|
|||
*
|
||||
* Inspired by <a href="http://blog.sqisland.com/2014/12/recyclerview-autofit-grid.html">RecyclerView: Autofit grid</a>
|
||||
*/
|
||||
public class RecyclerViewEmptyViewSupport extends RecyclerView {
|
||||
public class RecyclerViewEmptyViewSupport extends FastScrollRecyclerView {
|
||||
|
||||
public final static int AUTO_FIT = -1;
|
||||
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
limitations under the License.
|
||||
-->
|
||||
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
<attr name="colorFinished" format="reference|color" />
|
||||
|
||||
<attr name="separatorColor" format="reference|color" />
|
||||
<attr name="fastscrollHandleColor" format="reference|color" />
|
||||
|
||||
<attr name="drawerBackgroundColor" format="reference|color" />
|
||||
|
||||
|
|
|
@ -63,6 +63,9 @@
|
|||
<color name="dark_separator">#ff505050</color>
|
||||
<color name="light_separator">#ffafafaf</color>
|
||||
|
||||
<color name="dark_fastscroll_handle">#ff505050</color>
|
||||
<color name="light_fastscroll_handle">#ff606060</color>
|
||||
|
||||
<!-- Drawer colors -->
|
||||
<color name="dark_drawer_background">@color/dark_content_background</color>
|
||||
<color name="light_drawer_background">@color/light_content_background</color>
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
<dimen name="small_icon_size">24dp</dimen>
|
||||
<dimen name="medium_icon_size">32dp</dimen>
|
||||
|
||||
<dimen name="card_corner_radius">2dp</dimen>
|
||||
<dimen name="card_corner_radius">4dp</dimen>
|
||||
<dimen name="default_card_elevation">2dp</dimen>
|
||||
<dimen name="default_card_margin">2dp</dimen>
|
||||
|
||||
|
@ -43,7 +43,10 @@
|
|||
<dimen name="text_size_medium">14sp</dimen>
|
||||
<dimen name="text_size_large">16sp</dimen>
|
||||
<dimen name="text_size_xlarge">20sp</dimen>
|
||||
<dimen name="text_size_xxlarge">34sp</dimen>
|
||||
<dimen name="text_size_xxlarge">32sp</dimen>
|
||||
|
||||
<dimen name="fastscroll_popup_size">80dp</dimen>
|
||||
<dimen name="fastscroll_text_size">36sp</dimen>
|
||||
|
||||
<dimen name="default_list_item_height">56dp</dimen>
|
||||
|
||||
|
|
|
@ -55,14 +55,22 @@
|
|||
</style>
|
||||
|
||||
<style name="GridLayoutRecyclerView">
|
||||
<item name="fastScrollPopupBgColor">?attr/colorPrimary</item>
|
||||
<item name="fastScrollPopupTextColor">?attr/textColorOverPrimary</item>
|
||||
<item name="fastScrollPopupTextSize">@dimen/fastscroll_text_size</item>
|
||||
<item name="fastScrollPopupBackgroundSize">@dimen/fastscroll_popup_size</item>
|
||||
<item name="fastScrollThumbColor">?attr/colorPrimary</item>
|
||||
<item name="fastScrollThumbInactiveColor">?attr/fastscrollHandleColor</item>
|
||||
<item name="fastScrollPopupPosition">adjacent</item>
|
||||
|
||||
<item name="android:clipToPadding">false</item>
|
||||
<item name="android:scrollbars">vertical</item>
|
||||
<item name="android:paddingBottom">@dimen/default_padding</item>
|
||||
<item name="android:paddingLeft">@dimen/default_card_margin</item>
|
||||
<item name="android:columnWidth">@dimen/default_grid_column_width</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.CardView">
|
||||
<item name="cardCornerRadius">@dimen/card_corner_radius</item>
|
||||
<item name="cardElevation">@dimen/default_card_elevation</item>
|
||||
<item name="cardBackgroundColor">?attr/appCardBackgroundColor</item>
|
||||
<item name="android:layout_marginRight">@dimen/default_card_margin</item>
|
||||
|
|
|
@ -86,6 +86,7 @@
|
|||
<item name="drawerBackgroundColor">@color/dark_drawer_background</item>
|
||||
|
||||
<item name="separatorColor">@color/dark_separator</item>
|
||||
<item name="fastscrollHandleColor">@color/dark_fastscroll_handle</item>
|
||||
|
||||
<item name="remoteButtonColorFilter">@color/white</item>
|
||||
<item name="defaultButtonColorFilter">@color/white</item>
|
||||
|
@ -225,6 +226,7 @@
|
|||
<item name="drawerBackgroundColor">@color/light_drawer_background</item>
|
||||
|
||||
<item name="separatorColor">@color/light_separator</item>
|
||||
<item name="fastscrollHandleColor">@color/light_fastscroll_handle</item>
|
||||
|
||||
<item name="remoteButtonColorFilter">@color/black_dim_54pct</item>
|
||||
<item name="defaultButtonColorFilter">@color/black_dim_54pct</item>
|
||||
|
|
Loading…
Reference in New Issue