Android 는 ViewPager 를 사용 하여 무한 슬라이딩 효 과 를 실현 합 니 다.

머리말
사실 원 리 를 자세히 생각해 보면 매우 간단 하 다.우리 가 마지막 페이지 까지 미 끄 러 지고 뒤로 미 끄 러 질 때 첫 페이지 로 찾 는 것 이 아 닙 니 다.우리 가 첫 페이지 로 미 끄 러 졌 을 때,다시 앞으로 미 끄 러 졌 을 때,마지막 페이지 로 포 지 셔 닝 합 니 다.
그러나 많은 친구 들 이 이 문 제 를 겪 었 다 고 믿 습 니 다.보기 의 과도 한 효과 가 자 연 스 럽 지 않 습 니 다.
편집장 도 바 이 두 와 구 글 을 통 해 많은 해결 방안 을 찾 았 고 많은 방법 을 실험 하여 상대 적 으로 좋 은 방법 을 정리 했다.그 다음 에 여러분 에 게 미끄럼 효과,디 테 일 실현 과 밟 은 구 덩이 를 공유 했다.
1.무한 슬라이딩 효과(좌우 무한 슬라이딩)
미끄럼 사진 2 장 미리 준비 해 두 세 요.

실행 효과 그림(좌우 무한 순환):
보다 직관 적 으로 보이 기 위해,작은 편 은 그림 2 장 만 사용 했다.

2.코드 구현
(1)Activity 의 Xml 레이아웃 파일(매우 간단 한 레이아웃)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent">

 <android.support.v4.view.ViewPager
  android:id="@+id/view_pager"
  android:layout_width="match_parent"
  android:layout_height="200dp"/>
</RelativeLayout>
(2)Activity

public class MainActivity extends AppCompatActivity {

 private ViewPager mViewPager;
 private ViewPagerAdapter mAdapter;
 private int[] images; //       

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  initView(); //      
  initData(); //      
 }

 /**
  *      
  */
 private void initView() {
  mViewPager = (ViewPager) findViewById(R.id.view_pager);
 }

 /**
  *      
  */
 private void initData() {
  images = new int[]{R.mipmap.image1, R.mipmap.image2};
  mAdapter = new ViewPagerAdapter(this, images);
  mViewPager.setAdapter(mAdapter);

  //  ViewPager      (Short.MAX_VALUE/2          1        )
  //   :1.     >1     2.      ,       
  if(images.length > 1) {
   mViewPager.setCurrentItem(((Short.MAX_VALUE / 2) / images.length) * images.length, false);
  }
 }
}
(3)ViewPagerAdapter

/**
 * @ClassName: ViewPagerAdapter
 * @Description: ViewPager   
 * @Author Wangnan
 * @Date 2016/9/1
 */
public class ViewPagerAdapter extends PagerAdapter{

 private Context mContext;
 private int[] mImages; //     ID  
 private List<ImageView> mImageViews; // ImageView  

 public ViewPagerAdapter(Context context, int[] images){
  mContext = context;
  mImages = images;
  mImageViews = new ArrayList<>();
  initImageViews(mImages);
 }

 /**
  *    ImageViews  
  * @param imageIds
  */
 private void initImageViews(int[] imageIds) {

  //           ImageViews  
  for(int i = 0 ; i < imageIds.length ; i++){
   ImageView mImageView = new ImageView(mContext);
   mImageView.setImageResource(imageIds[i]);
   mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
   mImageViews.add(mImageView);
  }

  // ImageViews         [2,3]      ,        
  if(mImageViews.size() > 1 && mImageViews.size() < 4){
   initImageViews(imageIds);
  }
 }

 @Override
 public int getCount() {
  return mImageViews.size() <=1 ? mImageViews.size() : Short.MAX_VALUE;
 }

 @Override
 public boolean isViewFromObject(View view, Object object) {
  return view == object;
 }

 @Override
 public Object instantiateItem(ViewGroup container, int position) {
  ImageView mImageView = mImageViews.get(position % mImageViews.size());
  container.addView(mImageView);
  return mImageView;
 }

