Android 는 RecyclerView 를 사용 하여 수평 스크롤 컨트롤 을 실현 합 니 다.

머리말
안 드 로 이 드 스크롤 컨트롤 의 실현 방식 이 매우 많다 는 것 을 잘 알 고 있 을 것 입 니 다.RecyclerView 를 사용 하 는 것 도 간단 합 니 다.간단 한 나이 스크롤 컨트롤 을 만 들 었 습 니 다.RecyclerView 의 사용 방식 을 살 펴 보 겠 습 니 다.주로 다음 과 같은 몇 가지 가 있 습 니 다.
     (1)컨트롤 의 중심 위 치 를 정렬 합 니 다.
     (2)스크롤 거 리 를 계산한다.
     (3)하 이 라이트 중심 보기.
     (4)실시 간 으로 센터 데 이 터 를 표시 합 니 다.
     (5)정지 시 자동 정렬.
     (6)스크롤 할 때 단추 상태 스위치 를 설정 합 니 다.
효과.

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
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;
  }
 }
}
각 셀 폭 은 화면 너비 의 홀수 분 의 1 로 화면 을 채 우 면 시작 이 중심 을 가리킨다.

 @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 에 뷰 홀더 다시 그리 기 를 알 립 니 다.

 //     ,       
 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());
스크롤 이 멈 출 때 하 이 라 이 트 를 업데이트 하 는 것 이 좋 습 니 다.그렇지 않 으 면 다시 그 리 는 속도 가 느 려 서 스크롤 효과 에 영향 을 줄 수 있 습 니 다.
미끄럼 효과

총결산
자,이상 이 이 글 의 모든 내용 입 니 다.우 리 는 이러한 맞 춤 형 스크롤 바 를 만 들 수 있 습 니 다!이 글 이 모두 에 게 도움 이 되 기 를 바 랍 니 다.

좋은 웹페이지 즐겨찾기