Fragment Examples - Bottom Navigation Bar + ViewPager Slide to Switch Pages


In the first three sections, we used different methods to achieve the effect of the ordinary bottom navigation bar, and in this section we will use the second example based on Add ViewPager to achieve the effect of sliding switching pages! Most of my friends know what this ViewPager is. If It doesn’t matter if you don’t know. Let’s briefly introduce this control!


1. A brief introduction to ViewPager


1) What kind of control is it?

Answer: A page switching component, we can fill it with multiple Views, and then we can slide left and right by touching the screen Switching between different Views is the same as the ListView we learned earlier. We need an Adapter to combine the View to be displayed with Our ViewPager is bound, and ViewPager has its own specific Adapter-PagerAdapter! In addition, Google The official recommendation is that we use Fragment to fill ViewPager, which can more conveniently generate and manage each Page. The life cycle of each Page! Of course it provides us with two different Adapters, they are: FragmentPageAdapter and FragmentStatePagerAdapter! What we use in this section is the former: FragmentPageAdapter! Another thing to say is ViewPager’s caching mechanism: ViewPager will cache the current page, the previous page, and the next page. For example, there are four pages 1, 2, 3, and 4: When we are on the first page: Cache 1, 2
——> When we are on the second page: Cache 1, 2, 3
——> When we are on the third page: Cache 2, 3, 4 ——> It is in the fourth page cache 3, 4 like this!

2) To use PagerAdapter, rewrite the relevant methods:

  • getCount( ): Get how many views there are in the viewpager
  • destroyItem( ): Remove a page at a given location. It is the adapter's responsibility to remove this view from the container. This is to ensure The view can be removed when finishUpdate(viewGroup) returns.
  • instantiateItem( ): ① Add the view at the given position to the ViewGroup (container), create and display it ②Return an Object (key) representing the newly added page, usually just return the view itself directly. Of course, you can also customize your own key, but the key must have a one-to-one correspondence with each view
  • isViewFromObject( ): Determine the value returned by the instantiateItem(ViewGroup, int) function Key and whether a page view is represent the same view (that is, whether they are corresponding, and the corresponding ones represent the same View), usually we write directly return view == object; that’s it. As for why it’s done this way, it’s a bit complicated. I’ll have a chance to learn more about it later. It seems that there is an ArrayList in ViewPager that stores view status information. You can retrieve the corresponding information based on View!

PS: It is not necessary to rewrite all methods~


2. Implement the renderings and project directory structure:

Let’s first take a look at the effect we want to achieve

1.gif

Let’s take a look at our project structure:

2.png


3. Code implementation:


Step 1: Preparation of related resource files:

PS: We are writing on the basis of implementing method 2 of the bottom navigation bar, so just copy the resource files! I won’t post it too many times here~!

Step 2: Write the layout file of activity_main.xml:

PS: Just replace the previous FrameLayout with: 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>

Step 3: Write the layout and code of Fragment:

PS: In order to demonstrate the mechanism of ViewPager, four Fragments are specially written here. ! Print creation Log in 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;
    }
}

The other three follow the same pattern, change the points Just the stuff!

Step 4: Customize the FragmentPagerAdapter class:

The code is very simple, just pass a FragmentManager over, and the rest is done here!

/**
 * 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;
    }

}

Step 5: Writing MainActivity:

The logic is very simple, see for yourself~

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: Hehe, I also posted the code for the package import part above, just because I am afraid that you will import the wrong package and some inexplicable errors will occur! Because ViewPager is under the v4 package, Fragment, FragmentManager, and FragmentTransaction all need to be used. It’s under the V4 package! In addition, the method to obtain FragmentManager is not to use getFragmentManager() directly but to use getSupportFragmentManager() Oh!

Note: If ViewPager is placed behind RadioButton, RadioButton's click event will be invalid.


4. Code download:

FragmentDemo4Download FragmentDemo4.zip


Summary of this section :

Okay, the above is the implementation process of the bottom navigation bar + ViewPager to implement simple sliding switching of Fragments! That’s all, thank you~