AndroidRecyclerView水平分页滑动讲解
2023年7月7日发(作者:)
AndroidRecyclerView⽔平分页滑动讲解使⽤RecyclerView实现GridView和ViewPager滑动的分页效果,与上篇相似。效果图:简单的只能直接贴图全部代码了:1.主函数代码:package erview;import ;import patActivity;import erView;import Inflater;import ;import oup;import ion;import ionSet;import ionUtils;import AnimationController;import ew;import ;import aldesign.R;import ist;import ;/** * 分页滑动效果 */public class RecycleViewActivity extends AppCompatActivity { private PageRecyclerView mRecyclerView = null; private List dataList = null; private apter myAdapter = null; @Override protected void onCreate(Bundle savedInstanceState) { te(savedInstanceState); setContentView(ty_recycleview); initData(); mRecyclerView = (PageRecyclerView) findViewById(_swipe_view); // 设置指⽰器 icator((PageIndicatorView) findViewById(tor)); // 设置⾏数和列数 eSize(3, 3); // 设置页间距 eMargin(30); // Animation myAnim = imation(this, _from_right); lAfter(true);//android动画结束后停在结束位置 AnimationSet set = new AnimationSet(false); mation(myAnim); //加⼊动画集合 LayoutAnimationController controller = new LayoutAnimationController(set, 1); outAnimation(controller); //// outManager(new AutoGridLayoutManager(,())); // 设置数据 pter(myAdapter = PageAdapter(dataList, new ck() { @Override public lder onCreateViewHolder(ViewGroup parent, int viewType) { View view = ().inflate(, parent, false); return new MyHolder(view); } @Override public void onBindViewHolder(lder holder, int position) { ((MyHolder)holder).t((position)); } })); } private void initData() { dataList = new ArrayList<>(); for (int i = 0; i < 50; i++) { (f(i)); } } public class MyHolder extends lder { public TextView tv = null; public MyHolder(View itemView) { public MyHolder(View itemView) { super(itemView); tv = (TextView) ewById(); lickListener(new kListener() { @Override public void onClick(View v) { xt(, getAdapterPosition() + "", _SHORT).show(); } }); ongClickListener(new ClickListener() { @Override public boolean onLongClick(View v) { (getAdapterPosition()); return true; } }); } }}2.⾃定义GridLayoutManager 试控件可以⾃适应内容的⾼度import t;import youtManager;import erView;import uteSet;import ;/** *
*
* 重写GridLayoutManager,在{@link
*RecyclerView#setLayoutManager(Manager)}使⽤ * 此类替换{@link GridLayoutManager},使{@link RecyclerView}能够⾃使⽤内容的⾼度 * */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(er recycler, state, int widthSpec, int heightSpec) { //获取count判断,必须要有 int count = mCount(); if (count > 0) { if (measuredHeight <= 0) { View view = wForPosition(0); if (view != null) { measureChild(view, widthSpec, heightSpec); measuredWidth = e(widthSpec); measuredHeight = suredHeight() * getSpanCount(); } } setMeasuredDimension(measuredWidth, measuredHeight); }else { ure(recycler, state, widthSpec, heightSpec); } }}3.⾃定义圆点指⽰器,ViewPager共⽤的控件类型:import t;import uteSet;import y;import y;import ;import Layout;import ist;import ;/** *
* 指⽰器类,获得此类实例后,可通过{@link PageIndicatorView#initIndicator(int)}⽅法初始化指 * ⽰器 *
*/public class PageIndicatorView extends LinearLayout { private Context mContext = null; private int dotSize = 15; // 指⽰器的⼤⼩(dp) private int margins = 4; // 指⽰器间距(dp) private List 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) { xt = context; setGravity(); setOrientation(HORIZONTAL); dotSize = 2px(context, dotSize); margins = 2px(context, margins); } /** * 初始化指⽰器,默认选中第⼀页 * * @param count 指⽰器数量,即页数 */ public void initIndicator(int count) { if (indicatorViews == null) { indicatorViews = new ArrayList<>(); } else { (); removeAllViews(); } View view; LayoutParams params = new LayoutParams(dotSize, dotSize); gins(margins, margins, margins, margins); for (int i = 0; i < count; i++) { view = new View(mContext); kgroundResource(ce_invisible); addView(view, params); (view); } if (() > 0) { (0).setBackgroundResource(ce_online); } } /** * 设置选中页 * * @param selected 页下标,从0开始 */ public void setSelectedPage(int selected) { for (int i = 0; i < (); i++) { if (i == selected) { (i).setBackgroundResource(ce_online); } else { (i).setBackgroundResource(ce_invisible); } } }} 4.⾃定义分页RecyclerViewimport t;import ;import dapter;import erView;import uteSet;import Event;import ;import oup;import ;import s;/** * 横向分页的GridView效果 * 默认为1⾏,每页3列,如果要⾃定义⾏数和列数,请在调⽤{@link PageRecyclerView#setAdapter(Adapter)}⽅法前调⽤ * {@link PageRecyclerView#setPageSize(int, int)}⽅法⾃定义⾏数 */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) { xt = context; setLayoutManager(new AutoGridLayoutManager( mContext, spanRow, NTAL, false)); setOverScrollMode(OVER_SCROLL_NEVER); } /** * 设置⾏数和每页列数 * * @param spanRow ⾏数,<=0表⽰使⽤默认的⾏数 * @param spanColumn 每页列数,<=0表⽰使⽤默认每页列数 */ public void setPageSize(int spanRow, int spanColumn) { w = spanRow <= 0 ? w : spanRow; lumn = spanColumn <= 0 ? lumn : spanColumn; setLayoutManager(new AutoGridLayoutManager( mContext, w, NTAL, false)); } /** * 设置页间距 * * @param pageMargin 间距(px) */ public void setPageMargin(int pageMargin) { rgin = pageMargin; } /** * 设置指⽰器 * * @param indicatorView 指⽰器布局 */ public void setIndicator(PageIndicatorView indicatorView) { atorView = indicatorView; } @Override protected void onMeasure(int widthSpec, int heightSpec) { ure(widthSpec, heightSpec); shortestDistance = getMeasuredWidth() / 9;//3 } @Override public void setAdapter(Adapter adapter) { pter(adapter); ter = (PageAdapter) adapter; update(); } // 更新页码指⽰器和相关数据 private void update() { // 计算总页数 // 计算总页数 int temp = ((int) (() / (double) (spanRow * spanColumn))); if (temp != totalPage) { dicator(temp); // 页码减少且当前页为最后⼀页 if (temp < totalPage && currentPage == totalPage) { currentPage = temp; // 执⾏滚动 smoothScrollBy(-getWidth(), 0); } ectedPage(currentPage - 1); totalPage = temp; } } @Override public boolean onTouchEvent(MotionEvent event) { switch (ion()) { case _MOVE: if (currentPage == totalPage && downX - () > 0) { return true; } break; case _DOWN: downX = (); break; case _UP: slideDistance = () - downX; if ((slideDistance) > shortestDistance) { // 滑动距离⾜够,执⾏翻页 if (slideDistance > 0) { // 上⼀页 currentPage = currentPage == 1 ? 1 : currentPage - 1; } else { // 下⼀页 currentPage = currentPage == totalPage ? totalPage : currentPage + 1; } // 修改指⽰器选中项 ectedPage(currentPage - 1); } // 执⾏滚动 smoothScrollBy((int) ((currentPage - 1) * getWidth() - scrollX), 0); return true; default: break; } return hEvent(event); } @Override public void onScrolled(int dx, int dy) { scrollX += dx; lled(dx, dy); } /** * 数据适配器 */ public class PageAdapter extends r { private List> dataList = null; private CallBack mCallBack = null; private int itemWidth = 0; private int itemCount = 0; private int itemCount = 0; /** * 实例化适配器 * * @param data * @param callBack */ public PageAdapter(List> data, CallBack callBack) { st = data; ack = callBack; itemCount = () + spanRow * spanColumn; } @Override public lder onCreateViewHolder(ViewGroup parent, int viewType) { if (itemWidth <= 0) { // 计算Item的宽度 itemWidth = (th() - pageMargin * 2) / spanColumn; } lder holder = teViewHolder(parent, viewType); e(0, 0); outParams().width = itemWidth; outParams().height = suredHeight(); return holder; } @Override public void onBindViewHolder(lder holder, int position) { if (spanColumn == 1) { // 每个Item距离左右两侧各pageMargin outParams().width = itemWidth + pageMargin * 2; ding(pageMargin, 0, pageMargin, 0); } else { int m = position % (spanRow * spanColumn); if (m < spanRow) { // 每页左侧的Item距离左边pageMargin outParams().width = itemWidth + pageMargin; ding(pageMargin, 0, 0, 0); } else if (m >= spanRow * spanColumn - spanRow) { // 每页右侧的Item距离右边pageMargin outParams().width = itemWidth + pageMargin; ding(0, 0, pageMargin, 0); } else { // 中间的正常显⽰ outParams().width = itemWidth; ding(0, 0, 0, 0); } } if (position < ()) { ibility(E); ViewHolder(holder, position); } else { ibility(BLE); } } @Override public int getItemCount() { return itemCount; } } /** * 删除Item * * @param position 位置 */ public void remove(int position) { if (position < ()) { // 删除数据 (position); itemCount--; // 删除Item notifyItemRemoved(position); // 更新界⾯上发⽣改变的Item notifyItemRangeChanged(position, currentPage * spanRow * spanColumn); // 更新页码指⽰器 update(); } } } public interface CallBack { /** * 创建VieHolder * * @param parent * @param viewType */ lder onCreateViewHolder(ViewGroup parent, int viewType); /** * 绑定数据到ViewHolder * * @param holder * @param position */ void onBindViewHolder(lder holder, int position); }}5.像素转换⼯具类:import t;/** * 像素转换⼯具 */public class DimensionConvert { /** * 根据⼿机的分辨率从 dp 的单位 转成为 px(像素) * * @param context * @param dpValue 要转换的dp值 */ public static int dip2px(Context context, float dpValue) { final float scale = ources().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 = ources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); }}6.布局:activity_
发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1688675768a161703.html
评论列表(0条)