1. 程式人生 > >TabLayout+ViewPager更新fragment的ui數據

TabLayout+ViewPager更新fragment的ui數據

back ges tool layout handler tle tex bindview bing

先看下這樣一段代碼

private String titles[] = new String[]{"今天", "這周", "這月", "今年"};
    boolean[] fragmentsUpdateFlag = { false, false, false, false };
        StarFragment todatFragmet=new StarFragment(titles[0],starDetailEntity, AppConstants.TYPE_CONTENT_TODAY);
        StarFragment weekFragmet=new StarFragment(titles[1],starDetailEntity, AppConstants.TYPE_CONTENT_WEEK);
        StarFragment monthFragmet
=new StarFragment(titles[2],starDetailEntity, AppConstants.TYPE_CONTENT_MONTH); StarFragment yearFragmet=new StarFragment(titles[3],starDetailEntity, AppConstants.TYPE_CONTENT_YEAR); BaseFragment fragments[]={todatFragmet,weekFragmet,monthFragmet,yearFragmet};

我們定義了一些要使用的fragment,並且使用viewPager展示出來了。由於viewPager自身的緩存機制和預加載機制導致這樣的一個問題。

當我們請求接口請求一些數據回來要以後,想要更新某個fragment,但是界面數據總是更新失敗。

那麽這樣的問題據我研究之後要這樣來解決:

原理就是把就舊的fragment去除掉,換成新的fragment就OK了。

具體實現方法為重寫adapter的 instantiateItem()方法。

