[英]Android alphabetical fast scrollview in RecyclerView with Collapsing toolbar
在我的應用程序中,我有這樣的 activity_main.xml:-
<Coordinator Layout>
<AppBarLayout>
<CollapsingToolbarLayout>
<ImageView/>
<Toolbar/>
</CollapsingToolbarLayout>
</AppBarLayout>
<RecyclerView/>
</Coordinating Layout>
布局.xml ----->>>
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/theme_background"
android:id="@+id/drawerlayout"
>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:id="@+id/activity_main_id"
tools:context="objectdistance.ajai.ram.sita.gallery.MainActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="48dp"
app:expandedTitleMarginEnd="64dp"
android:fitsSystemWindows="true">
<ImageView
android:id="@+id/imagetoolbar"
android:layout_width="match_parent"
android:layout_height="200dp"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
android:foreground="@drawable/image_header_foreground"
app:layout_scrollFlags="scroll"
app:layout_collapseMode="parallax"/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
android:background="@drawable/theme_background"
app:layout_collapseMode="pin" >
<Spinner
android:id="@+id/spinner_nav"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:dropDownVerticalOffset="?attr/actionBarSize" />
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
<ListView
android:layout_width="200dp"
android:layout_height="match_parent"
android:id="@+id/navlist"
android:background="#dedede"
android:layout_gravity="start" />
</android.support.v4.widget.DrawerLayout>
現在我想將快速滾動包含到我的回收站視圖中,以便可以在滾動時彈出圖像日期。
我搜索了這個並嘗試使用幾個庫,但我認為由於我的折疊工具欄,滾動條無法正常工作。
在我的情況下,滾動條從頂部開始,滾動計算也不正確。
請幫助解決這個問題。
謝謝
我們想要一些SectionIndexer
知識。 這是SectionIndexer 的文檔。
我們必須設置 TRUE setFastScrollEnabled(true)
方法,該方法與LISTVIEW
使用.......你可以在下面的例子中使用recyclerview
而不是listView
......
這是活動
public class FastScoll extends ListActivity {
ListView fruitView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fast_scoll);
fruitView = (ListView) findViewById(android.R.id.list);
fruitView.setFastScrollEnabled(true);
String[] fruits = getResources().getStringArray(R.array.fruits_array);
final List<String> fruitList = Arrays.asList(fruits);
Collections.sort(fruitList);
setListAdapter(new ListAdapter(this, fruitList));
fruitView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View arg1,
int position, long arg3) {
Log.e("sushildlh",fruitList.get(position));
}
});
}
}
這是activity_fast_scoll.xml 文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp" >
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbarStyle="outsideOverlay" />
</RelativeLayout>
這是我帶有SectionIndexer
自定義適配器....
public class ListAdapter extends ArrayAdapter<String> implements SectionIndexer {
String[] sections;
List<String> fruits;
List<String> sectionLetters=new ArrayList<String>();
public ListAdapter(Context context, List<String> fruitList) {
super(context, android.R.layout.simple_list_item_1, fruitList);
this.fruits = fruitList;
for (int x = 0; x < fruits.size(); x++) {
String fruit = fruits.get(x);
String ch = fruit.charAt(0)+"";
ch = ch.toUpperCase(Locale.US);
sectionLetters.add(ch);
}
ArrayList<String> sectionList = new ArrayList<String>(sectionLetters);
sections = new String[sectionList.size()];
sectionList.toArray(sections);
}
public int getPositionForSection(int section) {
Log.e("sushildlh", "" + section);
return section;
}
public int getSectionForPosition(int position) {
Log.d("sushildlh", "" + position);
return position;
}
public Object[] getSections() {
return sections;
}
}
這是 string.xml 文件中的fruits數組。
<string-array name="fruits_array">
<item>Apples</item>
<item>Apricots</item>
<item>Avocado</item>
<item>Annona</item>
<item>Banana</item>
<item>Bilberry</item>
<item>Blackberry</item>
<item>Custard Apple</item>
<item>Clementine</item>
<item>Cantalope</item>
<item>Coconut</item>
<item>Currant</item>
<item>Cherry</item>
<item>Cherimoya</item>
<item>Date</item>
<item>Damson</item>
<item>Durian</item>
<item>Elderberry</item>
<item>Fig</item>
<item>Feijoa</item>
<item>Grapefruit</item>
<item>Grape</item>
<item>Gooseberry</item>
<item>Guava</item>
<item>Honeydew melon</item>
<item>Huckleberry</item>
<item>Jackfruit</item>
<item>Juniper Berry</item>
<item>Jambul</item>
<item>Jujube</item>
<item>Kiwi</item>
<item>Kumquat</item>
<item>Lemons</item>
<item>Limes</item>
<item>Lychee</item>
<item>Mango</item>
<item>Mandarin</item>
<item>Mangostine</item>
<item>Nectaraine</item>
<item>Orange</item>
<item>Olive</item>
<item>Prunes</item>
<item>Pears</item>
<item>Plum</item>
<item>Pineapple</item>
<item>Peach</item>
<item>Papaya</item>
<item>Passionfruit</item>
<item>Pomegranate</item>
<item>Pomelo</item>
<item>Raspberries</item>
<item>Rock melon</item>
<item>Rambutan</item>
<item>Strawberries</item>
<item>Sweety</item>
<item>Salmonberry</item>
<item>Satsuma</item>
<item>Tangerines</item>
<item>Tomato</item>
<item>Ugli</item>
<item>Watermelon</item>
<item>Woodapple</item>
</string-array>
最后這是這些代碼的輸出....
隨意問你是否卡在代碼之間的任何地方......
注意:- FastScroll 圖像在不同版本的 android(例如:-棒棒糖、棉花糖等)中會有所不同,下面的輸出用於棒棒糖
對於自定義字母快速滾動視圖,只需在AppTheme
的style.xml
文件中添加這兩行。
<item name="android:fastScrollTextColor">@color/apptheme_color</item> //this is used for the color of the Alphabetical Fast scrollView
<item name="android:fastScrollPreviewBackgroundRight">@drawable/bg_default_focused_holo_light</item> //this is the image or and drawable file you want to set on Alphabetical Fast scrollView
自定義快速 Scorll 輸出:-
有一個很好的圖書館這里這個例子。 在Github 中還有一個很好的教程, 這里有這個例子。
用法:
制作一個實現 BubbleTextGetter 的 RecyclerView.Adapter,它給定數據中的位置將返回文本以顯示在氣泡彈出窗口中。 將 FastScroller 放置在包含 RecyclerView 的布局內(可能在右側區域)。
自定義 FastScroller 的一些缺點:
不支持方向更改,但可能很容易修復。 不支持其他 layoutManagers。 只有 LinearLayoutManager 需要 API 11 及以上。
代碼:
氣泡文本獲取器
public interface BubbleTextGetter
{
String getTextToShowInBubble(int pos);
}
recycler_view_fast_scroller__fast_scroller.xml
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<TextView
android:id="@+id/fastscroller_bubble"
android:layout_gravity="right|end"
android:gravity="center"
android:textSize="48sp" tools:text="A"
android:layout_width="wrap_content"
android:textColor="#FFffffff"
android:layout_height="wrap_content"
android:background="@drawable/recycler_view_fast_scroller__bubble"
android:visibility="visible"/>
<ImageView
android:id="@+id/fastscroller_handle"
android:layout_width="wrap_content"
android:layout_marginRight="8dp"
android:layout_marginLeft="8dp"
android:layout_height="wrap_content"
android:src="@drawable/recycler_view_fast_scroller__handle"/>
</merge>
現在這個 ScrollListener:
private class ScrollListener extends OnScrollListener
{
@Override
public void onScrolled(RecyclerView rv,int dx,int dy)
{
View firstVisibleView=recyclerView.getChildAt(0);
int firstVisiblePosition=recyclerView.getChildPosition(firstVisibleView);
int visibleRange=recyclerView.getChildCount();
int lastVisiblePosition=firstVisiblePosition+visibleRange;
int itemCount=recyclerView.getAdapter().getItemCount();
int position;
if(firstVisiblePosition==0)
position=0;
else if(lastVisiblePosition==itemCount-1)
position=itemCount-1;
else
position=firstVisiblePosition;
float proportion=(float)position/(float)itemCount;
setPosition(height*proportion);
}
}
}
這個自定義 LinearLayout:
public class FastScroller extends LinearLayout
{
private static final int BUBBLE_ANIMATION_DURATION=100;
private static final int TRACK_SNAP_RANGE=5;
private TextView bubble;
private View handle;
private RecyclerView recyclerView;
private final ScrollListener scrollListener=new ScrollListener();
private int height;
private ObjectAnimator currentAnimator=null;
public FastScroller(final Context context,final AttributeSet attrs,final int defStyleAttr)
{
super(context,attrs,defStyleAttr);
initialise(context);
}
public FastScroller(final Context context)
{
super(context);
initialise(context);
}
public FastScroller(final Context context,final AttributeSet attrs)
{
super(context,attrs);
initialise(context);
}
private void initialise(Context context)
{
setOrientation(HORIZONTAL);
setClipChildren(false);
LayoutInflater inflater=LayoutInflater.from(context);
inflater.inflate(R.layout.recycler_view_fast_scroller__fast_scroller,this,true);
bubble=(TextView)findViewById(R.id.fastscroller_bubble);
handle=findViewById(R.id.fastscroller_handle);
bubble.setVisibility(INVISIBLE);
}
@Override
protected void onSizeChanged(int w,int h,int oldw,int oldh)
{
super.onSizeChanged(w,h,oldw,oldh);
height=h;
}
@Override
public boolean onTouchEvent(@NonNull MotionEvent event)
{
final int action=event.getAction();
switch(action)
{
case MotionEvent.ACTION_DOWN:
if(event.getX()<handle.getX())
return false;
if(currentAnimator!=null)
currentAnimator.cancel();
if(bubble.getVisibility()==INVISIBLE)
showBubble();
handle.setSelected(true);
case MotionEvent.ACTION_MOVE:
setPosition(event.getY());
setRecyclerViewPosition(event.getY());
return true;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
handle.setSelected(false);
hideBubble();
return true;
}
return super.onTouchEvent(event);
}
public void setRecyclerView(RecyclerView recyclerView)
{
this.recyclerView=recyclerView;
recyclerView.setOnScrollListener(scrollListener);
}
private void setRecyclerViewPosition(float y)
{
if(recyclerView!=null)
{
int itemCount=recyclerView.getAdapter().getItemCount();
float proportion;
if(handle.getY()==0)
proportion=0f;
else if(handle.getY()+handle.getHeight()>=height-TRACK_SNAP_RANGE)
proportion=1f;
else
proportion=y/(float)height;
int targetPos=getValueInRange(0,itemCount-1,(int)(proportion*(float)itemCount));
recyclerView.scrollToPosition(targetPos);
String bubbleText=((BubbleTextGetter)recyclerView.getAdapter()).getTextToShowInBubble(targetPos);
bubble.setText(bubbleText);
}
}
private int getValueInRange(int min,int max,int value)
{
int minimum=Math.max(min,value);
return Math.min(minimum,max);
}
private void setPosition(float y)
{
int bubbleHeight=bubble.getHeight();
int handleHeight=handle.getHeight();
handle.setY(getValueInRange(0,height-handleHeight,(int)(y-handleHeight/2)));
bubble.setY(getValueInRange(0,height-bubbleHeight-handleHeight/2,(int)(y-bubbleHeight)));
}
private void showBubble()
{
AnimatorSet animatorSet=new AnimatorSet();
bubble.setVisibility(VISIBLE);
if(currentAnimator!=null)
currentAnimator.cancel();
currentAnimator=ObjectAnimator.ofFloat(bubble,"alpha",0f,1f).setDuration(BUBBLE_ANIMATION_DURATION);
currentAnimator.start();
}
private void hideBubble()
{
if(currentAnimator!=null)
currentAnimator.cancel();
currentAnimator=ObjectAnimator.ofFloat(bubble,"alpha",1f,0f).setDuration(BUBBLE_ANIMATION_DURATION);
currentAnimator.addListener(new AnimatorListenerAdapter()
{
@Override
public void onAnimationEnd(Animator animation)
{
super.onAnimationEnd(animation);
bubble.setVisibility(INVISIBLE);
currentAnimator=null;
}
@Override
public void onAnimationCancel(Animator animation)
{
super.onAnimationCancel(animation);
bubble.setVisibility(INVISIBLE);
currentAnimator=null;
}
});
currentAnimator.start();
}
您的活動onCreate
的最后一步:
setContentView(R.layout.activity_main);
RecyclerView recyclerView =(RecyclerView)findViewById(R.id.activity_main_recyclerview);
FastScroller fastScroller=(FastScroller)findViewById(R.id.fastscroller);
fastScroller.setRecyclerView(recyclerView);
活動_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/theme_background"
android:id="@+id/drawerlayout">
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:id="@+id/activity_main_id"
tools:context="objectdistance.ajai.ram.sita.gallery.MainActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="48dp"
app:expandedTitleMarginEnd="64dp"
android:fitsSystemWindows="true">
<ImageView
android:id="@+id/imagetoolbar"
android:layout_width="match_parent"
android:layout_height="200dp"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
android:foreground="@drawable/image_header_foreground"
app:layout_scrollFlags="scroll"
app:layout_collapseMode="parallax"/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
android:background="@drawable/theme_background"
app:layout_collapseMode="pin" >
<Spinner
android:id="@+id/spinner_nav"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:dropDownVerticalOffset="?attr/actionBarSize" />
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/activity_main_recyclerview"
android:layout_width="match_parent"
android:layout_height="@dimen/activity_main_height"
android:background="@android:color/darker_gray" />
</android.support.design.widget.CoordinatorLayout>
</android.support.v4.widget.DrawerLayout>
為了實現類似於電話聯系人列表或與問題中給出的圖像相同的內容,同時具有文本和圖像,這是我遇到的最佳解決方案!
這將適用於自定義列表,因為圖像可能需要與名稱一起存在。 以上解決方案只有字符串列表或數組,可能不是每個人都需要!
只需 3 個簡單步驟:
1.添加依賴implementation 'com.simplecityapps:recyclerview-fastscroll:2.0.1'
2.用com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
替換你的RecyclerView
3.在你的 recyclerview 適配器中實現FastScrollRecyclerView.SectionedAdapter
完成了!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.