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;
        }
    }

}
时间: 2024-10-24 23:22:14

TabLayout+ViewPager更新fragment的ui数据的相关文章

Android开发之漫漫长途 Fragment番外篇——TabLayout+ViewPager+Fragment

该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解Android 卷Ⅰ,Ⅱ,Ⅲ>中的相关知识,另外也借鉴了其他的优质博客,在此向各位大神表示感谢,膜拜!!! 前言 上一篇文章中我们使用底部导航+Fragment的方式实现了Android主流App中大都存在的设计.并命名其为"Fragment最佳实践",作为想到单独使用Fragment的用

关于TabLayout与ViewPager在Fragment中嵌套Fragment使用或配合使用的思考

注意: 因为继承的是Fragment,所以getSupportFragmentManager()与getFragmentManager()方法无法使用,这里需要用到getChildFragmentManager()方法: (用getFragmentManager()方法并不会报错,但到时候运行的时候会出问题,查了好久才知道这个错误) 统一Fragment类型,要么为"android.support.v4.app.Fragment",要么为"android.app.Fragme

TabLayout与ViewPager和Fragment、FragmentPagerAdapter的合用

activity_main.xml 注意要把垂直设置好,因为是linearLayout布局,漏掉了就不能滑动了 <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tool

RecyclerView之更新UI数据的高级用法

原创文章,转载请注明 ( 来自:http://blog.csdn.net/leejizhou/article/details/51179233 李济洲的博客 ) 如果你还不了解RecyclerView如何去使用,可以参考我的前面几篇博文,再看此篇博文:) RecyclerView的使用(1)之HelloWorld RecyclerView的使用(2)之多Item布局的加载 RecyclerView的使用(3)之添加Header和Footer RecyclerView的使用(4)之下拉刷新和上拉加

Winform中使用Reactivex代替BeginInvoke/Invoke来更新UI数据

首先通过Nuget安装包System.Reactive. ReactiveX项目 Url: https://github.com/Reactive-Extensions/Rx.NET 1 public partial class ZSerialportForm : Form 2 { 3 private SerialPort sp; 4 private byte[] buffer = new byte[1024]; 5 // 定义ReactiveX对象 6 private IScheduler s

使用FragmentTabHost+TabLayout+ViewPager实现双层嵌套Tab

大多数应用程序都会在底部使用3~5个Tab对应用程序的主要功能进行划分,对于一些信息量非常大的应用程序,还需要在每个Tab下继续划分子Tab对信息进行分类显示. 本文实现采用FragmentTabHost+TabLayout+ViewPager实现双层嵌套Tab,实现原理如下: 第一层Tab:FragmentTabHost + Fragment; 第二层Tab:在第一层的Fragment中使用TabLayout和ViewPager实现. 第一层Tab实现: 1.布局文件activity_main

关于TabLayout+ViewPager组合实现多页面滑动

转载请注明出处:http://blog.csdn.net/ht_android/article/details/46647711 在android提供的design library中新增了一个控件,叫TabLayout,它继承自HorizontalScrollView,可以实现android中多页面滑动切换效果.但是一般需要和ViewPager组合使用,官方API地址:https://developer.android.com/reference/android/support/design/w

ViewPager之Fragment页面切换

一.概述 ViewPager是android-support-v4中提供的类,它是一个容器类,常用于页面之间的切换. 继上篇文章<ViewPager之引导页>之后,本文主要介绍ViewPager更为通用的实践:ViewPager搭配Fragment实现页面切换. 这种实现方式相对于上篇文章而言,可以更好的支持不同页面各自的复杂逻辑,与此同时,也能够保障页面之间的耦合度尽可能的低. 按照惯例,先晒出效果图:        二.实现思路 首先分析一下不同区域的交互需求: 中间灰色区域除了要支持三套

viewpager中fragment的生命周期管理

viewpager中fragment的生命周期管理 - i_bobby - 开源中国社区 调试fragment的时候发现一个莫名其妙的事情,viewpager中包含4个fragment,其中第一个和第三个fragment是要联网取得数据的,如图: 界面刚进去的时候显示第一个fragment,通过log信息,我发现two fragment竟然"偷偷"走了一遍的生命周期!着实把我震惊了! 然后我滑动到two,发现第三个也"偷"了一遍生命周期,也就是说,手机在显示第二个不