@Override
        public Object instantiateItem(ViewGroup container, int position) {
            //得到緩存的fragment
            Fragment fragment= (Fragment) super
.instantiateItem(container, position); //獲取到tag String fragmentTag=fragment.getTag(); if (fragmentsUpdateFlag[position % fragmentsUpdateFlag.length]){//如果這個fragment需要更新 android.support.v4.app.FragmentTransaction ft=fm.beginTransaction(); //移除舊的fragment ft.remove(fragment); //換成新的fragment fragment = fragments[position % fragments.length]; //添加新fragment時必須用前面獲得的tag,這點很重要 ft.add(container.getId(), fragment, fragmentTag ==null? fragment.getClass().getName()+position : fragmentTag); ft.attach(fragment); ft.commit(); //復位更新標誌 fragmentsUpdateFlag[position % fragmentsUpdateFlag.length] = false; } return fragment; }

下面貼出這個activity的全部的代碼以供自己查閱:

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.ViewGroup;
import com.bingo.cqtimelottery.R;
import com.bingo.cqtimelottery.api.ApiService;
import com.bingo.cqtimelottery.api.RetrofitManager;
import com.bingo.cqtimelottery.base.BaseActivity;
import com.bingo.cqtimelottery.base.BaseFragment;
import com.bingo.cqtimelottery.constants.ApiConstant;
import com.bingo.cqtimelottery.constants.AppConstants;
import com.bingo.cqtimelottery.starfortune.entity.StarDetailEntity;
import com.bingo.cqtimelottery.util.DateUtil;
import java.util.HashMap;
import java.util.Map;
import butterknife.BindView;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class StarFortuneDetailActivity extends BaseActivity {

    @BindView(R.id.tabLayout)
    TabLayout mTabLayout;
    @BindView(R.id.viewPager)
    ViewPager mViewPager;
    private String titles[] = new String[]{"今天", "這周", "這月", "今年"};
    boolean[] fragmentsUpdateFlag = {false, false, false, false};
    StarFragment todatFragmet = new StarFragment(titles[0], starDetailEntity, AppConstants.TYPE_CONTENT_TODAY);
    StarFragment weekFragmet = new StarFragment(titles[1], starDetailEntity, AppConstants.TYPE_CONTENT_WEEK);
    StarFragment monthFragmet = new StarFragment(titles[2], starDetailEntity, AppConstants.TYPE_CONTENT_MONTH);
    StarFragment yearFragmet = new StarFragment(titles[3], starDetailEntity, AppConstants.TYPE_CONTENT_YEAR);
    BaseFragment fragments[] = {todatFragmet, weekFragmet, monthFragmet, yearFragmet};
    private String starName;
    private String starId;
    public static StarDetailEntity starDetailEntity;
    StarPagerFragmentAdapter mainAdapter;
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.arg1 == 100) {
                fragments[0] = new StarFragment(titles[0], starDetailEntity, AppConstants.TYPE_CONTENT_TODAY);
                fragmentsUpdateFlag[0] = true;
                mainAdapter.notifyDataSetChanged();
            }
        }
    };


    public static StarDetailEntity getStarDetailEntity() {
        return starDetailEntity;
    }

    public static void setStarDetailEntity(StarDetailEntity starDetailEntity) {
        StarFortuneDetailActivity.starDetailEntity = starDetailEntity;
    }

    @Override
    public int getLayoutRes() {
        return R.layout.activity_star_fortune_detail;
    }

    @Override
    public void onCreateActivity(@Nullable Bundle savedInstanceState) {
        Bundle bundle = getIntent().getExtras();
        starName = bundle.getString("starName");
        starId = bundle.getString("starId");
        initToolbar(starName);
        initAdapter();
        getStarDetailInfo(starId);
    }

    private void initAdapter() {

        mainAdapter = new StarPagerFragmentAdapter(getSupportFragmentManager(), fragments, titles);
        mViewPager.setAdapter(mainAdapter);
        mTabLayout.setupWithViewPager(mViewPager);
        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                // arg0 :當前頁面,及你點擊滑動的頁面;arg1:當前頁面偏移的百分比;arg2:當前頁面偏移的像素位置
            }

            @Override
            public void onPageSelected(int position) {
                // arg0是當前選中的頁面的Position
                switch (position) {
                    case 0: //今天

                        break;
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {
                //arg0 ==1的時表示正在滑動,arg0==2的時表示滑動完畢了,arg0==0的時表示什麽都沒做。

            }
        });
    }

    /**
     * 請求網絡數據
     * @param lotteryid
     */
    private void getStarDetailInfo(String lotteryid) {
        showLoading();
        Map<String, String> map = new HashMap<>();
        map.put("astroid", lotteryid);
        map.put("date", DateUtil.formateDateString().substring(0, 10));
        map.put("appkey", ApiConstant.API_KEY);
        RetrofitManager.getInstance().createReq(ApiService.class)
                .loadStarDetailInfo(map)
                .enqueue(new Callback<StarDetailEntity>() {
                    @Override
                    public void onResponse(Call<StarDetailEntity> call, Response<StarDetailEntity> response) {
                        dismissLoading();
                        if (response.body() != null)
                            starDetailEntity = response.body();
                        //使用Handler發送數據跟新UI
                        Message message = new Message();
                        message.arg1 = 100;
                        mHandler.sendMessage(message);
                    }

                    @Override
                    public void onFailure(Call<StarDetailEntity> call, Throwable t) {

                    }
                });
    }


    private void replaceTodayFragment() {

    }


    public class StarPagerFragmentAdapter<T extends Fragment> extends FragmentPagerAdapter {

        private BaseFragment[] mList;
        private String[] mTitles;
        private StarDetailEntity starDetailEntity;
        private FragmentManager fm;

        public StarDetailEntity getStarDetailEntity() {
            return starDetailEntity;
        }

        public void setStarDetailEntity(StarDetailEntity starDetailEntity) {
            this.starDetailEntity = starDetailEntity;
        }

        public StarPagerFragmentAdapter(FragmentManager fm, BaseFragment[] list, String[] titles) {
            super(fm);
            this.mList = list;
            this.mTitles = titles;
            this.fm = fm;
        }

        @Override
        public Fragment getItem(int position) {
            Fragment fragment = fragments[position % fragments.length];
            Log.i("zzccbb", "getItem:position=" + position + ",fragment:"
                    + fragment.getClass().getName() + ",fragment.tag="
                    + fragment.getTag());
            return fragments[position % fragments.length];
        }

        @Override
        public int getItemPosition(Object object) {
            return POSITION_NONE;
        }

        @Override
        public int getCount() {
            return mList.length;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return mTitles == null ? super.getPageTitle(position) : mTitles[position];
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            //得到緩存的fragment
            Fragment fragment = (Fragment) super.instantiateItem(container, position);
            //獲取到tag
            String fragmentTag = fragment.getTag();
            if (fragmentsUpdateFlag[position % fragmentsUpdateFlag.length]) {//如果這個fragment需要更新
                android.support.v4.app.FragmentTransaction ft = fm.beginTransaction();
                //移除舊的fragment
                ft.remove(fragment);
                //換成新的fragment
                fragment = fragments[position % fragments.length];
                //添加新fragment時必須用前面獲得的tag,這點很重要
                ft.add(container.getId(), fragment, fragmentTag == null ? fragment.getClass().getName() + position : fragmentTag);
                ft.attach(fragment);
                ft.commit();

                //復位更新標誌
                fragmentsUpdateFlag[position % fragmentsUpdateFlag.length] = false;

            }
            return fragment;
        }
    }


}

TabLayout+ViewPager更新fragment的ui數據