横向滑动分页的recycleview

为了实现下图中的效果


描述一下需求:

1.根据后台返回的菜单数量,每页展示10条? 不够10条也要占用一页? 比如20条是两页,21条是3页

2.可以左右滑动,下方指示器跟着左右动

下面开始表演

1.首先自定义一个Helper,用于分页

public class PagingScrollHelper {

? ? RecyclerView mRecyclerView= null;

? ? private MyOnScrollListener mOnScrollListener= new MyOnScrollListener();

? ? private MyOnFlingListener mOnFlingListener= new MyOnFlingListener();

? ? private int offsetY= 0;

? ? private int offsetX= 0;

? ? int startY= 0;

? ? int startX= 0;

? ? enum ORIENTATION {

? ? ? ? HORIZONTAL, VERTICAL, NULL

? ? }

? ? private ORIENTATION mOrientation= ORIENTATION.HORIZONTAL;

? ? public void setUpRecycleView(RecyclerView recycleView) {

? ? ? ? if (recycleView == null) {

? ? ? ? ? ? throw new IllegalArgumentException("recycleView must be not null");

}

? ? ? ? mRecyclerView= recycleView;

? ? ? ? //处理滑动

? ? ? ? recycleView.setOnFlingListener(mOnFlingListener);

? ? ? ? //设置滚动监听,记录滚动的状态,和总的偏移量

? ? ? ? recycleView.setOnScrollListener(mOnScrollListener);

? ? ? ? //记录滚动开始的位置

? ? ? ? recycleView.setOnTouchListener(mOnTouchListener);

? ? ? ? //获取滚动的方向

? ? ? ? updateLayoutManger();

}

? ? public void updateLayoutManger() {

? ? ? ? RecyclerView.LayoutManager layoutManager= mRecyclerView.getLayoutManager();

? ? ? ? if (layoutManager!= null) {

? ? ? ? ? ? if (layoutManager.canScrollVertically()) {

? ? ? ? ? ? ? ? mOrientation= ORIENTATION.VERTICAL;

? ? ? ? ? ? } else if (layoutManager.canScrollHorizontally()) {

? ? ? ? ? ? ? ? mOrientation= ORIENTATION.HORIZONTAL;

? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? mOrientation= ORIENTATION.NULL;

}

? ? ? ? ? ? if (mAnimator!= null) {

? ? ? ? ? ? ? ? mAnimator.cancel();

}

? ? ? ? ? ? startX= 0;

? ? ? ? ? ? startY= 0;

? ? ? ? ? ? offsetX= 0;

? ? ? ? ? ? offsetY= 0;

}

}

? ? /**

* 获取总共的页数

*/

? ? public int getPageCount() {

? ? ? ? if (mRecyclerView!= null) {

? ? ? ? ? ? if (mOrientation== ORIENTATION.NULL) {

? ? ? ? ? ? ? ? return 0;

}

? ? ? ? ? ? if (mOrientation== ORIENTATION.VERTICAL && mRecyclerView.computeVerticalScrollExtent() != 0) {

? ? ? ? ? ? ? ? return mRecyclerView.computeVerticalScrollRange() / mRecyclerView.computeVerticalScrollExtent();

? ? ? ? ? ? } else if (mRecyclerView.computeHorizontalScrollExtent() != 0) {

? ? ? ? ? ? ? ? return mRecyclerView.computeHorizontalScrollRange() / mRecyclerView.computeHorizontalScrollExtent();

}

}

? ? ? ? return 0;

}

? ? ValueAnimator mAnimator= null;

? ? public void scrollToPosition(int position) {

? ? ? ? if (mAnimator== null) {

? ? ? ? ? ? mOnFlingListener.onFling(0, 0);

}

? ? ? ? if (mAnimator!= null) {

? ? ? ? ? ? int startPoint= mOrientation== ORIENTATION.VERTICAL ? offsetY: offsetX, endPoint= 0;

? ? ? ? ? ? if (mOrientation== ORIENTATION.VERTICAL) {

? ? ? ? ? ? ? ? endPoint= mRecyclerView.getHeight() * position;

? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? endPoint= mRecyclerView.getWidth() * position;

}

? ? ? ? ? ? if (startPoint!= endPoint) {

? ? ? ? ? ? ? ? mAnimator.setIntValues(startPoint, endPoint);

? ? ? ? ? ? ? ? mAnimator.start();

}

}

}

? ? public class MyOnFlingListener extends RecyclerView.OnFlingListener {

? ? ? ? @Override

? ? ? ? public boolean onFling(int velocityX, int velocityY) {

? ? ? ? ? ? if (mOrientation== ORIENTATION.NULL) {

? ? ? ? ? ? ? ? return false;

}

? ? ? ? ? ? //获取开始滚动时所在页面的index

? ? ? ? ? ? int p= getStartPageIndex();

? ? ? ? ? ? //记录滚动开始和结束的位置

? ? ? ? ? ? int endPoint= 0;

? ? ? ? ? ? int startPoint= 0;

? ? ? ? ? ? //如果是垂直方向

? ? ? ? ? ? if (mOrientation== ORIENTATION.VERTICAL) {

? ? ? ? ? ? ? ? startPoint= offsetY;

? ? ? ? ? ? ? ? if (velocityY < 0) {

? ? ? ? ? ? ? ? ? ? p--;

? ? ? ? ? ? ? ? } else if (velocityY > 0) {

? ? ? ? ? ? ? ? ? ? p++;

}

? ? ? ? ? ? ? ? //更具不同的速度判断需要滚动的方向

//注意,此处有一个技巧,就是当速度为0的时候就滚动会开始的页面,即实现页面复位

? ? ? ? ? ? ? ? endPoint= p* mRecyclerView.getHeight();

? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? startPoint= offsetX;

? ? ? ? ? ? ? ? if (velocityX < 0) {

? ? ? ? ? ? ? ? ? ? p--;

? ? ? ? ? ? ? ? } else if (velocityX > 0) {

? ? ? ? ? ? ? ? ? ? p++;

}

? ? ? ? ? ? ? ? endPoint= p* mRecyclerView.getWidth();

}

? ? ? ? ? ? if (endPoint< 0) {

? ? ? ? ? ? ? ? endPoint= 0;

}

? ? ? ? ? ? //使用动画处理滚动

? ? ? ? ? ? if (mAnimator== null) {

? ? ? ? ? ? ? ? mAnimator= new ValueAnimator().ofInt(startPoint, endPoint);

? ? ? ? ? ? ? ? mAnimator.setDuration(300);

? ? ? ? ? ? ? ? mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public void onAnimationUpdate(ValueAnimator animation) {

? ? ? ? ? ? ? ? ? ? ? ? int nowPoint= (int) animation.getAnimatedValue();

? ? ? ? ? ? ? ? ? ? ? ? if (mOrientation== ORIENTATION.VERTICAL) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? int dy= nowPoint- offsetY;

? ? ? ? ? ? ? ? ? ? ? ? ? ? //这里通过RecyclerView的scrollBy方法实现滚动。

? ? ? ? ? ? ? ? ? ? ? ? ? ? mRecyclerView.scrollBy(0, dy);

? ? ? ? ? ? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? ? ? ? ? ? ? int dx= nowPoint- offsetX;

? ? ? ? ? ? ? ? ? ? ? ? ? ? mRecyclerView.scrollBy(dx, 0);

}

}

});

? ? ? ? ? ? ? ? mAnimator.addListener(new AnimatorListenerAdapter() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public void onAnimationEnd(Animator animation) {

? ? ? ? ? ? ? ? ? ? ? ? //回调监听

? ? ? ? ? ? ? ? ? ? ? ? if (null != mOnPageChangeListener) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? mOnPageChangeListener.onPageChange(getPageIndex());

}

? ? ? ? ? ? ? ? ? ? ? ? //修复双击item bug

? ? ? ? ? ? ? ? ? ? ? ? mRecyclerView.stopScroll();

? ? ? ? ? ? ? ? ? ? ? ? startY= offsetY;

? ? ? ? ? ? ? ? ? ? ? ? startX= offsetX;

}

});

? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? mAnimator.cancel();

? ? ? ? ? ? ? ? mAnimator.setIntValues(startPoint, endPoint);

}

? ? ? ? ? ? mAnimator.start();

? ? ? ? ? ? return true;

}

}

? ? public class MyOnScrollListener extends RecyclerView.OnScrollListener {

? ? ? ? @Override

? ? ? ? public void onScrollStateChanged(RecyclerView recyclerView, int newState) {

? ? ? ? ? ? //newState==0表示滚动停止,此时需要处理回滚

? ? ? ? ? ? if (newState == 0 && mOrientation!= ORIENTATION.NULL) {

? ? ? ? ? ? ? ? boolean move;

? ? ? ? ? ? ? ? int vX= 0, vY= 0;

? ? ? ? ? ? ? ? if (mOrientation== ORIENTATION.VERTICAL) {

? ? ? ? ? ? ? ? ? ? int absY= Math.abs(offsetY- startY);

? ? ? ? ? ? ? ? ? ? //如果滑动的距离超过屏幕的一半表示需要滑动到下一页

? ? ? ? ? ? ? ? ? ? move= absY> recyclerView.getHeight() / 2;

? ? ? ? ? ? ? ? ? ? vY= 0;

? ? ? ? ? ? ? ? ? ? if (move) {

? ? ? ? ? ? ? ? ? ? ? ? vY= offsetY- startY< 0 ? -1000 : 1000;

}

? ? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? ? ? int absX= Math.abs(offsetX- startX);

? ? ? ? ? ? ? ? ? ? move= absX> recyclerView.getWidth() / 2;

? ? ? ? ? ? ? ? ? ? if (move) {

? ? ? ? ? ? ? ? ? ? ? ? vX= offsetX- startX< 0 ? -1000 : 1000;

}

}

? ? ? ? ? ? ? ? mOnFlingListener.onFling(vX, vY);

}

}

? ? ? ? @Override

? ? ? ? public void onScrolled(RecyclerView recyclerView, int dx, int dy) {

? ? ? ? ? ? //滚动结束记录滚动的偏移量

? ? ? ? ? ? offsetY+= dy;

? ? ? ? ? ? offsetX+= dx;

}

}

