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()); }设置一个水平布局
LinearLayoutManager mLayoutManager =new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);mRvAgeList.setLayoutManager(mLayoutManager);添加Adapter, 设置起始和结束位置.
mAgeAdapter = new PersonAgeAdapter(START_NUM, END_NUM);mRvAgeList.setAdapter(mAgeAdapter);2. 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不能移动半个单元, 每行数量是单数时, 则必会指向中心.
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());注意在滚动停止时, 更新高亮比较好, 否则重绘速度较慢, 会影响滚动效果.
总结
好了,以上就是这篇文章的全部内容了,我们可以根据这些定制各式各样的滚动条了!希望这篇文章对大家能有所帮助。