1. 程式人生 > >Activity,ViewPager,Fragment和TabLayout資料傳遞

Activity,ViewPager,Fragment和TabLayout資料傳遞

描述:Activity頂部嵌著一個按鈕供選擇型別,TabLayout有三個選項卡,ViewPager有三個Fragment,不論是點選還是滑動到每個Fragment,點選按鈕選擇型別可改變相對著的Fragment中資料,並且每次滑動或者點選呈現的資料都是按鈕型別對應著的。上一下效果圖:


問題 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的預快取機制導致每次滑到中間時其按鈕型別自動載入的是快取資料那一方的,所以不能及時更新中間的資料型別,只能將預快取遮蔽掉: