欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ViewPager+Fragment,Fragment里面嵌套Fragment的简单实现

程序员文章站 2022-06-08 13:06:54
...

今天整理ViewPager的一些内容,一方面巩固一下所学的Android知识,不能学了这忘了那;另一方面以后在需要的时候可以直接拿出来使用,不用再去重新去撸,可以节省点时间。内容还会持续更新加深。

ViewPager+Fragment,Fragment里面嵌套Fragment的简单实现
需求
1.最外层是拨号、联系人、短信三个Fragment滑动
2.然后在拨号的Fragment里面嵌套了Fragment,分别是已拨电话,已接电话,未接电话3个Fragment

明确了目的就直接上代码

主Activity的布局viewpager_activity

<?xml version="1.0" encoding="utf-8"?>
<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">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:background="#333444"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/tv_dial"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="拨号"
            android:textColor="#ffffff"
            android:textSize="18sp"
            tools:ignore="HardcodedText" />

        <TextView
            android:id="@+id/tv_contacts"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="联系人"
            android:textColor="#ffffff"
            android:textSize="18sp"
            tools:ignore="HardcodedText" />

        <TextView
            android:id="@+id/tv_sms"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="短信"
            android:textColor="#ffffff"
            android:textSize="18sp"
            tools:ignore="HardcodedText" />

    </LinearLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/vp_viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

然后是拨号、联系人、短信3个人Fragment的布局,

fragment_dial.xml

<?xml version="1.0" encoding="utf-8"?>
<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">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="36dp"
        android:orientation="horizontal"
        tools:ignore="UselessParent">

        <TextView
            android:id="@+id/tv_yibodianhua"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="已拨电话"
            android:textColor="#4a4a4a"
            android:textSize="16sp"
            tools:ignore="HardcodedText" />

        <TextView
            android:id="@+id/tv_yijiedianhua"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="已接电话"
            android:textColor="#4a4a4a"
            android:textSize="16sp"
            tools:ignore="HardcodedText" />

        <TextView
            android:id="@+id/tv_weijiedianhua"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="未接电话"
            android:textColor="#4a4a4a"
            android:textSize="16sp"
            tools:ignore="HardcodedText" />

    </LinearLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/vp_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

后面两个布局简单也都是一样的,这里就不多啰嗦了

接着就是主Activity的实现

/**
 * 实现标题控件的监听接口,viewpager的页面改变监听接口
 */
public class VpActivity extends FragmentActivity implements ViewPager.OnPageChangeListener, View.OnClickListener {

    private ViewPager mViewPager;
    private TextView mTvDial, mTvContacts, mTvSMS;

    //定义一个list来存放Fragment,建议这里的Fragment使用v4包下面的
    private List<Fragment> mFragmentLists;

    //自定义一个适配器
    private ViewPagerAdapter mAdater;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.viewpager_activity);

        initView();
        initEvent();

        mAdater = new ViewPagerAdapter(getSupportFragmentManager());
        mViewPager.setAdapter(mAdater);
    }

    //初始化控件
    private void initView() {

        mViewPager = findViewById(R.id.vp_viewpager);
        mTvDial = findViewById(R.id.tv_dial);
        mTvContacts = findViewById(R.id.tv_contacts);
        mTvSMS = findViewById(R.id.tv_sms);
        mFragmentLists = new ArrayList<>();

        mFragmentLists.add(new DialFragment());
        mFragmentLists.add(new ContactsFragment());
        mFragmentLists.add(new SMSFragment());

        //默认进入应用第一个被选中
        resetTextViewColor();
        mTvDial.setTextColor(Color.parseColor("#1FB79F"));
    }

    //设置监听
    private void initEvent() {

        mViewPager.addOnPageChangeListener(this);
        mTvDial.setOnClickListener(this);
        mTvContacts.setOnClickListener(this);
        mTvSMS.setOnClickListener(this);
    }

    /**
     * 官方注释:
     * Callback interface for responding to changing state of the selected page.
     * <p>
     * 页面被选择回调(这翻译确实有点生硬,硬伤啊)
     */
    @Override
    public void onPageSelected(int position) {

        resetTextViewColor();
        switch (position) {

            case 0:

                mTvDial.setTextColor(Color.parseColor("#1FB79F"));
                break;

            case 1:

                mTvContacts.setTextColor(Color.parseColor("#1FB79F"));
                break;

            case 2:

                mTvSMS.setTextColor(Color.parseColor("#1FB79F"));
                break;
        }
    }

    //页面滑动过程中回调

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    //页面滑动状态监听
    @Override
    public void onPageScrollStateChanged(int state) {

    }

    //点击事件,当点击标题的时候,通过传入当前点击的页面的position,调用mViewPager.setCurrentItem()来实现页面的变化
    @Override
    public void onClick(View v) {

        switch (v.getId()) {

            case R.id.tv_dial:

                mViewPager.setCurrentItem(0);
                break;

            case R.id.tv_contacts:

                mViewPager.setCurrentItem(1);
                break;

            case R.id.tv_sms:

                mViewPager.setCurrentItem(2);
                break;
        }
    }

    //颜色初始化
    private void resetTextViewColor() {

        mTvDial.setTextColor(Color.WHITE);
        mTvContacts.setTextColor(Color.WHITE);
        mTvSMS.setTextColor(Color.WHITE);
    }

    //适配器
    class ViewPagerAdapter extends FragmentPagerAdapter {

        ViewPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        //获取Fragment
        @Override
        public Fragment getItem(int position) {


            return mFragmentLists.get(position);
        }

        //总共有mFragmentLists.size()个需要显示
        @Override
        public int getCount() {

            return mFragmentLists.size();
        }
    }
}

