フラグメントの例 - 下部のナビゲーション バー + ViewPager スライドによるページ切り替え
最初の 3 つのセクションでは、通常の下部ナビゲーション バーの効果をさまざまな方法で実装しました。このセクションでは、以下に基づいて 2 番目の例を使用します。 ViewPager を追加して、スライドでページを切り替える効果を実現します。私の友人のほとんどは、この ViewPager が何であるかを知っています。 知らなくても大丈夫ですので、簡単にこのコントロールを紹介しましょう。
1. ViewPager の簡単な紹介
1) それはどのようなコントロールですか?
答え: ページ切り替えコンポーネント。複数のビューを入力でき、画面をタッチして左右にスライドできます。 異なるビュー間の切り替えは、前に学習した ListView と同じで、表示するビューを組み合わせるアダプターが必要です。 ViewPager はバインドされており、ViewPager には独自の固有のアダプター - ページャーアダプターがあります。さらに、Google 公式の推奨事項は、Fragment を使用して ViewPager を埋めることです。これにより、各ページの生成と管理がより便利になります。 もちろん、各ページのライフサイクルには、FragmentPageAdapter と FragmentStatePagerAdapter という 2 つの異なるアダプターが用意されています。 このセクションで使用するのは前者の FragmentPageAdapter です。 もう 1 つ言及すべきことは、ViewPager のキャッシュ メカニズムです。 ViewPager は、現在のページ、前のページ、および次のページをキャッシュします。たとえば、1、2、3、4 という 4 つのページがあります。 最初のページの場合: キャッシュ 1、2
——> 2 ページの場合: キャッシュ 1、2、3
——> 3 ページの場合: キャッシュ 2、3、4 ——>4ページ目のキャッシュ3、4にはこんな感じです!
2) PagerAdapter を使用して関連メソッドを書き換えます:
- getCount( ): ビューページャーにあるビューの数を取得します
- destroyItem( ): 指定された位置でページを削除します。このビューをコンテナから削除するのはアダプタの責任です。これは確実にするためです ビューは、finishUpdate(viewGroup) が返されたときに削除できます。
- instantiateItem():① ViewGroup(コンテナ)に指定位置のビューを追加し、作成して表示します ②新しく追加されたページを表すオブジェクト(キー)を返します。通常はビュー自体を直接返すだけです。 もちろん、独自のキーをカスタマイズすることもできますが、キーと各ビューの間には 1 対 1 の対応が必要です
- isViewFromObject( ): キーが instantiateItem(ViewGroup, int) 関数によって返されたかどうかを判断しますページビューと同じです 同じビューを表す (つまり、それらが対応しているかどうか、および対応するものが同じビューを表す)。通常は直接書きます。 return view == object; 以上です。なぜこのようにするのかについては、少し複雑になります。 ViewPagerにはViewのステータス情報を格納するArrayListがあるようです!
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: 書き込みますFragment のレイアウトとコード:
PS: ViewPager のメカニズムを示すために、4 つの Fragment がここに特別に書かれています。プリント作成CreateView にログインしてください!
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: FragmentDemo4.zip をダウンロード
このセクションの概要:
以上が、単純なスライドを実現するための下部ナビゲーション バー + ViewPager の実装プロセスです。フラグメントの切り替え! 以上です、ありがとうございます~