조각 예 - 하단 탐색 모음 + 페이지 전환을 위한 ViewPager 슬라이딩
처음 세 섹션에서는 일반 하단 네비게이션 바의 효과를 다양한 방식으로 구현했으며, 이번 섹션에서는 다음을 기반으로 두 번째 예시를 사용하겠습니다. 페이지 전환 슬라이딩 효과를 얻으려면 ViewPager를 추가하세요! 내 친구들 대부분은 이 ViewPager가 무엇인지 알고 있습니다. 모르셔도 상관없습니다. 이 컨트롤에 대해 간단히 소개하겠습니다!
1. ViewPager에 대한 간략한 소개
1) 어떤 컨트롤인가요?
답변: 페이지 전환 구성요소로, 이를 여러 보기로 채울 수 있으며 화면을 터치하여 왼쪽과 오른쪽으로 슬라이드할 수 있습니다. 서로 다른 뷰 사이를 전환하는 것은 앞서 배운 ListView와 동일합니다. 표시할 뷰를 결합하려면 어댑터가 필요합니다. ViewPager는 바인딩되어 있으며 ViewPager에는 고유한 특정 Adapter-PagerAdapter가 있습니다! 게다가 구글은 공식적인 권장 사항은 각 페이지를 보다 편리하게 생성하고 관리할 수 있는 ViewPager를 채우기 위해 Fragment를 사용하는 것입니다. 각 페이지의 수명 주기는 물론 FragmentPageAdapter 및 FragmentStatePagerAdapter라는 두 가지 어댑터를 제공합니다! 이 섹션에서 사용하는 것은 전자인 FragmentPageAdapter입니다! 언급할 또 다른 사항은 ViewPager의 캐싱 메커니즘입니다. ViewPager는 현재 페이지, 이전 페이지 및 다음 페이지를 캐시합니다. 예를 들어 1, 2, 3, 4개의 페이지가 있습니다. 첫 번째 페이지에 있을 때: Cache 1, 2
——> 두 번째 페이지에 있을 때: Cache 1, 2, 3
——> 세 번째 페이지에 있을 때: Cache 2, 3, 4 ——> 4페이지 캐시 3, 4에 이렇게 나와있어요!
2) PagerAdapter를 사용하여 관련 메소드를 다시 작성합니다.
- getCount( ): 뷰페이지에 있는 뷰 수를 가져옵니다.
- destroyItem( ): 지정된 위치에서 페이지를 제거합니다. 컨테이너에서 이 뷰를 제거하는 것은 어댑터의 책임입니다. 이는 다음을 보장하기 위한 것입니다. FinishUpdate(viewGroup)가 반환되면 뷰가 제거될 수 있습니다.
- instantiateItem( ): ① 주어진 위치의 뷰를 ViewGroup(컨테이너)에 추가하고 생성하여 표시합니다. ②새로 추가된 페이지를 나타내는 객체(키)를 반환합니다. 일반적으로 뷰 자체를 직접 반환합니다. 물론 자신만의 키를 맞춤설정할 수도 있지만 키와 각 뷰 사이에는 일대일 대응이 있어야 합니다
- isViewFromObject( ): instantiateItem(ViewGroup, int) 함수에서 키를 반환하는지 여부를 확인합니다. 페이지 조회수와 동일합니다. 동일한 뷰를 나타냅니다(즉, 대응하는지, 대응하는 뷰가 동일한 뷰를 나타내는지 여부). 일반적으로 우리는 직접 작성합니다. return view == object; 그게 다입니다. 왜 이렇게 되었는지는 나중에 좀 더 자세히 알아볼 기회가 있을 것입니다. ViewPager에는 View 상태 정보를 저장하는 ArrayList가 있는 것 같습니다. View를 기반으로 해당 정보를 검색할 수 있습니다.
PS:모든 메소드를 다시 작성할 필요는 없습니다~
2. 및 프로젝트 디렉토리 구조:
먼저 달성하려는 효과를 살펴보겠습니다
프로젝트 구조를 살펴보겠습니다:
3. 코드 구현:
1단계: 관련 리소스 파일 준비:
PS: 하단 탐색 모음 방법 2를 구현합니다. 기본을 바탕으로 작성되었으니 리소스 파일을 복사해두시면 됩니다! 여기에는 여러번 올리지 않겠습니다~!
2단계: Activity_main.xml의 레이아웃 파일 작성:
PS: 이전 FrameLayout을 android.support.v4.view.ViewPager:
activity_mian.xml:
<RelativeLayout 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" tools:context=".MainActivity"> <RelativeLayout android:id="@+id/ly_top_bar" android:layout_width="match_parent" android:layout_height="48dp" android:background="../style/images/bg_topbar"> <TextView android:id="@+id/txt_topbar" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerInParent="true" android:gravity="center" android:text="提醒" android:textColor="@color/text_topbar" android:textSize="18sp" /> <View android:layout_width="match_parent" android:layout_height="2px" android:layout_alignParentBottom="true" android:background="../style/images/div_white" /> </RelativeLayout> <RadioGroup android:id="@+id/rg_tab_bar" android:layout_width="match_parent" android:layout_height="56dp" android:layout_alignParentBottom="true" android:background="../style/images/bg_white" android:orientation="horizontal"> <RadioButton android:id="@+id/rb_channel" style="@style/tab_menu_item" android:drawableTop="@drawable/tab_menu_channel" android:text="@string/tab_menu_alert" /> <RadioButton android:id="@+id/rb_message" style="@style/tab_menu_item" android:drawableTop="@drawable/tab_menu_message" android:text="@string/tab_menu_profile" /> <RadioButton android:id="@+id/rb_better" style="@style/tab_menu_item" android:drawableTop="@drawable/tab_menu_better" android:text="@string/tab_menu_pay" /> <RadioButton android:id="@+id/rb_setting" style="@style/tab_menu_item" android:drawableTop="@drawable/tab_menu_setting" android:text="@string/tab_menu_setting" /> </RadioGroup> <View android:id="@+id/div_tab_bar" android:layout_width="match_parent" android:layout_height="2px" android:layout_above="@id/rg_tab_bar" android:background="../style/images/div_white" /> <android.support.v4.view.ViewPager android:id="@+id/vpager" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@id/div_tab_bar" android:layout_below="@id/ly_top_bar" /> </RelativeLayout>
3단계: 쓰기 조각의 레이아웃 및 코드:
PS: ViewPager의 메커니즘을 보여주기 위해 여기에는 4개의 조각이 특별히 작성되었습니다! 인쇄 생성 로그인 onCreateView!
fg_content.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="../style/images/bg_white" android:orientation="vertical"> <TextView android:id="@+id/txt_content" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="呵呵" android:textColor="@color/text_yellow" android:textSize="20sp" /> </LinearLayout>
MyFragment1.java:
/** * Created by Jay on 2015/8/28 0028. */ public class MyFragment1 extends Fragment { public MyFragment1() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fg_content, container, false); TextView txt_content = (TextView) view.findViewById(R.id.txt_content); txt_content.setText("第一个Fragment"); Log.e("HEHE", "1日狗"); return view; } }
나머지 3개는 조롱박과 똑같습니다. 하나만 바꾸세요!
4단계: FragmentPagerAdapter 클래스 사용자 정의:
코드는 매우 간단합니다. FragmentManager를 전달하기만 하면 다른 모든 작업이 여기서 완료됩니다!
/** * Created by Jay on 2015/8/31 0031. */ public class MyFragmentPagerAdapter extends FragmentPagerAdapter { private final int PAGER_COUNT = 4; private MyFragment1 myFragment1 = null; private MyFragment2 myFragment2 = null; private MyFragment3 myFragment3 = null; private MyFragment4 myFragment4 = null; public MyFragmentPagerAdapter(FragmentManager fm) { super(fm); myFragment1 = new MyFragment1(); myFragment2 = new MyFragment2(); myFragment3 = new MyFragment3(); myFragment4 = new MyFragment4(); } @Override public int getCount() { return PAGER_COUNT; } @Override public Object instantiateItem(ViewGroup vg, int position) { return super.instantiateItem(vg, position); } @Override public void destroyItem(ViewGroup container, int position, Object object) { System.out.println("position Destory" + position); super.destroyItem(container, position, object); } @Override public Fragment getItem(int position) { Fragment fragment = null; switch (position) { case MainActivity.PAGE_ONE: fragment = myFragment1; break; case MainActivity.PAGE_TWO: fragment = myFragment2; break; case MainActivity.PAGE_THREE: fragment = myFragment3; break; case MainActivity.PAGE_FOUR: fragment = myFragment4; break; } return fragment; } }
5단계: MainActivity 작성:
논리는 매우 간단합니다. 직접 확인해 보세요~
MainActivity.java:
package com.jay.fragmentdemo4; import android.os.Bundle; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.widget.RadioButton; import android.widget.RadioGroup; import android.widget.TextView; /** * Created by Coder-pig on 2015/8/28 0028. */ public class MainActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener, ViewPager.OnPageChangeListener { //UI Objects private TextView txt_topbar; private RadioGroup rg_tab_bar; private RadioButton rb_channel; private RadioButton rb_message; private RadioButton rb_better; private RadioButton rb_setting; private ViewPager vpager; private MyFragmentPagerAdapter mAdapter; //几个代表页面的常量 public static final int PAGE_ONE = 0; public static final int PAGE_TWO = 1; public static final int PAGE_THREE = 2; public static final int PAGE_FOUR = 3; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager()); bindViews(); rb_channel.setChecked(true); } private void bindViews() { txt_topbar = (TextView) findViewById(R.id.txt_topbar); rg_tab_bar = (RadioGroup) findViewById(R.id.rg_tab_bar); rb_channel = (RadioButton) findViewById(R.id.rb_channel); rb_message = (RadioButton) findViewById(R.id.rb_message); rb_better = (RadioButton) findViewById(R.id.rb_better); rb_setting = (RadioButton) findViewById(R.id.rb_setting); rg_tab_bar.setOnCheckedChangeListener(this); vpager = (ViewPager) findViewById(R.id.vpager); vpager.setAdapter(mAdapter); vpager.setCurrentItem(0); vpager.addOnPageChangeListener(this); } @Override public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId) { case R.id.rb_channel: vpager.setCurrentItem(PAGE_ONE); break; case R.id.rb_message: vpager.setCurrentItem(PAGE_TWO); break; case R.id.rb_better: vpager.setCurrentItem(PAGE_THREE); break; case R.id.rb_setting: vpager.setCurrentItem(PAGE_FOUR); break; } } //重写ViewPager页面切换的处理方法 @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { } @Override public void onPageScrollStateChanged(int state) { //state的状态有三个,0表示什么都没做,1正在滑动,2滑动完毕 if (state == 2) { switch (vpager.getCurrentItem()) { case PAGE_ONE: rb_channel.setChecked(true); break; case PAGE_TWO: rb_message.setChecked(true); break; case PAGE_THREE: rb_better.setChecked(true); break; case PAGE_FOUR: rb_setting.setChecked(true); break; } } } }
PS: 헤헤, 위에 가이드 패키지 부분의 코드도 게시했습니다. , 잘못된 패키지를 가져오거나 설명할 수 없는 오류가 발생할까 두렵습니다! ViewPager는 v4 패키지에 속하므로 Fragment, FragmentManager 및 FragmentTransaction을 모두 사용해야 합니다. V4 패키지 아래에 있습니다! 또한 FragmentManager를 얻는 방법은 getFragmentManager()를 직접 사용하는 것이 아니라 getSupportFragmentManager() 오!
참고: ViewPager가 RadioButton 뒤에 배치되면 RadioButton의 클릭 이벤트가 유효하지 않습니다.
4. 코드 다운로드:
FragmentDemo4: Download FragmentDemo4.zip
이 섹션 요약:
자, 위는 간단한 슬라이딩을 구현하기 위한 하단 탐색 모음 + ViewPager의 구현 과정입니다. 조각 전환! 그게 다예요, 감사합니다~