Android 에서 ViewPager 는 미끄럼 지시 줄 과 Fragment 와 의 협 조 를 실현 합 니 다.
선행 효과 도:
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);//
}
일부 학생 들 이 모 르 는 위 치 는 위 치 를 초기 화 하 는 오프셋 이 왜 이렇게 계산 되 는 지 에 있 을 것 입 니 다.아래 에 제 가 그림 을 그 렸 는데 보면 알 것 입 니 다.마지막 으로 오프셋 방법 에 대해 사용 할 수 있 는 것 이 많 습 니 다.여 기 는 인터넷 의 코드 를 모방 하여 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'인지 설명 하 는 그림 을 그 렸 다.다른 거 리 는 비슷 하 다.
이 편 은 여기까지 이 고,게다가 이 난이 도 는 그리 크 지 않 아서,말 하 는 것 이 그리 세밀 하지 않 을 것 이다.
원본 코드 에서 Tab 상호작용 이 있 는 Demo 를 보 여 주 었 습 니 다.그림 은 다음 과 같 습 니 다.
Fragment 를 사용 하여 ViewPager 미끄럼 실현
Fragment 를 사용 하여 ViewPager 미끄럼 을 실현 하 는 것 은 Android 공식 에서 비교적 추천 하 는 방법 입 니 다.먼저 효과 도 를 살 펴 보 겠 습 니 다.
첫 페이지 에 Btn 추가
첫 페이지 는 두 번 째 페이지 로 미 끄 러 집 니 다.
두 번 째 페이지 는 세 번 째 페이지 로 미 끄 러 집 니 다.
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 로 통일 적 으로 가 져 온 후에 정상 입 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.