前些天看到有人在論壇上問這種效果怎么實現,沒寫過也沒用過這個功能,網上查了一下,大多是使用ViewPager+GridView或者HorizontalScrollView+GridView實現,不過貌似有點復雜,太懶,沒仔細看。這兩天學習RecyclerView的使用(網上有很多文章,建議大家閱讀本博客的時候先去了解一下),發現RecyclerView可以實現GridView 的橫向滾動效果,不過沒有分頁,因此決定自己寫一個。
Demo已上傳到GitHub,CSDN下載頻道,是AS項目,使用AS的同學可以直接下載或者clone,博文最后也有貼出完整代碼,使用Eclipse的同學可以自己新建項目並Copy代碼。
效果圖:
(由於這里每個Item都很相像,所以效果看起來不是很好,請見諒)
圖1:
圖2:
(刪除的操作是在長按事件中寫的)
圖1是帶頁碼指示器的多行橫向分頁的GridView效果,拖動距離不足時,還可以滾動回原來的位置(類似於ViewPager拖動距離不足的效果);
圖2是和ViewPager一模一樣的效果,實現此效果只要設置行數和列數都為1即可。
使用以下代碼,需要導入RecyclerView的jar包或者依賴
代碼結構:

- AutoGridLayoutManager繼承自GridLayoutManager並重寫了
onMeasure方法,目的是使RecyclerView的高度自適應內容高度。 - DimensionConvert是一個用來轉換px和pd的工具類。
- MainActivity是一個使用示例。
- PageIndicatorView繼承自LinearLayout,存放一些小圓點作為頁碼指示器。
- PageRecyclerView繼承自RecyclerView,用來完成分頁等功能。
先簡單講一下實現步驟,之后貼完整的代碼
第一步: 實現橫向滾動的GridView效果
這個很簡單,只要給RecyclerView設置橫向的GridLayoutManager就可以了。但是使用過程中發現,RecyclerView並不會自適應內容的高度,因此重寫了GridLayoutManager的onMeasure方法(MyGridLayoutManager.java);
@Override public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) { View view = recycler.getViewForPosition(0); if (view != null) { measureChild(view, widthSpec, heightSpec); int measuredWidth = View.MeasureSpec.getSize(widthSpec); int measuredHeight = view.getMeasuredHeight() * getSpanCount(); setMeasuredDimension(measuredWidth, measuredHeight); } }
第二步:實現自定義行數和列數功能
實現此功能需要重寫RecyclerView(MyRecyclerView.java),並添加兩個成員變量spanRow、spanColumn和一個設置行數列數的方法setPageSize(int spanRow, int spanColumn)。
之后,在Adapter中生成Item的時候就可以根據設置好的PageRecyclerView的寬度和列數計算單個Item的寬度,以達到一頁正好顯示固定列數的目的:
@Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (itemWidth <= 0) { // 計算Item的寬度 itemWidth = (parent.getWidth() - pageMargin * 2) / spanColumn; } RecyclerView.ViewHolder holder = mCallBack.onCreateViewHolder(parent, viewType); holder.itemView.measure(0, 0); holder.itemView.getLayoutParams().width = itemWidth; holder.itemView.getLayoutParams().height = holder.itemView.getMeasuredHeight(); return holder; }
可以看到上面代碼中有一個mCallBack變量,這是一個接口的實現類的實例,我們需要創建Adapter實例的時候傳入一個此接口的子類實例。
public interface CallBack { /** * 創建VieHolder * * @param parent * @param viewType */ RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType); /** * 綁定數據到ViewHolder * * @param holder * @param position */ void onBindViewHolder(RecyclerView.ViewHolder holder, int position); }
此接口共有兩個方法,這兩個方法和Adapter中需要重寫的兩個方法一樣,用法也一樣,分別用來創建ViewHolder實例和給ViewHolder中的控件綁定數據。
第三步:開始分頁滾動
1> 分頁:
完成第二步之后,布局就調整好了,之后我們實現分頁滾動的功能。要分頁就肯定需要總頁數(totalPage)和當前頁碼(currentPage),我們需要在設置Adapter適配器之后根據Item的總數和每頁的Item數計算總頁數:
@Override public void setAdapter(Adapter adapter) { super.setAdapter(adapter); // 計算總頁數 totalPage = ((int) Math.ceil(adapter.getItemCount() / (double) (spanRow * spanColumn))); mIndicatorView.initIndicator(totalPage); }
然后就可以重寫RecyclerView的onTouchEvent方法實現分頁,根據ACTION_DOWN和ACTION_UP時候的坐標計算滑動方向,在ACTION_UP的時候根據滑動的方向使用smoothScrollBy方法向左或向右滑動一個MyRecyclerView的寬度就可以了。
不過這種切換頁面的方式很生硬,我們要實現的ViewPager的滑動效果:要滑動超過一定的距離才能切換頁碼,否則滾回原來的位置。實現此功能需要一個常量,不過為了適應各種寬度的MyRecyclerView,這里根據MyRecyclerView的寬度動態設置最小滾動距離:
private int shortestDistance; // 超過此距離的滑動才有效 @Override protected void onMeasure(int widthSpec, int heightSpec) { super.onMeasure(widthSpec, heightSpec); shortestDistance = getMeasuredWidth() / 3; }
還需要其他的幾個變量:
private float downX = 0; // 手指按下的X軸坐標 private float slideDistance = 0; // 滑動的距離 private float scrollX = 0; // X軸當前的位置
scrollX為當前滾動的位置,重寫onScrolled計算滾動到的位置:
@Override public void onScrolled(int dx, int dy) { scrollX += dx; super.onScrolled(dx, dy); }
之后就可以編寫完整的onTouchEvent方法:
@Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: downX = event.getX(); break; case MotionEvent.ACTION_UP: slideDistance = event.getX() - downX; if (Math.abs(slideDistance) > shortestDistance) { // 滑動距離足夠,執行翻頁 if (slideDistance > 0) { // 上一頁 currentPage = currentPage == 1 ? 1 : currentPage - 1; } else { // 下一頁 currentPage = currentPage == totalPage ? totalPage : currentPage + 1; } } // 執行滾動 smoothScrollBy((int) ((currentPage - 1) * getWidth() - scrollX), 0); return true; default: break; } return super.onTouchEvent(event);
2> 頁間距
為了分頁更加清晰,還需要給頁與頁添加間距:
首先添加一個成員變量,和set方法
private int pageMargin = 0; // 頁間距 /** * 設置頁間距 * * @param pageMargin 間距(px) */ public void setPageMargin(int pageMargin) { this.pageMargin = pageMargin; }
然后重寫Adapter的onBindViewHolder方法調整頁間距:
@Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (spanColumn == 1) { // 每個Item距離左右兩側各pageMargin holder.itemView.getLayoutParams().width = itemWidth + pageMargin * 2; holder.itemView.setPadding(pageMargin, 0, pageMargin, 0); } else { int m = position % (spanRow * spanColumn); if (m < spanRow) { // 每頁左側的Item距離左邊pageMargin holder.itemView.getLayoutParams().width = itemWidth + pageMargin; holder.itemView.setPadding(pageMargin, 0, 0, 0); } else if (m >= spanRow * spanColumn - spanRow) { // 每頁右側的Item距離右邊pageMargin holder.itemView.getLayoutParams().width = itemWidth + pageMargin; holder.itemView.setPadding(0, 0, pageMargin, 0); } else { // 中間的正常顯示 holder.itemView.getLayoutParams().width = itemWidth; holder.itemView.setPadding(0, 0, 0, 0); } } }
3> 占位Item
為了最后不足一頁時也能完整顯示,還需要在最后不足一頁時,生成占位的View,因此修改Adapter的onBindViewHolder方法和getItemCount方法:
@Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { ... if (position < dataList.size()) { holder.itemView.setAlpha(1); mCallBack.onBindViewHolder(holder, position); } else { holder.itemView.setAlpha(0); } } @Override public int getItemCount() { int m = dataList.size() % (spanRow * spanColumn); if (m == 0) { return dataList.size(); } else { return dataList.size() + (spanRow * spanColumn - m); } }
至此,分頁功能就完成了,為了功能更豐滿,還需要添加一個分頁指示器(就是效果圖中的小圓點),這個功能還是很簡單的,新建一個類繼承LinearLayout並根據總頁數生成一些小圓點的View,然后提供一個修改當前頁碼的方法就OK啦。
第四步:刪除Item
最后還有一個刪除Item的功能,實現方式還是使用系統的Adapter的notifyItemRemoved(int position);方法,由於前面分頁時給部分Item設置了padding,所以為了布局不會錯亂,還需要更新其他改變的Item:
// 刪除Item notifyItemRemoved(position); // 更新界面上發生改變的Item notifyItemRangeChanged(position, currentPage * spanRow * spanColumn);
然后還要更新頁碼指示器,這里就不貼代碼了,直接看下面的類就可以了。
使用的時候只要把指示器和MyRecyclerView按照自己的需求布局,並在切換頁面的時候更新指示器就完成了。
改:
1. 上面分頁滑動是在onTouchEvent()方法中實現的,但是后來發現,這種實現方式會導致給Item添加onClickListener、onLongClickListener、onTouchListener的時候會產生事件沖突,因此修改為在onScrollStateChanged()方法中實現,代碼如下:
/* * 0: 停止滾動且手指移開; 1: 開始滾動; 2: 手指做了拋的動作(手指離開屏幕前,用力滑了一下) */ private int scrollState = 0; // 滾動狀態 @Override public void onScrollStateChanged(int state) { switch (state) { case 2: scrollState = 2; break; case 1: scrollState = 1; break; case 0: if (slideDistance == 0) { break; } scrollState = 0; if (slideDistance < 0) { // 上頁 currentPage = (int) Math.ceil(scrollX / getWidth()); if (currentPage * getWidth() - scrollX < shortestDistance) { currentPage += 1; } } else { // 下頁 currentPage = (int) Math.ceil(scrollX / getWidth()) + 1; if (currentPage <= totalPage) { if (scrollX - (currentPage - 2) * getWidth() < shortestDistance) { // 如果這一頁滑出距離不足,則定位到前一頁 currentPage -= 1; } } else { currentPage = totalPage; } } // 執行自動滾動 smoothScrollBy((int) ((currentPage - 1) * getWidth() - scrollX), 0); // 修改指示器選中項 mIndicatorView.setSelectedPage(currentPage - 1); slideDistance = 0; break; } super.onScrollStateChanged(state); } @Override public void onScrolled(int dx, int dy) { scrollX += dx; if (scrollState == 1) { slideDistance += dx; } super.onScrolled(dx, dy); }
- RecyclerView的GridLayoutManager是從上到下從左到右排列的,而我們分頁時大多需要的是從左到右從上到下排列,因此增加一個方法調整位置(此方法只適用於3*3排列的,還沒有找到通用的方法,如果那位同學有方法,麻煩分享一下,先謝過)
private void countRealPosition(int position) { // 為了使Item從左到右從上到下排列,需要position的值 int m = position % (spanRow * spanColumn); switch (m) { case 1: case 5: realPosition = position + 2; break; case 3: case 7: realPosition = position - 2; break; case 2: realPosition = position + 4; break; case 6: realPosition = position - 4; break; case 0: case 4: case 8: realPosition = position; break; } }
<<<<<<<<<<<<<<<<<<<<<<使用方法參考MainActivity.java>>>>>>>>>>>>>>>>>>>>
上面講的不夠詳細,具體見代碼>>>>>>>>>>>>>>
完整代碼:
AutoGridLayoutManager.java
使用這個類替代GridLayoutManager是為了使RecyclerView及其子類能夠自適應內容的高度。
import android.content.Context; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; import android.view.View; /** * Created by shichaohui on 2015/7/9 0009. * <p> * 重寫GridLayoutManager,在{@link RecyclerView#setLayoutManager(RecyclerView.LayoutManager)}使用 * 此類替換{@link GridLayoutManager},使{@link RecyclerView}能夠自使用內容的高度 * </p> */ public class AutoGridLayoutManager extends GridLayoutManager { private int measuredWidth = 0; private int measuredHeight = 0; public AutoGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } public AutoGridLayoutManager(Context context, int spanCount) { super(context, spanCount); } public AutoGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) { super(context, spanCount, orientation, reverseLayout); } @Override public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) { if (measuredHeight <= 0) { View view = recycler.getViewForPosition(0); if (view != null) { measureChild(view, widthSpec, heightSpec); measuredWidth = View.MeasureSpec.getSize(widthSpec); measuredHeight = view.getMeasuredHeight() * getSpanCount(); } } setMeasuredDimension(measuredWidth, measuredHeight); } }
PageRecyclerView.java
重寫RecyclerView實現分頁
import android.content.Context; import android.graphics.Color; import android.support.v4.view.PagerAdapter; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import java.util.List; import java.util.Objects; /** * Created by shichaohui on 2015/7/9 0009. * <p> * 橫向分頁的GridView效果 * </p> * <p> * 默認為1行,每頁3列,如果要自定義行數和列數,請在調用{@link PageRecyclerView#setAdapter(Adapter)}方法前調用 * {@link PageRecyclerView#setPageSize(int, int)}方法自定義行數 * </p> */ public class PageRecyclerView extends RecyclerView { private Context mContext = null; private PageAdapter myAdapter = null; private int shortestDistance; // 超過此距離的滑動才有效 private float downX = 0; // 手指按下的X軸坐標 private float slideDistance = 0; // 滑動的距離 private float scrollX = 0; // X軸當前的位置 private int spanRow = 1; // 行數 private int spanColumn = 3; // 每頁列數 private int totalPage = 0; // 總頁數 private int currentPage = 1; // 當前頁 private int pageMargin = 0; // 頁間距 private PageIndicatorView mIndicatorView = null; // 指示器布局 public PageRecyclerView(Context context) { this(context, null); } public PageRecyclerView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public PageRecyclerView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); defaultInit(context); } // 默認初始化 private void defaultInit(Context context) { this.mContext = context; setLayoutManager(new AutoGridLayoutManager( mContext, spanRow, AutoGridLayoutManager.HORIZONTAL, false)); setOverScrollMode(OVER_SCROLL_NEVER); } /** * 設置行數和每頁列數 * * @param spanRow 行數,<=0表示使用默認的行數 * @param spanColumn 每頁列數,<=0表示使用默認每頁列數 */ public void setPageSize(int spanRow, int spanColumn) { this.spanRow = spanRow <= 0 ? this.spanRow : spanRow; this.spanColumn = spanColumn <= 0 ? this.spanColumn : spanColumn; setLayoutManager(new AutoGridLayoutManager( mContext, this.spanRow, AutoGridLayoutManager.HORIZONTAL, false)); } /** * 設置頁間距 * * @param pageMargin 間距(px) */ public void setPageMargin(int pageMargin) { this.pageMargin = pageMargin; } /** * 設置指示器 * * @param indicatorView 指示器布局 */ public void setIndicator(PageIndicatorView indicatorView) { this.mIndicatorView = indicatorView; } @Override protected void onMeasure(int widthSpec, int heightSpec) { super.onMeasure(widthSpec, heightSpec); shortestDistance = getMeasuredWidth() / 3; } @Override public void setAdapter(Adapter adapter) { super.setAdapter(adapter); this.myAdapter = (PageAdapter) adapter; update(); } // 更新頁碼指示器和相關數據 private void update() { // 計算總頁數 int temp = ((int) Math.ceil(myAdapter.dataList.size() / (double) (spanRow * spanColumn))); if (temp != totalPage) { mIndicatorView.initIndicator(temp); // 頁碼減少且當前頁為最后一頁 if (temp < totalPage && currentPage == totalPage) { currentPage = temp; // 執行滾動 smoothScrollBy(-getWidth(), 0); } mIndicatorView.setSelectedPage(currentPage - 1); totalPage = temp; } } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_MOVE: if (currentPage == totalPage && downX - event.getX() > 0) { return true; } break; case MotionEvent.ACTION_DOWN: downX = event.getX(); break; case MotionEvent.ACTION_UP: slideDistance = event.getX() - downX; if (Math.abs(slideDistance) > shortestDistance) { // 滑動距離足夠,執行翻頁 if (slideDistance > 0) { // 上一頁 currentPage = currentPage == 1 ? 1 : currentPage - 1; } else { // 下一頁 currentPage = currentPage == totalPage ? totalPage : currentPage + 1; } // 修改指示器選中項 mIndicatorView.setSelectedPage(currentPage - 1); } // 執行滾動 smoothScrollBy((int) ((currentPage - 1) * getWidth() - scrollX), 0); return true; default: break; } return super.onTouchEvent(event); } @Override public void onScrolled(int dx, int dy) { scrollX += dx; super.onScrolled(dx, dy); } /** * 數據適配器 */ public class PageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private List<?> dataList = null; private CallBack mCallBack = null; private int itemWidth = 0; private int itemCount = 0; /** * 實例化適配器 * * @param data * @param callBack */ public PageAdapter(List<?> data, CallBack callBack) { this.dataList = data; this.mCallBack = callBack; itemCount = dataList.size() + spanRow * spanColumn; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (itemWidth <= 0) { // 計算Item的寬度 itemWidth = (parent.getWidth() - pageMargin * 2) / spanColumn; } RecyclerView.ViewHolder holder = mCallBack.onCreateViewHolder(parent, viewType); holder.itemView.measure(0, 0); holder.itemView.getLayoutParams().width = itemWidth; holder.itemView.getLayoutParams().height = holder.itemView.getMeasuredHeight(); return holder; } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (spanColumn == 1) { // 每個Item距離左右兩側各pageMargin holder.itemView.getLayoutParams().width = itemWidth + pageMargin * 2; holder.itemView.setPadding(pageMargin, 0, pageMargin, 0); } else { int m = position % (spanRow * spanColumn); if (m < spanRow) { // 每頁左側的Item距離左邊pageMargin holder.itemView.getLayoutParams().width = itemWidth + pageMargin; holder.itemView.setPadding(pageMargin, 0, 0, 0); } else if (m >= spanRow * spanColumn - spanRow) { // 每頁右側的Item距離右邊pageMargin holder.itemView.getLayoutParams().width = itemWidth + pageMargin; holder.itemView.setPadding(0, 0, pageMargin, 0); } else { // 中間的正常顯示 holder.itemView.getLayoutParams().width = itemWidth; holder.itemView.setPadding(0, 0, 0, 0); } } if (position < dataList.size()) { holder.itemView.setVisibility(View.VISIBLE); mCallBack.onBindViewHolder(holder, position); } else { holder.itemView.setVisibility(View.INVISIBLE); } } @Override public int getItemCount() { return itemCount; } /** * 刪除Item * @param position 位置 */ public void remove(int position) { if (position < dataList.size()) { // 刪除數據 dataList.remove(position); itemCount--; // 刪除Item notifyItemRemoved(position); // 更新界面上發生改變的Item notifyItemRangeChanged(position, currentPage * spanRow * spanColumn); // 更新頁碼指示器 update(); } } } public interface CallBack { /** * 創建VieHolder * * @param parent * @param viewType */ RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType); /** * 綁定數據到ViewHolder * * @param holder * @param position */ void onBindViewHolder(RecyclerView.ViewHolder holder, int position); } } PageIndicatorView.java 頁碼指示器 ,此類可以作為一個工具類,在ViewPager做的輪播圖上也可以使用 import android.content.Context; import android.util.AttributeSet; import android.view.Gravity; import android.view.View; import android.widget.LinearLayout; import java.util.ArrayList; import java.util.List; /** * Created by shichaohui on 2015/7/10 0010. * <p/> * 頁碼指示器類,獲得此類實例后,可通過{@link PageIndicatorView#initIndicator(int)}方法初始化指示器 * </P> */ public class PageIndicatorView extends LinearLayout { private Context mContext = null; private int dotSize = 15; // 指示器的大小(dp) private int margins = 4; // 指示器間距(dp) private List<View> indicatorViews = null; // 存放指示器 public PageIndicatorView(Context context) { this(context, null); } public PageIndicatorView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public PageIndicatorView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } private void init(Context context) { this.mContext = context; setGravity(Gravity.CENTER); setOrientation(HORIZONTAL); dotSize = DimensionConvert.dip2px(context, dotSize); margins = DimensionConvert.dip2px(context, margins); } /** * 初始化指示器,默認選中第一頁 * * @param count 指示器數量,即頁數 */ public void initIndicator(int count) { if (indicatorViews == null) { indicatorViews = new ArrayList<>(); } else { indicatorViews.clear(); removeAllViews(); } View view; LayoutParams params = new LayoutParams(dotSize, dotSize); params.setMargins(margins, margins, margins, margins); for (int i = 0; i < count; i++) { view = new View(mContext); view.setBackgroundResource(android.R.drawable.presence_invisible); addView(view, params); indicatorViews.add(view); } if (indicatorViews.size() > 0) { indicatorViews.get(0).setBackgroundResource(android.R.drawable.presence_online); } } /** * 設置選中頁 * * @param selected 頁下標,從0開始 */ public void setSelectedPage(int selected) { for (int i = 0; i < indicatorViews.size(); i++) { if (i == selected) { indicatorViews.get(i).setBackgroundResource(android.R.drawable.presence_online); } else { indicatorViews.get(i).setBackgroundResource(android.R.drawable.presence_invisible); } } } }
DimensionConvert.java
用來轉換dip和px的工具類
import android.content.Context; /** * Created by shichaohui on 2015/7/10 0010. */ public class DimensionConvert { /** * 根據手機的分辨率從 dp 的單位 轉成為 px(像素) * * @param context * @param dpValue 要轉換的dp值 */ public static int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } /** * 根據手機的分辨率從 px(像素) 的單位 轉成為 dp * * @param context * @param pxValue 要轉換的px值 */ public static int px2dip(Context context, float pxValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); } }
MainActivity.java
import android.app.Activity; import android.os.Bundle; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import android.widget.Toast; import java.util.ArrayList; import java.util.List; public class MainActivity extends Activity { private PageRecyclerView mRecyclerView = null; private List<String> dataList = null; private PageRecyclerView.PageAdapter myAdapter = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initData(); mRecyclerView = (PageRecyclerView) findViewById(R.id.cusom_swipe_view); // 設置指示器 mRecyclerView.setIndicator((PageIndicatorView) findViewById(R.id.indicator)); // 設置行數和列數 mRecyclerView.setPageSize(3, 3); // 設置頁間距 mRecyclerView.setPageMargin(30); // 設置數據 mRecyclerView.setAdapter(myAdapter = mRecyclerView.new PageAdapter(dataList, new PageRecyclerView.CallBack() { @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(MainActivity.this).inflate(R.layout.item, parent, false); return new MyHolder(view); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { ((MyHolder)holder).tv.setText(dataList.get(position)); } })); } private void initData() { dataList = new ArrayList<>(); for (int i = 0; i < 50; i++) { dataList.add(String.valueOf(i)); } } public class MyHolder extends RecyclerView.ViewHolder { public TextView tv = null; public MyHolder(View itemView) { super(itemView); tv = (TextView) itemView.findViewById(R.id.text); tv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this, getAdapterPosition() + "", Toast.LENGTH_SHORT).show(); } }); tv.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { myAdapter.remove(getAdapterPosition()); return true; } }); } } }
最后是兩個布局文件:
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:orientation="vertical" android:layout_height="match_parent"> <com.example.sch.myapplication.PageRecyclerView android:id="@+id/cusom_swipe_view" android:layout_width="match_parent" android:layout_height="match_parent" /> <com.example.sch.myapplication.PageIndicatorView android:id="@+id/indicator" android:layout_width="match_parent" android:layout_marginBottom="20dp" android:layout_height="wrap_content" android:layout_gravity="bottom"/> </LinearLayout>
item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/text" android:layout_width="match_parent" android:layout_height="50dp" android:layout_margin="10dp" android:background="#770000ff" android:gravity="center" /> </LinearLayout>
