Android开发ViewPager的预加载和Fragment的销毁问题,以及tabLayout+ViewPager的使用,tablayout平板适配问题解决

最近想起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的销毁问题
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销毁的方法.(方法针对fragment中数据量不是很大,对内存消耗不是很在意)
①ViewPager重写setOffscreenPageLimit()方法,其值默认为1。若是设置成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();

三,在使用tabLayout适配平板出现title字体不居中的问题解决方法
在布局文件中添加:

 app:tabMaxWidth="0dp"
 app:tabGravity="fill"
 app:tabMode="fixed"
  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值