? ? private MyOnTouchListener mOnTouchListener= new MyOnTouchListener();

? ? private boolean firstTouch= true;

? ? public class MyOnTouchListener implements View.OnTouchListener {

? ? ? ? @Override

? ? ? ? public boolean onTouch(View v, MotionEvent event) {

? ? ? ? ? ? //手指按下的时候记录开始滚动的坐标

? ? ? ? ? ? if (firstTouch) {

? ? ? ? ? ? ? ? //第一次touch可能是ACTION_MOVE或ACTION_DOWN,所以使用这种方式判断

? ? ? ? ? ? ? ? firstTouch= false;

? ? ? ? ? ? ? ? startY= offsetY;

? ? ? ? ? ? ? ? startX= offsetX;

}

? ? ? ? ? ? if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {

? ? ? ? ? ? ? ? firstTouch= true;

}

? ? ? ? ? ? return false;

}

}

? ? private int getPageIndex() {

? ? ? ? int p= 0;

? ? ? ? if (mRecyclerView.getHeight() == 0 || mRecyclerView.getWidth() == 0) {

? ? ? ? ? ? return p;

}

? ? ? ? if (mOrientation== ORIENTATION.VERTICAL) {

? ? ? ? ? ? p= offsetY/ mRecyclerView.getHeight();

? ? ? ? } else {

? ? ? ? ? ? p= offsetX/ mRecyclerView.getWidth();

}

? ? ? ? return p;

}

? ? private int getStartPageIndex() {

? ? ? ? int p= 0;

? ? ? ? if (mRecyclerView.getHeight() == 0 || mRecyclerView.getWidth() == 0) {

? ? ? ? ? ? //没有宽高无法处理

? ? ? ? ? ? return p;

}

? ? ? ? if (mOrientation== ORIENTATION.VERTICAL) {

? ? ? ? ? ? p= startY/ mRecyclerView.getHeight();

? ? ? ? } else {

? ? ? ? ? ? p= startX/ mRecyclerView.getWidth();

}

? ? ? ? return p;

}

? ? onPageChangeListener mOnPageChangeListener;

? ? public void setOnPageChangeListener(onPageChangeListener listener) {

? ? ? ? mOnPageChangeListener= listener;

}

? ? public interface onPageChangeListener {

? ? ? ? void onPageChange(int index);

}

}

2.定义一个接口(用于我们自定义LayoutMAnager)

public interface PageDecorationLastJudge {

? ? boolean isLastRow(int position);

? ? boolean isLastColumn(int position);

? ? boolean isPageLast(int position);

}

3.自定义LayoutManager

public class HorizontalPageLayoutManager extends RecyclerView.LayoutManager implements PageDecorationLastJudge {

? ? @Override

? ? public RecyclerView.LayoutParams generateDefaultLayoutParams() {

? ? ? ? return null;

}

? ? int totalHeight= 0;

? ? int totalWidth= 0;

? ? int offsetY= 0;

? ? int offsetX= 0;

? ? public HorizontalPageLayoutManager(int rows, int columns) {

? ? ? ? this.rows= rows;

? ? ? ? this.columns= columns;

? ? ? ? this.onePageSize= rows * columns;

}

? ? @Override

? ? public boolean canScrollHorizontally() {

? ? ? ? return true;

}

? ? @Override

? ? public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, RecyclerView.State state) {

? ? ? ? detachAndScrapAttachedViews(recycler);

? ? ? ? int newX= offsetX+ dx;

? ? ? ? int result= dx;

? ? ? ? if (newX> totalWidth) {

? ? ? ? ? ? result= totalWidth- offsetX;

? ? ? ? } else if (newX< 0) {

? ? ? ? ? ? result= 0 - offsetX;

}

? ? ? ? offsetX+= result;

? ? ? ? offsetChildrenHorizontal(-result);

? ? ? ? recycleAndFillItems(recycler, state);

? ? ? ? return result;

}

? ? private SparseArray<Rect> allItemFrames= new SparseArray<>();

? ? private int getUsableWidth() {

? ? ? ? return getWidth() - getPaddingLeft() - getPaddingRight();

}

? ? private int getUsableHeight() {

? ? ? ? return getHeight() - getPaddingTop() - getPaddingBottom();

}

? ? int rows= 0;

? ? int columns= 0;

? ? int pageSize= 0;

? ? int itemWidth= 0;

? ? int itemHeight= 0;

? ? int onePageSize= 0;

? ? int itemWidthUsed;

? ? int itemHeightUsed;

? ? @Override

