Android开发ViewPager的预加载和Fragment的销毁问题,以及tabLayout+ViewPager的使用

来源:互联网 发布:闹钟铃声推荐 知乎 编辑:程序博客网 时间:2024/05/16 10:22
最近想起ViwPager+Fragment一起使用的问题,于是就搞了Demo,随便使用了下TabLayout+ViewPager感觉效果还不错.在这里记录一下便于自己日后使用,也可以和大家分享下.

一,首先TabLayout+ViewPager的搭配使用
①因TabLayout是Design包的首先需要第一步导入Design包,AS直接中央仓库下载或者在dependencies中配置也可以

 compile 'com.android.support:design:25.1.0'

②ViewPager+TabLayout的XML布局文件,很简单就二个控件

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <!--tabIndicatorColor:设置选中下划线颜色;tabTextColor:默认字体颜色        tabSelectedTextColor: 选中字体颜色      -->    <android.support.design.widget.TabLayout        android:id="@+id/tabLayout"        android:layout_width="match_parent"        android:layout_height="40dp"        app:tabIndicatorColor="#E81010"        app:tabSelectedTextColor="@color/colorPrimary"        app:tabTextColor="#A2C437" />    <android.support.v4.view.ViewPager        android:id="@+id/viewPager"        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1" /></LinearLayout>

③它们一起使用代码,一些重要的都已经备注就不多废话啦

public class MainActivity extends AppCompatActivity {    private TabLayout mTabLayout;    private ViewPager mViewPager;    private List<String> tabTitle=new ArrayList<>();    private List<Fragment> fragmentList=new ArrayList<>();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();        setTabLaout();        initData();    }    private void initView() {        mTabLayout = (TabLayout) findViewById(R.id.tabLayout);        mViewPager = (ViewPager) findViewById(R.id.viewPager);    }    private void initData() {        fragmentList.add(new FirstFragment());        fragmentList.add(new SecondFragment());        fragmentList.add(new ThirdFragment());        fragmentList.add(new FourthFragment());        fragmentList.add(new FivethFragment());        fragmentList.add(new SixthFragment());        mTabLayout.setTabMode(TabLayout.MODE_FIXED);//MODE_FIXED:根据屏幕填充;MODE_SCROLLABLE :超出屏幕左右滑动        mViewPager.setAdapter(new TabFragmentAdapter(getSupportFragmentManager(),fragmentList,tabTitle));        mTabLayout.setupWithViewPager(mViewPager);//设置TabLayout和ViewPager一起使用        mViewPager.setOffscreenPageLimit(2);    }    private void setTabLaout() {        tabTitle.add("第一个");        tabTitle.add("第二个");        tabTitle.add("第三个");        tabTitle.add("第四个");        tabTitle.add("第五个");        tabTitle.add("第六个");        mTabLayout.addTab(mTabLayout.newTab().setText(tabTitle.get(0)));        mTabLayout.addTab(mTabLayout.newTab().setText(tabTitle.get(1)));        mTabLayout.addTab(mTabLayout.newTab().setText(tabTitle.get(2)));        mTabLayout.addTab(mTabLayout.newTab().setText(tabTitle.get(3)));        mTabLayout.addTab(mTabLayout.newTab().setText(tabTitle.get(4)));        mTabLayout.addTab(mTabLayout.newTab().setText(tabTitle.get(5)));    }}

ViewPager的FragmentPagerAdapter

public class TabFragmentAdapter extends FragmentPagerAdapter {    private final List<Fragment> mFragmentList;    private final List<String> mTabTitle;    public TabFragmentAdapter(FragmentManager fm, List<Fragment> fragmentList, List<String> tabTitle) {        super(fm);        this.mFragmentList=fragmentList;        this.mTabTitle=tabTitle;    }    @Override    public Fragment getItem(int position) {        return mFragmentList.get(position);    }    @Override    public int getCount() {        return mFragmentList.size();    }    @Override    public CharSequence getPageTitle(int position) {        return mTabTitle.get(position % mTabTitle.size());    }}

二,主角出来啦,解决ViewPager的预加载问题和Fragment的销毁问题
1,ViewPager的预加载问题是指:应用在打开一个Fragment的时候它会多加载一个Fragment的数据,造成的影响是当用户不需要另外一个Fragment的时候造成数据浪费问题.为了避免这种情况发生我们通常在应用中会做出处理.我自己处理的代码如下:
①建立一个BaseFragment类继承Fragment

public abstract class BaseFragment extends Fragment {    abstract View initView();    protected boolean isVisible;    @Override    public void setUserVisibleHint(boolean isVisibleToUser) {        super.setUserVisibleHint(isVisibleToUser);        if (isVisibleToUser){            isVisible=true;            onVisible();        }else {            isVisible=false;            onInVisible();        }    }    protected void onVisible() {        //可见时加载数据        Loading();    }    protected abstract void Loading();    protected void onInVisible() {  //不可见时不加载数据    }}

②其他Fragment继承BaseFragment,并重新Loading()方法(因都是相同操作就直接下一个Fragment啦)

public class FirstFragment extends BaseFragment {    private boolean isPrepared;//初始化是否完成    private boolean isHasLoadedOnce;    //是否已经有过一次加载数据    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        isPrepared=true;       TextView textView = new TextView(getContext());        textView.setGravity(Gravity.CENTER);        textView.setTextSize(30);        textView.setTextColor(Color.BLUE);        textView.setText("我是第一个Fragment");        return textView;    }    @Override    View initView() {        //返回Viw        return null;    }    @Override    protected void Loading() {        if (!isVisible||!isPrepared||isHasLoadedOnce){            return;        }else {           new AsyncTask<Void, Void, Boolean>() {               @Override               protected void onPreExecute() {  //网络数据加载前                   super.onPreExecute();               }               @Override               protected Boolean doInBackground(Void... params) {   //网络数据加载中,此方法是在后台运行                   return null;               }               @Override               protected void onPostExecute(Boolean sucess) {//网络数据加载后                   super.onPostExecute(sucess);                   if (sucess){                       isHasLoadedOnce=true;                   }               }           };        }    }}

2,防止Fragment销毁的二种方法.
①ViewPager重写setOffscreenPageLimit()方法,其值默认为1,意义就是可见Fragment+另外一个不可见Fragment,其余统统死啦死啦的。若是设置成2,可见Fragment左右各一个对用户体验较好而且不浪费内存;

 mViewPager.setOffscreenPageLimit(2);

②重写ViewPager的适配器FragmentPagerAdapter,注释其返回值 //super.destroyItem(container, position, object);

@Override    public void destroyItem(ViewGroup container, int position, Object object) {        //super.destroyItem(container, position, object); 避免多出销毁Fragment    }

3,避免FragmentMent多次创建
BaseFragment基类中重写onCReatView()方法定义初始化抽象方法view,这样子类继承BaseFragment的时候就只创建一次,避免多个子类都创建

 protected View mView;    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,  Bundle savedInstanceState) {        mView =initView();        return mView;    } abstract View initView();
1 0
原创粉丝点击