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

Activity,ViewPager,Fragment和TabLayout数据传递

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

描述:Activity顶部嵌着一个按钮供选择类型,TabLayout有三个选项卡,ViewPager有三个Fragment,不论是点击还是滑动到每个Fragment,点击按钮选择类型可改变相对着的Fragment中数据,并且每次滑动或者点击呈现的数据都是按钮类型对应着的。上一下效果图:

Activity,ViewPager,Fragment和TabLayout数据传递

问题 activity的数据传递给对应着的Fragment:

1)写一个ViewPager的适配器:点击下载源码链接

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

import java.util.List;

/**
 * Created by xy on 2017-12-14.
 * ViewPager 的适配器
 */

public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
    private String[] mTitles = new String[]{"我提交的","我审批的","抄送我的"};
    List<Fragment> mList;
    public MyFragmentPagerAdapter(FragmentManager fm, List<Fragment> mList) {
        super(fm);
        this.mList = mList;
    }

    @Override
    public Fragment getItem(int position) {
        return mList.get(position);
    }

    @Override
    public int getCount() {
        if(mList.size()<=0){
            return 0;
        }
        return mList.size();
    }

    //设置tab的标题
    @Override
    public CharSequence getPageTitle(int position) {
        return mTitles[position];
    }
}
2)在主activity中初始化MyFragmentPagerAdapter:

        //右上角选择类型
        righttv.setText("类型");
        //TabLayaout
        mHandle_tab = findViewById(R.id.handle_tab);
        //ViewPager
        mViewPager = findViewById(R.id.view_pager);
        //初始化MyFragmentPagerAdapter
        myFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(),mList);
        mViewPager.setAdapter(myFragmentPagerAdapter);
        mViewPager.setCurrentItem(0);
        //将TabLayout和ViewPager绑定在一起,使双方各自的改变都能直接影响另一方,解放了开发人员对双方变动事件的监听
        mHandle_tab.setupWithViewPager(mViewPager);
        mHandle_tab.setVerticalScrollbarPosition(0);
3)每次点击右上角出现数据类型,选择之后将数据传给当前Fragment:如“我提交的”----- CommitFragment

在CommitFragment中写一个方法:用于传递数据

public void showMessageFromActivity(String message){
        type = message;
    }

在activity中调用:根据选择的tab判断调用

mHandle_tab.getSelectedTabPosition()
/**
     * 从Activity传递类型到Fragment 加载数据
     * @param selectedTabPosition 选中的tab位置
     * @param type 查看的类型
     */
    private void loadData(int selectedTabPosition, String type) {
        if ( selectedTabPosition == 0) {
            //我提交的
            CommitFragment fragment0= (CommitFragment) myFragmentPagerAdapter.getItem(0);
            fragment0.showMessageFromActivity(type);
        }else if (selectedTabPosition == 1){
            //我审批的
            ReviseFragment fragment1 = (ReviseFragment) myFragmentPagerAdapter.getItem(1);
            fragment1.showMessageFromActivity(type);
        }else if (selectedTabPosition == 2){
            //抄送我的
            SendFragment fragment2 = (SendFragment) myFragmentPagerAdapter.getItem(2);
            fragment2.showMessageFromActivity(type);
        }
    }


4)数据传完成之后,再次滑动发现按钮类型没有跟着发生变化,需要在fragment中写一个接口让activity调用,不过一定要在fragment onAttach()方法中实例化该接口:
CallBackCommitValue callBackValue;

/**
     * fragment与activity产生关联是  回调这个方法
     */
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        //当前fragment从activity重写了回调接口  得到接口的实例化对象
        callBackValue = (CallBackCommitValue) getActivity();
    }

    //定义一个回调接口
    public interface CallBackCommitValue{
        void SendMessageValue(String type, String strValue);
    }
在activity中实现该接口,并将获取到的数据放到右上角:
/**
     * 获取的类型
     * @param strValue
     */
    @Override
    public void SendMessageValue(String type, String strValue) {

            if (TextUtils.isEmpty(strValue)){
                righttv.setText("全部");
            }else {
                righttv.setText(strValue);
            }

    }
5)由于ViewPager的预缓存机制导致每次滑到中间时其按钮类型自动加载的是缓存数据那一方的,所以不能及时更新中间的数据类型,只能将预缓存屏蔽掉:

请参考:防止ViewPager和Fragment结合使用时候的数据预加载 点击打开链接

我只用了前两种方法,如果加时间的话会又出现4)的情况所以没有处理,如果有更好的解决方法欢迎指正。

点击下载源码链接