? ? public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {

? ? ? ? if (getItemCount() == 0) {

? ? ? ? ? ? removeAndRecycleAllViews(recycler);

? ? ? ? ? ? return;

}

? ? ? ? if (state.isPreLayout()) {

? ? ? ? ? ? return;

}

? ? ? ? //获取每个Item的平均宽高

? ? ? ? itemWidth= getUsableWidth() / columns;

? ? ? ? itemHeight= getUsableHeight() / rows;

? ? ? ? //计算宽高已经使用的量,主要用于后期测量

? ? ? ? itemWidthUsed= (columns- 1) * itemWidth;

? ? ? ? itemHeightUsed= (rows- 1) * itemHeight;

? ? ? ? //计算总的页数

//? ? ? ? pageSize = state.getItemCount() / onePageSize + (state.getItemCount() % onePageSize == 0 ? 0 : 1);

? ? ? ? computePageSize(state);

? ? ? ? Log.i("zzz", "itemCount=" + getItemCount() + " state itemCount=" + state.getItemCount() + " pageSize=" + pageSize);

? ? ? ? //计算可以横向滚动的最大值

? ? ? ? totalWidth= (pageSize- 1) * getWidth();

? ? ? ? //分离view

? ? ? ? detachAndScrapAttachedViews(recycler);

? ? ? ? int count= getItemCount();

? ? ? ? for (int p= 0; p< pageSize; p++) {

? ? ? ? ? ? for (int r= 0; r< rows; r++) {

? ? ? ? ? ? ? ? for (int c= 0; c< columns; c++) {

? ? ? ? ? ? ? ? ? ? int index= p* onePageSize+ r* columns+ c;

? ? ? ? ? ? ? ? ? ? if (index== count) {

? ? ? ? ? ? ? ? ? ? ? ? //跳出多重循环

? ? ? ? ? ? ? ? ? ? ? ? c= columns;

? ? ? ? ? ? ? ? ? ? ? ? r= rows;

? ? ? ? ? ? ? ? ? ? ? ? p= pageSize;

? ? ? ? ? ? ? ? ? ? ? ? break;

}

? ? ? ? ? ? ? ? ? ? View view= recycler.getViewForPosition(index);

? ? ? ? ? ? ? ? ? ? addView(view);

? ? ? ? ? ? ? ? ? ? //测量item

? ? ? ? ? ? ? ? ? ? measureChildWithMargins(view, itemWidthUsed, itemHeightUsed);

? ? ? ? ? ? ? ? ? ? int width= getDecoratedMeasuredWidth(view);

? ? ? ? ? ? ? ? ? ? int height= getDecoratedMeasuredHeight(view);

? ? ? ? ? ? ? ? ? ? //记录显示范围

? ? ? ? ? ? ? ? ? ? Rect rect= allItemFrames.get(index);

? ? ? ? ? ? ? ? ? ? if (rect== null) {

? ? ? ? ? ? ? ? ? ? ? ? rect= new Rect();

}

? ? ? ? ? ? ? ? ? ? int x= p* getUsableWidth() + c* itemWidth;

? ? ? ? ? ? ? ? ? ? int y= r* itemHeight;

? ? ? ? ? ? ? ? ? ? rect.set(x, y, width+ x, height+ y);

? ? ? ? ? ? ? ? ? ? allItemFrames.put(index, rect);

}

}

? ? ? ? ? ? //每一页循环以后就回收一页的View用于下一页的使用

? ? ? ? ? ? removeAndRecycleAllViews(recycler);

}

? ? ? ? recycleAndFillItems(recycler, state);

}

? ? private void computePageSize(RecyclerView.State state) {

? ? ? ? pageSize= state.getItemCount() / onePageSize+ (state.getItemCount() % onePageSize== 0 ? 0 : 1);

}

? ? @Override

? ? public void onDetachedFromWindow(RecyclerView view, RecyclerView.Recycler recycler) {

? ? ? ? super.onDetachedFromWindow(view, recycler);

? ? ? ? offsetX= 0;

? ? ? ? offsetY= 0;

}

