Android 에서 ViewPager 는 미끄럼 지시 줄 과 Fragment 와 의 협 조 를 실현 합 니 다.

16695 단어 AndroidViewPager
자체 적 으로 미끄럼 지시 조 를 실현 하 다.
선행 효과 도:
2016323115400211.png (300×500) 2016323115431597.png (300×500)
1.XML 레이아웃
레이아웃 코드 는 다음 과 같 습 니 다:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
 xmlns:tools="http://schemas.android.com/tools" 
 android:layout_width="match_parent" 
 android:layout_height="match_parent" 
 android:orientation="vertical" 
 tools:context="com.example.testviewpage_2.MainActivity" > 
  
  <ImageView 
  android:id="@+id/cursor" 
  android:layout_width="fill_parent" 
  android:layout_height="wrap_content" 
  android:scaleType="matrix" 
  android:src="@drawable/a" /> 
 
 <android.support.v4.view.ViewPager 
  android:id="@+id/viewpager" 
  android:layout_width="wrap_content" 
  android:layout_height="wrap_content" 
  android:layout_gravity="center"/> 
 
</LinearLayout> 
선형 수직 레이아웃 을 사용 하여 미끄럼 페이지 위 에 작은 수평 바 를 추가 합 니 다.
2.JAVA 코드
먼저 모든 코드 를 제시 한 후에 점차적으로 설명 하 다.

public class MainActivity extends Activity { 
 
 private View view1, view2, view3; 
 private List<View> viewList;// view   
 private ViewPager viewPager; //    viewPager 
 
 private ImageView cursor; 
 private int bmpw = 0; //      
 private int offset = 0;// //         
 private int currIndex = 0;//        
 
 @Override 
 protected void onCreate(Bundle savedInstanceState) { 
  super.onCreate(savedInstanceState); 
  setContentView(R.layout.activity_main); 
 
  viewPager = (ViewPager) findViewById(R.id.viewpager); 
  LayoutInflater inflater = getLayoutInflater(); 
  view1 = inflater.inflate(R.layout.layout1, null); 
  view2 = inflater.inflate(R.layout.layout2, null); 
  view3 = inflater.inflate(R.layout.layout3, null); 
 
  viewList = new ArrayList<View>();//        View      
  viewList.add(view1); 
  viewList.add(view2); 
  viewList.add(view3); 
 
  //         
  initCursorPos(); 
   
  viewPager.setAdapter(new MyPagerAdapter(viewList)); 
  viewPager.setOnPageChangeListener(new MyPageChangeListener()); 
 
 } 
  
 //         
 public void initCursorPos() { 
  //       
  cursor = (ImageView) findViewById(R.id.cursor); 
  bmpw = BitmapFactory.decodeResource(getResources(), R.drawable.a) 
    .getWidth();//        
 
  DisplayMetrics dm = new DisplayMetrics(); 
  getWindowManager().getDefaultDisplay().getMetrics(dm); 
  int screenW = dm.widthPixels;//         
  offset = (screenW / viewList.size() - bmpw) / 2;//       
 
  Matrix matrix = new Matrix(); 
  matrix.postTranslate(offset, 0); 
  cursor.setImageMatrix(matrix);//          
 } 
  
 
 //        
 public class MyPageChangeListener implements OnPageChangeListener { 
 
  int one = offset * 2 + bmpw;//   1 ->   2     
  int two = one * 2;//   1 ->   3     
 
  @Override 
  public void onPageSelected(int arg0) { 
   Animation animation = null; 
   switch (arg0) { 
   case 0: 
    if (currIndex == 1) { 
     animation = new TranslateAnimation(one, 0, 0, 0); 
    } else if (currIndex == 2) { 
     animation = new TranslateAnimation(two, 0, 0, 0); 
    } 
    break; 
   case 1: 
    if (currIndex == 0) { 
     animation = new TranslateAnimation(offset, one, 0, 0); 
    } else if (currIndex == 2) { 
     animation = new TranslateAnimation(two, one, 0, 0); 
    } 
    break; 
   case 2: 
    if (currIndex == 0) { 
     animation = new TranslateAnimation(offset, two, 0, 0); 
    } else if (currIndex == 1) { 
     animation = new TranslateAnimation(one, two, 0, 0); 
    } 
    break; 
   } 
   currIndex = arg0; 
   animation.setFillAfter(true);// True:           
   animation.setDuration(300); 
   cursor.startAnimation(animation); 
  } 
 
  @Override 
  public void onPageScrolled(int arg0, float arg1, int arg2) { 
  } 
 
  @Override 
  public void onPageScrollStateChanged(int arg0) { 
  } 
 } 
 
