TabLayout+ViewPager更新fragment的ui数据

Posted 客舍青

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TabLayout+ViewPager更新fragment的ui数据相关的知识,希望对你有一定的参考价值。

先看下这样一段代码

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数据的主要内容,如果未能解决你的问题,请参考以下文章

TabLayout+ViewPager更新fragment的ui数据

在不更改选定选项卡的情况下动态更新 TabLayout

由于 ViewPager2 导致 TabLayout 损坏

底部导航片段中的 Viewpager2

tablayout+viewpager怎么设置取消滑动

不使用 ViewPager 的 TabLayout