通过以上代码就可以实现第一个需求(外层的滑动)
最后上嵌套Fragment的代码

public class DialFragment extends Fragment implements View.OnClickListener, ViewPager.OnPageChangeListener {

    private ViewPager mViewPager;
    private TextView mTv1, mTv2, mTv3;
    private List<Fragment> fragmentList;
    private VpAdapter mAdapter;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_dial, container, false);

        initView(view);
        return view;
    }

    private void initView(View view) {

        mViewPager = view.findViewById(R.id.vp_fragment);
        mTv1 = view.findViewById(R.id.tv_yibodianhua);
        mTv2 = view.findViewById(R.id.tv_yijiedianhua);
        mTv3 = view.findViewById(R.id.tv_weijiedianhua);

        mViewPager.addOnPageChangeListener(this);
        mTv1.setOnClickListener(this);
        mTv2.setOnClickListener(this);
        mTv3.setOnClickListener(this);

        fragmentList = new ArrayList<>();
        fragmentList.add(new YBTel());
        fragmentList.add(new YJTel());
        fragmentList.add(new WJTel());

        mAdapter = new VpAdapter(getChildFragmentManager());
        mViewPager.setAdapter(mAdapter);

        resetTextViewColor();
        mTv1.setTextColor(Color.parseColor("#1FB79F"));
    }

    @Override
    public void onPageSelected(int position) {

        resetTextViewColor();
        switch (position) {

            case 0:

                mTv1.setTextColor(Color.parseColor("#1FB79F"));
                break;

            case 1:

                mTv2.setTextColor(Color.parseColor("#1FB79F"));
                break;

            case 2:

                mTv3.setTextColor(Color.parseColor("#1FB79F"));
                break;
        }
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }

    @Override
    public void onClick(View v) {

        switch (v.getId()) {

            case R.id.tv_yibodianhua:

                mViewPager.setCurrentItem(0);
                break;

            case R.id.tv_yijiedianhua:

                mViewPager.setCurrentItem(1);
                break;

            case R.id.tv_weijiedianhua:

                mViewPager.setCurrentItem(2);
                break;
        }
    }

    private void resetTextViewColor() {

        mTv1.setTextColor(Color.parseColor("#4a4a4a"));
        mTv2.setTextColor(Color.parseColor("#4a4a4a"));
        mTv3.setTextColor(Color.parseColor("#4a4a4a"));
    }

    class VpAdapter extends FragmentPagerAdapter {


        VpAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {

            return fragmentList.get(position);
        }

        @Override
        public int getCount() {

            return fragmentList.size();
        }
    }
}

这里面的逻辑与上面外层的逻辑相似,可以参考上面的去理解
需要注意的是:mAdapter = new VpAdapter(getChildFragmentManager())这句
getChildFragmentManager()获取Fragment内部子容器的管理器

好了,这样就实现了上面提出的两个需求,此博文持续加入新东西,如有错误之处,请多多指教!

完整代码