 /** 
  * ViewPager    
  */ 
 public class MyPagerAdapter extends PagerAdapter { 
  public List<View> mListViews; 
 
  public MyPagerAdapter(List<View> mListViews) { 
   this.mListViews = mListViews; 
  } 
 
  @Override 
  public boolean isViewFromObject(View arg0, Object arg1) { 
   // TODO Auto-generated method stub 
   return arg0 == arg1; 
  } 
 
  @Override 
  public int getCount() { 
   // TODO Auto-generated method stub 
   return mListViews.size(); 
  } 
 
  @Override 
  public void destroyItem(ViewGroup container, int position, Object object) { 
   // TODO Auto-generated method stub 
   container.removeView(mListViews.get(position)); 
  } 
 
  @Override 
  public Object instantiateItem(ViewGroup container, int position) { 
   // TODO Auto-generated method stub 
   container.addView(mListViews.get(position)); 
 
   return mListViews.get(position); 
  } 
 } 
 
} 
쉬 운 것 부터 어 려 운 것 까지 한 걸음 한 걸음 말 하 다.
1,MyPagerAdapter 클래스
일반적으로 우 리 는 어댑터 의 실현 에 대해 항상 new PageAdapter 의 인 스 턴 스 를 사용 합 니 다.우 리 는 여기에 약간의 변경 을 해서 그것 을 한 종류 로 합 쳤 는데 내용 은 변 하지 않 았 다.단지 구조 함수 가 하나 더 생 겼 을 뿐이다.그래서 이런 유형의 구체 적 인 코드 에 대해 저 는 더 이상 자세히 말 하지 않 겠 습 니 다.만약 에 그 중의 복사 함수 에 대해 왜 이렇게 이해 하지 못 하 는 학생 을 써 야 하 는 지 보 세 요.
2,initCursorPos()---표시 기 위치 초기 화
커서 가 초기 화 될 때 화면 너비 에 따라 커서 위 치 를 표시 해 야 합 니 다.먼저 이 부분의 코드 를 보십시오.

//         
public void initCursorPos() { 
 //       
 cursor = (ImageView) findViewById(R.id.cursor); 
 bmpw = BitmapFactory.decodeResource(getResources(), R.drawable.a) 
   .getWidth();//        
 
 DisplayMetrics dm = new DisplayMetrics(); 
 getWindowManager().getDefaultDisplay().getMetrics(dm); 
 int screenW = dm.widthPixels;//         
 offset = (screenW / viewList.size() - bmpw) / 2;//       
 
 Matrix matrix = new Matrix(); 
 matrix.postTranslate(offset, 0); 
 cursor.setImageMatrix(matrix);//          
} 

일부 학생 들 이 모 르 는 위 치 는 위 치 를 초기 화 하 는 오프셋 이 왜 이렇게 계산 되 는 지 에 있 을 것 입 니 다.아래 에 제 가 그림 을 그 렸 는데 보면 알 것 입 니 다.
2016323115509630.png (960×540)
마지막 으로 오프셋 방법 에 대해 사용 할 수 있 는 것 이 많 습 니 다.여 기 는 인터넷 의 코드 를 모방 하여 matrix 를 사 용 했 습 니 다.물론 여러분 은 다른 오프셋 방법 을 사용 할 수 있 습 니 다.마찬가지 입 니 다.
3,MyPageChangeListener()---페이지 변경 모니터
코드 는 다음 과 같 습 니 다:

public class MyPageChangeListener implements OnPageChangeListener { 
 
 int one = offset * 2 + bmpw;//   1 ->   2     
 int two = one * 2;//   1 ->   3     
 
 @Override 
 public void onPageSelected(int arg0) { 
  Animation animation = null; 
  switch (arg0) { 
  case 0: 
   if (currIndex == 1) { 
    animation = new TranslateAnimation(one, 0, 0, 0); 
   } else if (currIndex == 2) { 
    animation = new TranslateAnimation(two, 0, 0, 0); 
   } 
   break; 
  case 1: 
   if (currIndex == 0) { 
    animation = new TranslateAnimation(offset, one, 0, 0); 
   } else if (currIndex == 2) { 
    animation = new TranslateAnimation(two, one, 0, 0); 
   } 
   break; 
  case 2: 
   if (currIndex == 0) { 
    animation = new TranslateAnimation(offset, two, 0, 0); 
   } else if (currIndex == 1) { 
    animation = new TranslateAnimation(one, two, 0, 0); 
   } 
   break; 
  } 
  currIndex = arg0; 
  animation.setFillAfter(true);// True:           
  animation.setDuration(300); 
  cursor.startAnimation(animation); 
 } 
원 리 는 이 렇 습 니 다.미 끄 러 진 페이지 에 따라 커서 를 미 끄 러 뜨 려 지정 한 위 치 를 찾 습 니 다.
여기 서 어 려 운 점 은 수학...
나 는 첫 번 째 페이지 에서 두 번 째 페이지 까지 의 거리 가 왜'커서 너비+offset*2'인지 설명 하 는 그림 을 그 렸 다.다른 거 리 는 비슷 하 다.
2016323115543616.png (960×540)
이 편 은 여기까지 이 고,게다가 이 난이 도 는 그리 크 지 않 아서,말 하 는 것 이 그리 세밀 하지 않 을 것 이다.
원본 코드 에서 Tab 상호작용 이 있 는 Demo 를 보 여 주 었 습 니 다.그림 은 다음 과 같 습 니 다.
2016323115611176.png (300×533) 2016323115625900.png (300×533)
Fragment 를 사용 하여 ViewPager 미끄럼 실현
Fragment 를 사용 하여 ViewPager 미끄럼 을 실현 하 는 것 은 Android 공식 에서 비교적 추천 하 는 방법 입 니 다.먼저 효과 도 를 살 펴 보 겠 습 니 다.
첫 페이지 에 Btn 추가
2016323115641975.png (300×533)
첫 페이지 는 두 번 째 페이지 로 미 끄 러 집 니 다.
2016323115656400.png (300×533)
두 번 째 페이지 는 세 번 째 페이지 로 미 끄 러 집 니 다.
2016323115713962.png (300×533)
1.어댑터 실현―Fragment PagerAdapter
먼저 전체 코드 를 보고 자세히 말 하 세 요.

public class FragAdapter extends FragmentPagerAdapter { 
 
 private List<Fragment> mFragments; 
  
 public FragAdapter(FragmentManager fm,List<Fragment> fragments) { 
  super(fm); 
  // TODO Auto-generated constructor stub 
  mFragments=fragments; 
 } 
 
 @Override 
 public Fragment getItem(int arg0) { 
  // TODO Auto-generated method stub 
  return mFragments.get(arg0); 
 } 
 
 @Override 
 public int getCount() { 
  // TODO Auto-generated method stub 
  return mFragments.size(); 
 } 
 
} 
여기 에는 세 개의 함수 가 있 습 니 다.첫 번 째 부분의 공식 문서 에 따 르 면 Fragment PagerAdapter 의 파생 류 에 대해 서 는 getItem(int)과 getCount()만 다시 쓰 면 됩 니 다.
구조 함수 에 대해 Fragment 의 List 대상 을 신청 하여 미끄럼 에 사용 할 Fragment 대상 을 저장 하고 창조 함수 에서 초기 화 합 니 다.

public FragAdapter(FragmentManager fm,List<Fragment> fragments) { 
 super(fm); 
 // TODO Auto-generated constructor stub 
 mFragments=fragments; 
} 
그리고 getItem(int arg 0)에서 전 달 된 매개 변수 arg 0 에 따라 현재 표시 할 fragment 를 되 돌려 줍 니 다.다음은 getItem 의 공식 설명 입 니 다.난이도 가 크 지 않 고 자세히 설명 하지 않 습 니 다.
public abstract Fragment getItem (int position)
Return the Fragment associated with a specified position.
마지막 으로 getCount()는 미끄럼 에 사용 할 fragment 의 총 수 를 되 돌려 줍 니 다.
구조 함수 에서 알 수 있 듯 이 우 리 는 Fragment 의 집합 을 구성 해 야 하기 때문에 다음 에 우 리 는 우리 가 필요 로 하 는 Fragment 류 를 먼저 만들어 야 한다.
2.세 개의 Fragment 류
첫 번 째 Fragment 클래스:
XML:(layout1.xml)

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
 android:layout_width="match_parent" 
 android:layout_height="match_parent" 
 android:background="#ffffff" 
 android:orientation="vertical" > 
  
 <Button android:id="@+id/fragment1_btn" 
  android:layout_width="wrap_content" 
  android:layout_height="wrap_content" 
  android:text="show toast" 
  /> 
</LinearLayout> 
그 중 에 Btn 을 하나 넣 었 어 요.
Java 코드:

public class Fragment1 extends Fragment { 
  