? ? private void recycleAndFillItems(RecyclerView.Recycler recycler, RecyclerView.State state) {

? ? ? ? if (state.isPreLayout()) {

? ? ? ? ? ? return;

}

? ? ? ? Rect displayRect= new Rect(getPaddingLeft() + offsetX, getPaddingTop(), getWidth() - getPaddingLeft() - getPaddingRight() + offsetX, getHeight() - getPaddingTop() - getPaddingBottom());

? ? ? ? Rect childRect= new Rect();

? ? ? ? for (int i= 0; i< getChildCount(); i++) {

? ? ? ? ? ? View child= getChildAt(i);

? ? ? ? ? ? childRect.left= getDecoratedLeft(child);

? ? ? ? ? ? childRect.top= getDecoratedTop(child);

? ? ? ? ? ? childRect.right= getDecoratedRight(child);

? ? ? ? ? ? childRect.bottom= getDecoratedBottom(child);

? ? ? ? ? ? if (!Rect.intersects(displayRect, childRect)) {

? ? ? ? ? ? ? ? removeAndRecycleView(child, recycler);

}

}

? ? ? ? for (int i= 0; i< getItemCount(); i++) {

? ? ? ? ? ? if (Rect.intersects(displayRect, allItemFrames.get(i))) {

? ? ? ? ? ? ? ? View view= recycler.getViewForPosition(i);

? ? ? ? ? ? ? ? addView(view);

? ? ? ? ? ? ? ? measureChildWithMargins(view, itemWidthUsed, itemHeightUsed);

? ? ? ? ? ? ? ? Rect rect= allItemFrames.get(i);

? ? ? ? ? ? ? ? layoutDecorated(view, rect.left- offsetX, rect.top, rect.right- offsetX, rect.bottom);

}

}

}

? ? @Override

? ? public boolean isLastRow(int index) {

? ? ? ? if (index >= 0 && index < getItemCount()) {

? ? ? ? ? ? int indexOfPage= index % onePageSize;

? ? ? ? ? ? indexOfPage++;

? ? ? ? ? ? if (indexOfPage> (rows- 1) * columns&& indexOfPage<= onePageSize) {

? ? ? ? ? ? ? ? return true;

}

}

? ? ? ? return false;

}

? ? @Override

? ? public boolean isLastColumn(int position) {

? ? ? ? if (position >= 0 && position < getItemCount()) {

? ? ? ? ? ? position++;

? ? ? ? ? ? if (position % columns== 0) {

? ? ? ? ? ? ? ? return true;

}

}

? ? ? ? return false;

}

? ? @Override

? ? public boolean isPageLast(int position) {

? ? ? ? position++;

? ? ? ? return position % onePageSize== 0;

}

? ? @Override

? ? public int computeHorizontalScrollRange(RecyclerView.State state) {

? ? ? ? computePageSize(state);

? ? ? ? return pageSize* getWidth();

}

? ? @Override

? ? public int computeHorizontalScrollOffset(RecyclerView.State state) {

? ? ? ? return offsetX;

}

? ? @Override

? ? public int computeHorizontalScrollExtent(RecyclerView.State state) {

? ? ? ? return getWidth();

}

}

4.下面开始调用

4.1首先是布局??

//RecyclerView? 要定义高度

<androidx.recyclerview.widget.RecyclerView

? ? android:id="@+id/rv_menu"

? ? android:layout_marginLeft="@dimen/dp_12"

? ? android:layout_width="match_parent"

? ? android:layout_height="@dimen/dp_150"

? ? android:layout_marginTop="@dimen/dp_12" />

//指示器

<LinearLayout

? ? android:id="@+id/indicator_layout"

? ? android:layout_marginTop="@dimen/dp_8"

? ? android:layout_width="match_parent"

? ? android:layout_height="wrap_content"

? ? android:layout_marginHorizontal="5dp"

? ? android:layout_marginBottom="@dimen/dp_10"

? ? android:gravity="center_horizontal"

? ? android:orientation="horizontal" />

4.2然后造数据

mItemBeans= new ArrayList<>();

for (int i= 0; i< 28; i++) {

? ? if (i== 28) {

? ? ? ? MenuBean.ItemBean itemBean= new MenuBean.ItemBean();

? ? ? ? itemBean.setTitle("全部");

? ? ? ? mItemBeans.add(itemBean);

? ? } else {

? ? ? ? MenuBean.ItemBean itemBean= new MenuBean.ItemBean();

? ? ? ? itemBean.setTitle("菜单" + i);

? ? ? ? mItemBeans.add(itemBean);

}

}