 @Override
 public void destroyItem(ViewGroup container, int position, Object object) {
  container.removeView((View)object);
 }
}
구체 적 으로 설명 해 야 할 부분 은 코드 에 해당 하 는 주석 을 달 았 기 때문에 더 이상 설명 을 하지 않 지만 뒤에 있 는 작은 편집 자 는 만 나 는 두 개의 구덩이 점 을 설명 할 것 이다.
3.디 테 일 밟 기
소 편 실현 방식 을 보기 전에 인터넷 에서 도 비슷 한 실현 을 많이 찾 았 다 고 믿는다.편집장 이 다음 에 말 하고 자 하 는 것 은 바로 이런 비슷 한 실현 에 대해 구 덩이 를 밟 는 것 이다.
1.이상 발생:java.lang.IllegalStateException:지 정 된 자녀 는 이미 부모 가 있 습 니 다.자녀의 부모 에 removeView()를 먼저 호출 해 야 합 니 다.
원인:이미지 자원 이 4 개 보다 적 고 생 성 된 이미지 뷰 도 4 개 보다 적다.
알다 시 피ViewPager는 보통 2~3 페이지 를 유지 하 는데,3 개ImageView만 있 으 면 이 럴 가능성 이 높다.3 개Page페이지 를 생 성 한 뒤 4 번 째 페이지 를 생 성 하려 고 할 때 제거 해 야 할 맨 앞 페이지 는 아직 제거 되 지 않 았 다.시스템 이 이상 을 알 리 고 이런 힌트 를 줄 것 입 니 다.You must call removeView()on the child's parent first(맨 앞 페이지 의 하위View를 맨 앞 페이지 에서 제거 한 다음 이 하위View를 4 페이지 에 추가 하 라 는 뜻 입 니 다.
해결 방법:그림 이 한 장 밖 에 없 을 때 미 끄 러 질 수 없고 처리 하지 않 습 니 다.그림 이 2~3 장 있 을 때 재 귀 는 4 개ImageView이상(아래 는 이 문 제 를 해결 하 는 코드)으로 증가한다.

 /**
  *    ImageViews  
  * @param imageIds
  */
 private void initImageViews(int[] imageIds) {

  ......

  // ImageViews         [2,3]      ,        
  if(mImageViews.size() > 1 && mImageViews.size() < 4){
   initImageViews(imageIds);
  }
 }
2.미끄럼 효과 에 혼란 이 발생 합 니 다(뒤에 혼란 효과 그림 이 첨부 됨)
원인:ViewPager소스 코드 자체 에 문제 가 존재 합 니 다.-데이터 범위 의 경계 넘 기 문제.
작은 편집ViewPager페이지 수 를 가 져 오 는 방법 은 다음 과 같 습 니 다.

 @Override
 public int getCount() {
  return mImageViews.size() <=1 ? mImageViews.size() : Short.MAX_VALUE;
 }
1 보다 작 을 때 페이지 가 미 끄 러 지지 않 아 페이지 수 를 늘 릴 필요 가 없습니다.
1 보다 크 면 취Short수치 범위 의 최대 치 32767(우 리 는 3W 이상 의 페이지 가 있 지만 동시에 존재 하지 않 습 니 다.ViewPager 는 최대 3 개의 페이지 를 유지 하기 때 문 입 니 다)
편집장 은 여기 서 Short 를 사 용 했 지만 처음에 인터넷 에서 찾 은 비슷 한 실현 은 모두 사용 되 었 다Integer(Integer.MAXVALUE=2147483647,즉 우리 뷰 페 어 에는 약 21 억 페이지 가 있 을 것 이다.Integer를 사용 하면 비교적 세심 한 친구 들 은 미끄럼 이 자주 혼 란 스 러 워 지 는 것 을 발견 할 수 있다.
페이지 리 턴 버그

우리 가 손 을 놓 을 때 페이지 에 역방향 리 턴(1~2 페이지)이 나타 나 는데 이것 은 우리 가 기대 하 는 미끄럼 효과 와 일치 하지 않 는 다.
이것 은 그 중의 Bug 이 고 설명 하기 어 려 운 미끄럼 Bug 도 있 습 니 다.작은 편 은'미끄럼 혼란'이라는 명사 로 설명 하 였 습 니 다.
해결 방법:페이지 수 축소(소 편 사용Short대체Integer페이지 감소).
구체 적 으로 bug 의 임계값 이 없 으 면 관심 있 는 파트너 가 실험 할 수 있 습 니 다.작은 편집자 의 테스트 결 과 는 다음 과 같 습 니 다.
800 만 이내:기본적으로 미끄럼 없 음 버그;
1000 만 정도:현재 페이지 의 위치 가 정확 하지 않 은 버그 가 나타 나 기 시 작 했 지만 역방향 버그 가 나타 나 지 않 았 습 니 다.
총결산
이상 은 안 드 로 이 드 가 ViewPager 를 사용 하여 무한 슬라이딩 효 과 를 실현 하 는 것 에 관 한 모든 내용 입 니 다.이 글 이 여러분 이 개발 할 때 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 면 댓 글로 소통 할 수 있 습 니 다.

좋은 웹페이지 즐겨찾기