 @Override 
 public View onCreateView(LayoutInflater inflater, ViewGroup container, 
   Bundle savedInstanceState) { 
  // TODO Auto-generated method stub 
  View view= inflater.inflate(R.layout.layout1, container, false); 
   
  // View         
  Button btn = (Button)view.findViewById(R.id.fragment1_btn); 
  btn.setOnClickListener(new View.OnClickListener() { 
    
   @Override 
   public void onClick(View v) { 
    // TODO Auto-generated method stub 
    Toast.makeText(getActivity(), "      fragment BTN", Toast.LENGTH_SHORT).show(); 
   } 
  }); 
  return view; 
 } 
} 
onCreateView()에서 표시 할 View 를 되 돌려 줍 니 다.위의 코드 는 보기 의 컨트롤 을 어떻게 조작 하 는 지 간단하게 보 여 줍 니 다.난이도 가 크 지 않 고 자세히 설명 하지 않 습 니 다.두 번 째 Fragment 클래스:
XML 코드:(layout 2.xml)네 이 티 브 코드 로 변경 되 지 않 았 습 니 다.

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
 android:layout_width="match_parent" 
 android:layout_height="match_parent" 
 android:background="#ffff00" 
 android:orientation="vertical" > 
  
 
</LinearLayout> 
자바 코드:

public class Fragment2 extends Fragment { 
  
 @Override 
 public View onCreateView(LayoutInflater inflater, ViewGroup container, 
   Bundle savedInstanceState) { 
  // TODO Auto-generated method stub 
  View view=inflater.inflate(R.layout.layout2, container, false); 
  return view; 
 } 
 
} 
세 번 째 Fragment 클래스:
XML 코드:(layout3.xml)마찬가지 로 네 이 티 브 코드 는 변경 되 지 않 았 습 니 다.

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
 android:layout_width="match_parent" 
 android:layout_height="match_parent" 
 android:background="#ff00ff" 
 android:orientation="vertical" > 
  
 
</LinearLayout> 
자바 코드:

public class Fragment3 extends Fragment { 
  
 @Override 
 public View onCreateView(LayoutInflater inflater, ViewGroup container, 
   Bundle savedInstanceState) { 
  // TODO Auto-generated method stub 
  View view=inflater.inflate(R.layout.layout3, container, false); 
  return view; 
 } 
 
} 
3.주요 활동 실현
핵심 코드:

public class MainActivity extends FragmentActivity { 
 
 @Override 
 protected void onCreate(Bundle savedInstanceState) { 
  super.onCreate(savedInstanceState); 
  setContentView(R.layout.activity_main); 
 
  //      
  List<Fragment> fragments=new ArrayList<Fragment>(); 
  fragments.add(new Fragment1()); 
  fragments.add(new Fragment2()); 
  fragments.add(new Fragment3()); 
  FragAdapter adapter = new FragAdapter(getSupportFragmentManager(), fragments); 
   
  //      
  ViewPager vp = (ViewPager)findViewById(R.id.viewpager); 
  vp.setAdapter(adapter); 
 } 
 
} 
먼저 가장 주의해 야 할 점 이 하나 있다.Activity 는 Fragment Activity 에서 파생 된 것 이다.사실은 이것 은 Fragment 에 관 한 기초 지식 이다.Fragment Activity 만 fragment 페이지 를 삽입 할 수 있 고 일반 Activity 는 안 된다.
이 코드 는 주로 두 단계 로 나 뉘 는데 첫 번 째 단 계 는 구조 어댑터 이다.두 번 째 단계:어댑터 설정.
구조 어댑터 의 과정 을 먼저 봅 니 다.

//      
List<Fragment> fragments=new ArrayList<Fragment>(); 
fragments.add(new Fragment1()); 
fragments.add(new Fragment2()); 
fragments.add(new Fragment3()); 
FragAdapter adapter = new FragAdapter(getSupportFragmentManager(), fragments); 
fragment 목록 을 만 든 다음 위의 세 개의 Fragment 류 에 대응 하 는 인 스 턴 스 를 추가 하고 마지막 으로 FragAdapter 인 스 턴 스 를 생 성 합 니 다.
두 번 째 단 계 는 어댑터 를 설정 하 는 것 에 대해 서 는 할 말 이 없다.
4.발생 할 수 있 는 문제
문제:MainActivity 에서 이 문장 을 썼 을 때:fragments.add(new Fragment 1());Fragment 목록 에 Fragement 대상 인 스 턴 스 를 추가 하면'Fragment 1()을 fragment 로 변환 할 수 없습니다'라 는 메시지 가 표 시 됩 니 다.
해결 방법:가 져 온 가방 이 일치 하지 않 기 때 문 입 니 다.일반적인 문 제 는 Fragment 1 에서 가 져 온 것 은 android.app.Fragment 입 니 다.여기 서 가 져 온 종 류 는 android.support.v4.app.Fragment 입 니 다.가방 이 다 르 면 당연히 변환 할 수 없습니다.android.support.v4.app.Fragment 로 통일 적 으로 가 져 온 후에 정상 입 니 다.

좋은 웹페이지 즐겨찾기