4.3 调用

PagingScrollHelper scrollHelper= new PagingScrollHelper();//初始化横向管理器

HorizontalPageLayoutManager horizontalPageLayoutManager

= new HorizontalPageLayoutManager(2, 5);//这里两个参数是行列,这里实现的是三行四列

scrollHelper.setUpRecycleView(rvMenu);//将横向布局管理器和recycler view绑定到一起

scrollHelper.setOnPageChangeListener(this);//设置滑动监听

rvMenu.setLayoutManager(horizontalPageLayoutManager);//设置为横向

scrollHelper.updateLayoutManger();

scrollHelper.scrollToPosition(0);//默认滑动到第一页

rvMenu.setHorizontalScrollBarEnabled(true);

HorizontalScrollItemAdapter itemAdapter= new HorizontalScrollItemAdapter(context, R.layout.item_menu);

itemAdapter.setNewData(mItemBeans);

rvMenu.setAdapter(itemAdapter);

if (mItemBeans.size() % 10 > 0) {

? ? //一共的页数等于 总数/每页数量,并取整。

? ? page= (int) Math.ceil(mItemBeans.size() * 1.0 / 10);

} else if (mItemBeans.size() % 10 == 0){

? ? page= mItemBeans.size() % 10;

}

setIndicatorLayout(page);

4.4 指示器

/*

page 是页数 需要自己算 比如我是三行四列 就是每页12个item

用我们数据的size%12 如不不等于0 就是 (size/12)+1

如果等于0 就是 size/12

*/

private void setIndicatorLayout(int page) {

? ? //生成相应数量的导航小圆点

? ? LinearLayout.LayoutParams params= new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,

? ? ? ? ? ? LinearLayout.LayoutParams.WRAP_CONTENT);

? ? //设置小圆点左右之间的间隔

? ? params.setMargins(10, 0, 10, 0);

? ? //得到页面个数

? ? dotViews= new ImageView[page];//此处传进来的6是页面数,通常要遍历得到页面的数量来创建图片集合

? ? for (int i= 0; i< page; i++) {//这里也是循环页面数量

? ? ? ? ImageView imageView= new ImageView(context);

? ? ? ? imageView.setLayoutParams(params);

? ? ? ? imageView.setImageResource(R.drawable.shape_circle);//设置默认没有选中时所有图片为灰色

? ? ? ? if (i== 0) {

? ? ? ? ? ? //默认启动时,选中第一个小圆点

? ? ? ? ? ? imageView.setSelected(true);

? ? ? ? } else {

? ? ? ? ? ? imageView.setSelected(false);

}

? ? ? ? //得到每个小圆点的引用,用于滑动页面时,更改它们的状态。

? ? ? ? dotViews[i] = imageView;

? ? ? ? dotViews[0].setImageResource(R.drawable.shape_sel_circle);//设置第一个页面选择为嗨丝

//添加到布局里面显示

? ? ? ? indicatorLayout.addView(imageView);

}

}

4.5指示器样式

//未选中状态

<shape xmlns:android="http://schemas.android.com/apk/res/android"

? ? android:shape="oval">

? ? <solid android:color="#e5e5e5" />

? ? <size

? ? ? ? android:width="@dimen/dp_3"

? ? ? ? android:height="@dimen/dp_3" />

</shape>

//选中状态

<shape xmlns:android="http://schemas.android.com/apk/res/android"

? ? android:shape="rectangle">

? ? <solid android:color="#EA3721" />

? ? <corners android:radius="@dimen/dp_3"/>

? ? <size

? ? ? ? android:width="@dimen/dp_10"

? ? ? ? android:height="@dimen/dp_3" />

</shape>

5.表演结束? 谢谢大家

?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,128评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,316评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,737评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,283评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,384评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,458评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,467评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,251评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,688评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,980评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,155评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,818评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,492评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,142评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,382评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,020评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,044评论 2 352

推荐阅读更多精彩内容