Android RecyclerView 实现横向滚动效果
2017-10-09 20:04
721 查看
滚动控件的实现方式有很多, 使用RecyclerView也比较简单. 做了一个简单的年龄滚动控件, 让我们来看看RecyclerView的使用方式, 主要有以下几点:
(1) 对齐控件中心位置.
(2) 计算滚动距离.
(3) 高亮中心视图.
(4) 实时显示中心数据.
(5) 停止时自动对齐.
(6) 滚动时, 设置按钮状态开关
类似源码下载: 点击下载源码 点击下载源码2
1.RecyclerView部分逻辑:
1).设置一个水平布局:
2).添加Adapter, 设置起始和结束位置:
2.Adapter:
Adapter定制一些功能,
如标示指向中心位置, 数据联动显示, 高亮Item等
每个单元格宽度是屏幕宽度的
填充屏幕, 则起始指向中心
单数Item数量, 则中心的指示器必指向中心Item的中心,根据选中状态, 更新Item样式.
设置高亮, 把中心位置高亮, 两边恢复, 通知Adapter重绘ViewHolder
notifyItemChanged()会重绘所选择的页面,获取宽度, 把一行显示Item数量设置为单数, 则中心指向一个Item
注意RecyclerView不能移动半个单元, 每行数量是单数时, 则必会指向中心
3.滚动逻辑
在滚动时,
实时更新页面显示; 在停止时, 更新高亮和存储数据; 滚动结束时, 激活按钮
判断滚动的距离单位, 偏移总距离/单个Item宽度
中间位置, 还要加上半行Item数量
判断滚动是否停止
在滚动停止时, 自动对齐
调用需要高亮显示的Item
注意在滚动停止时, 更新高亮比较好, 否则重绘速度较慢, 会影响滚动效果
OK
点击下载源码
(1) 对齐控件中心位置.
(2) 计算滚动距离.
(3) 高亮中心视图.
(4) 实时显示中心数据.
(5) 停止时自动对齐.
(6) 滚动时, 设置按钮状态开关
类似源码下载: 点击下载源码 点击下载源码2
1.RecyclerView部分逻辑:
/** * 初始化年龄滑动条 */ private void initAgeList() { LinearLayoutManager mLayoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false); mRvAgeList.setLayoutManager(mLayoutManager); mAgeAdapter = new PersonAgeAdapter(START_NUM, END_NUM); mRvAgeList.setAdapter(mAgeAdapter); mRvAgeList.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); mBDownStep.setEnabled(false); // 效果在暂停时显示, 否则会导致重绘异常 if (newState == RecyclerView.SCROLL_STATE_IDLE) { mAgeAdapter.highlightItem(getMiddlePosition()); mRvAgeList.scrollToPosition(getScrollPosition()); mLastValue = getMiddlePosition(); UserInfoManager.setAge(getMiddlePosition() + START_NUM); mBDownStep.setEnabled(true); // 滑动时不可用, 停止时才可以 } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { // 值是实时增加 mTvAgeValue.setText(String.valueOf(getMiddlePosition() + START_NUM)); } }); mAgeAdapter.highlightItem(getMiddlePosition()); }
1).设置一个水平布局:
LinearLayoutManager mLayoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false); mRvAgeList.setLayoutManager(mLayoutManager);
2).添加Adapter, 设置起始和结束位置:
mAgeAdapter = new PersonAgeAdapter(START_NUM, END_NUM); mRvAgeList.setAdapter(mAgeAdapter);
2.Adapter:
Adapter定制一些功能,
如标示指向中心位置, 数据联动显示, 高亮Item等
/** * 年龄的适配器 * <p> * Created by wangchenlong on 15/11/12. */ public class PersonAgeAdapter extends RecyclerView.Adapter<PersonAgeAdapter.AgeItemViewHolder> { public static final int ITEM_NUM = 7; // 每行拥有的Item数, 必须是奇数 private int mFrom; // 起始 private int mTo; // 终止 private int mHighlight = -1; // 高亮 public PersonAgeAdapter(int from, int to) { mFrom = from; mTo = to; } @Override public AgeItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View item = LayoutInflater.from(parent.getContext()). inflate(R.layout.view_age_item, parent, false); // 设置Item的宽度 ViewGroup.LayoutParams lp = item.getLayoutParams(); lp.width = getItemStdWidth(); return new AgeItemViewHolder(item); } @Override public void onBindViewHolder(AgeItemViewHolder holder, int position) { holder.getTextView().setText(String.valueOf(mFrom + position)); // 高亮显示 if (isSelected(position)) { holder.getTextView().setTextSize(30); holder.getTextView().setTextColor(ChunyuApp.getAppContext().getResources().getColor(R.color.black)); } else { holder.getTextView().setTextSize(20); holder.getTextView().setTextColor(ChunyuApp.getAppContext().getResources().getColor(R.color.gray_line)); } } // 高亮中心, 更新前后位置 public void highlightItem(int position) { mHighlight = position; int offset = ITEM_NUM / 2; for (int i = position - offset; i <= position + offset; ++i) notifyItemChanged(i); } // 判断是否是高亮 public boolean isSelected(int position) { return mHighlight == position; } @Override public int getItemCount() { return mTo - mFrom + 1; } // 获取标准宽度 public static int getItemStdWidth() { DisplayMetrics displayMetrics = ChunyuApp.getAppContext().getResources().getDisplayMetrics(); return displayMetrics.widthPixels / ITEM_NUM; } // ViewHolder public class AgeItemViewHolder extends RecyclerView.ViewHolder { private TextView mTextView; public AgeItemViewHolder(View itemView) { super(itemView); mTextView = (TextView) itemView.findViewById(R.id.item_age_value); mTextView.setTag(this); } public TextView getTextView() { return mTextView; } } }
每个单元格宽度是屏幕宽度的
奇数分之一,
填充屏幕, 则起始指向中心
@Override public AgeItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View item = LayoutInflater.from(parent.getContext()). inflate(R.layout.view_age_item, parent, false); // 设置Item的宽度 ViewGroup.LayoutParams lp = item.getLayoutParams(); lp.width = getItemStdWidth(); return new AgeItemViewHolder(item); }
单数Item数量, 则中心的指示器必指向中心Item的中心,根据选中状态, 更新Item样式.
@Override public void onBindViewHolder(AgeItemViewHolder holder, int position) { holder.getTextView().setText(String.valueOf(mFrom + position)); // 高亮显示 if (isSelected(position)) { holder.getTextView().setTextSize(30); holder.getTextView().setTextColor(ChunyuApp.getAppContext().getResources().getColor(R.color.black)); } else { holder.getTextView().setTextSize(20); holder.getTextView().setTextColor(ChunyuApp.getAppContext().getResources().getColor(R.color.gray_line)); } }
设置高亮, 把中心位置高亮, 两边恢复, 通知Adapter重绘ViewHolder
// 高亮中心, 更新前后位置 public void highlightItem(int position) { mHighlight = position; int offset = ITEM_NUM / 2; for (int i = position - offset; i <= position + offset; ++i) notifyItemChanged(i); } // 判断是否是高亮 public boolean isSelected(int position) { return mHighlight == position; }
notifyItemChanged()会重绘所选择的页面,获取宽度, 把一行显示Item数量设置为单数, 则中心指向一个Item
// 获取标准宽度 public static int getItemStdWidth() { DisplayMetrics displayMetrics = ChunyuApp.getAppContext().getResources().getDisplayMetrics(); return displayMetrics.widthPixels / ITEM_NUM; }
注意RecyclerView不能移动半个单元, 每行数量是单数时, 则必会指向中心
3.滚动逻辑
在滚动时,
实时更新页面显示; 在停止时, 更新高亮和存储数据; 滚动结束时, 激活按钮
mRvAgeList.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); mBDownStep.setEnabled(false); // 效果在暂停时显示, 否则会导致重绘异常 if (newState == RecyclerView.SCROLL_STATE_IDLE) { mAgeAdapter.highlightItem(getMiddlePosition()); mRvAgeList.scrollToPosition(getScrollPosition()); mLastValue = getMiddlePosition(); UserInfoManager.setAge(getMiddlePosition() + START_NUM); mBDownStep.setEnabled(true); // 滑动时不可用, 停止时才可以 } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { // 值是实时增加 mTvAgeValue.setText(String.valueOf(getMiddlePosition() + START_NUM)); } }); mAgeAdapter.highlightItem(getMiddlePosition()); } /** * 获取中间位置 * * @return 当前值 */ private int getMiddlePosition() { return getScrollPosition() + (PersonAgeAdapter.ITEM_NUM / 2); } /** * 获取滑动值, 滑动偏移 / 每个格子宽度 * * @return 当前值 */ private int getScrollPosition() { return (int) ((double) mRvAgeList.computeHorizontalScrollOffset() / (double) PersonAgeAdapter.getItemStdWidth()); }
判断滚动的距离单位, 偏移总距离/单个Item宽度
private int getScrollPosition() { return (int) ((double) mRvAgeList.computeHorizontalScrollOffset() / (double) PersonAgeAdapter.getItemStdWidth()); }
computeHorizontalScrollOffset()获取RecyclerView的偏移总位移
中间位置, 还要加上半行Item数量
private int getMiddlePosition() { return getScrollPosition() + (PersonAgeAdapter.ITEM_NUM / 2); }
判断滚动是否停止
if (newState == RecyclerView.SCROLL_STATE_IDLE)
在滚动停止时, 自动对齐
mRvAgeList.scrollToPosition(getScrollPosition());
调用需要高亮显示的Item
mAgeAdapter.highlightItem(getMiddlePosition());
注意在滚动停止时, 更新高亮比较好, 否则重绘速度较慢, 会影响滚动效果
OK
点击下载源码
相关文章推荐
- [置顶] RecyclerView 实现横向滚动效果
- RecyclerView 实现横向滚动效果
- RecyclerView 实现横向滚动效果
- Android 实现横向标题栏滚动效果(HorizontalScrollView + GridView + Viewpager + 自定义适配器)
- RecyclerView 实现横向滚动效果
- Android开发之实现水平滚动效果—RecyclerView
- 安卓的那些事儿-android之RecyclerView的使用,实现列表横向滚动
- Android RecyclerView实现横向滚动
- Android使用Recyclerview实现图片水平自动循环滚动效果
- Android使用Recyclerview实现图片水平自动循环滚动效果
- RecyclerView 实现横向滚动效果
- RecyclerView实现横向分页滚动效果,欢迎大家前来交流
- Android开发之TextView文字水平滚动效果实现
- Android 自定义RecyclerView 实现真正的Gallery效果
- Android之如何用TextView实现滚动字幕的效果【跑马灯】
- Android 自定义RecyclerView 实现真正的Gallery效果
- Android 自定义RecyclerView 实现真正的Gallery效果
- Android 自定义RecyclerView 实现真正的Gallery效果
- 一分钟实现 Android textview 跑马灯文字滚动效果
- Android 自定义RecyclerView 实现真正的Gallery效果