ViewPager的刷新

ViewPager的刷新

最近有个需求涉及到viewpager的刷新问题,需求是这样的:一进入界面即发起数据请求,请求到数据后,根据数据的对象个数加载对应数目的fragment,并把相应的对象传递给fragment,进行数据的显示。但是当网络速度慢的时候就会出现一段时间的界面空白,用户体验不好。处理办法是,一开始先先加载一个fragment,显示默认数据,等网络请求到数据后再刷新显示,就类似listview的空数据处理。
Listview 的刷新很常见,也很简单,就是listview绑定的adapter设置新的数据,然后`adapter.notifyDataSetChanged();`一下 就可以刷新整个列表。
但是viewpager就稍微麻烦一些。有些人 可能会再要刷新的时候重新设置一下适配器,也能达到刷新的目的。但某些情况下会出现问题(具体什么情况,偶也不不清楚~~)
这里只是记录一下我的解决方案

我的解决方案有两种:

1.预加载几个空的fragment,比如说6个,然后获取到新数据后,再将对应得数据传给对应得fragment,以达到刷新的目的。但是这样有个弊端就是我无法得知新数据的长度,如果预加载的fragment 少于新数据的长度,就无法显示完全,如果多于,就会出现活动到最后出现空界面。

2.这种方法其实是在第一种方法基础上做的修改,即刚开始预加载1个fragment,以至于用户看到的界面不是空的,然后获取到新数据后,就把之前加载的fragment移除,根据新数据,重新绘制相应个数的fragment。但是,这样做有一个缺点,那就是会造成不必要的浪费,会影响性能。还有就是必须使用一个 List 缓存所有的 Fragment,这也得占用不少内存…,如果需求不是很复杂,可以考虑如果不是很理解,看代码:
activity界面布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingTop="@dimen/activity_vertical_margin">

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:background="#42452389"
        android:layout_marginLeft="30dp"
        android:layout_marginRight="30dp"
        android:clipChildren="false"></android.support.v4.view.ViewPager>

    <Button
        android:id="@+id/btn1"
        android:layout_width="100dp"
        android:layout_height="50dp"
        android:text="更新1"
        android:layout_below="@+id/viewpager"
        android:layout_marginTop="20dp"
        android:layout_marginLeft="50dp"/>
    <Button
        android:id="@+id/btn2"
        android:layout_width="100dp"
        android:layout_height="50dp"
        android:text="更新2"
        android:layout_below="@+id/viewpager"
        android:layout_marginTop="20dp"
        android:layout_marginLeft="200dp"/>


</RelativeLayout>

fragment界面布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:background="#78976540">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="发个红包让我撑过这个月"
        android:id="@+id/textView"
        android:textSize="24sp"
        android:textColor="@android:color/black"/>
    <TextView
        android:id="@+id/tv_index"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="page 1"
        android:layout_marginTop="100dp"
        android:textColor="@android:color/holo_red_dark"/>
</LinearLayout>
Activity.java
public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private ViewPager viewPager;
    private ViewPagerAdapter adapter;
    private List<ChildFragment> listFragments = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        viewPager = (ViewPager)findViewById(R.id.viewpager);
        listFragments.add(new ChildFragment());
        //listFragments.add(new ChildFragment());
        adapter = new ViewPagerAdapter(getSupportFragmentManager(),listFragments);
        viewPager.setAdapter(adapter);
        Button btn1 = (Button)findViewById(R.id.btn1);
        Button btn2 = (Button)findViewById(R.id.btn2);
        btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //这里一定要先清空列表
                listFragments.clear();
                for (int i = 0; i < 9; i++) {
                    listFragments.add(ChildFragment.newInstance(i));
                }
                //更新数据之前,要先把之前预加载的子view全部清除,重新绘制新view,不然adapter.getItem时发现缓存的有fragment,就会拿出来用,而不会重新绘制,达不到刷新的效果
                viewPager.removeAllViews();
                adapter.setDatas(listFragments);
                adapter.notifyDataSetChanged();
                viewPager.setCurrentItem(0);
            }
        });
        btn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                listFragments.clear();
                for (int i = 0; i < 3; i++) {
                    listFragments.add(new ChildFragment());
                }
                viewPager.removeAllViews();
                adapter.setDatas(listFragments);
                adapter.notifyDataSetChanged();
                viewPager.setCurrentItem(0);
            }
        });
    }

}

ViewPagerAdapter.java

//FragmentStatePagerAdapter 和 FragmentPagerAdapter的区别这里不做介绍,有兴趣可以百度一下
public class ViewPagerAdapter extends FragmentStatePagerAdapter{
    private List<ChildFragment> listFragments ;
    public ViewPagerAdapter(FragmentManager fm,List<ChildFragment> listFragments) {
        super(fm);
        this.listFragments = listFragments;
    }

    public void setDatas(List<ChildFragment> listFragments){
        this.listFragments = listFragments;
    }
    @Override
    public Fragment getItem(int position) {
        if (null == listFragments){
            return null;
        }else {
            return listFragments.get(position);
        }
    }

    @Override
    public int getCount() {
        return listFragments == null ? 0 : listFragments.size();
    }

    //getItemPosition()  如果 Item 的位置如果没有发生变化,则返回 POSITION_UNCHANGED。如果返回了 POSITION_NONE,表示该位置的 Item 已经不存在了。默认的实现是假设 Item 的位置永远不会发生变化,而返回 POSITION_UNCHANGED。所以调用notifyDataSetChanged方法不会刷新Fragment。为了让Fragment重新绘制,必须重载PagerAdapter的getItemPositon方法并修改为return POSITION_NONE。这样之前所有的Fragment都会被detach掉。
    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }
}

ChildFragment.java

public class ChildFragment extends Fragment{
    private String[] content = {
            "帝高阳之苗裔兮,朕皇考曰伯庸。",
            "摄提贞于孟陬兮,惟庚寅吾以降。",
            "皇览揆余初度兮,肇锡余以嘉名:",
            "名余曰正则兮,字余曰灵均。",
            "纷吾既有此内美兮,又重之以修能。",
            "扈江离与辟芷兮,纫秋兰以为佩。",
            "汨余若将不及兮,恐年岁之不吾与。",
            "朝搴阰之木兰兮,夕揽洲之宿莽。",
            "日月忽其不淹兮,春与秋其代序。",
    };
    private static final String KEY = "index";
    public static ChildFragment newInstance(int index){
        ChildFragment childFragment = new ChildFragment();
        Bundle bundle = new Bundle();
        bundle.putInt(KEY, index);
        childFragment.setArguments(bundle);
        return childFragment;
    }
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        return inflater.inflate(R.layout.layout_item,null);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        TextView textView = (TextView) getView().findViewById(R.id.textView);
        TextView textViewIndex = (TextView) getView().findViewById(R.id.tv_index);
        Bundle bundle = getArguments();
        if (null == bundle){

        }else {
            int index = bundle.getInt(KEY);
            textView.setText(content[index]);
            textViewIndex.setText("page " + String.valueOf(index + 1));
        }
    }
}

运行结果:(偶不会截动图,凑合着看吧)
初始界面:
这里写图片描述
点击按钮 更新1
第一页
这里写图片描述
最后一页
这里写图片描述

是不是达到更新的目的了呢,点击按扭 更新2会更新到初始到初始样子,第一张图

这只是解决了我的需求,viewpager的刷新介绍的并不完善,想知道更多可以参考ViewPager刷新问题详解,我觉得这个写的特别详细,鉴于博主我能力有限,这里只是简单记录一下自己的解决办法,之后遇到能有个方向。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值