Android activity+多个fragment 页面滑动切换的集成项目前的小建议和思考

         为什么要写这篇文章,一是我本人经历过的一些坑,从中的学习和思考,二是,我们在入门开发这一门的时候,我们也要花费多点思考,采用什么的具体方式来开发现在的业务,以及他可行性,会出现的各种技术上的问题,或者优缺点,是否影响我们整个项目的正常跑通。当前比较流行的多个标签点击切换相应布局页面有以下两种比较常用的方式:

              1.懒加载方式:(activity)+viewpager+fragment +Tablayout

        private ArrayList fragments;
        private TobFragmentPagerAdapter adpater;
        private IndexViewPager MyViewPager;

        fragments = new ArrayList<>();
        fragments.add(new VideoFragment());
        fragments.add(new ImageFragment());
        fragments.add(new processFragment());


        //禁止滑动页面 t/f 手动开始滑动/关闭
        MyViewPager.setScanScroll(true);

        adpater = new TobFragmentPagerAdapter(getSupportFragmentManager(), fragments);
        MyViewPager.setAdapter(adpater);
        try {
            MyViewPager.setCurrentItem(0);
        } catch (Resources.NotFoundException e) {
            e.printStackTrace();
        }

        //layout 下的xml
        MyViewPager = findViewById(R.id.myViewPager);

           这里面我放入了三个Fragment 来展示相应的布局页面,里面有一个控制页面左右滑动的方法,很简单,只是重写一个自定义的viewpager类,extends Viewpager  重写下面的方法就可以了。 通过一行代码调用就可以开启、关闭页面滑动
        MyViewPager.setScanScroll(true);

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;

public class IndexViewPager extends ViewPager {
    private boolean isCanScroll = true;//开启滑动

    public IndexViewPager(@NonNull Context context) {
        super(context);
    }

    public IndexViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * 设置其是否能滑动换页
     *
     * @param isCanScroll false 不能换页, true 可以滑动换页
     */
    public void setScanScroll(boolean isCanScroll) {
        this.isCanScroll = isCanScroll;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return isCanScroll && super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return isCanScroll && super.onTouchEvent(ev);
    }
}
  

    MyViewPager.setCurrentItem(index); 调用这行代码 传入你想要进去的list 的下标,切换到你想要的页面,方式网上很多demo,我就不重新把完整代码发出来了。当然说到这里,这是简单的实现大逻辑而已,我们为什么称呼它为懒加载或者预加载,很简单,当你初始化app的时候,它会顺便把第二页面的布局初始化生命周期也跑起来,所以这边如果是想着用单个Fragment的生命周期处理较为复杂的控制代码,就让你原本的业务实现起来会特别困难,当然也是不建议这样做的,也是考虑到设计模式那些解耦问题。如果你觉得,你有这样的需要,也可以实现,但是你就要学习,activity与fragment页面相互传递数据问题了。

分享一个viewpager+fragment的详细生命周期变化的文章:                https://blog.csdn.net/qq451765271/article/details/71475360
       activity+fragment 页面传递数据的文章:

        https://www.cnblogs.com/mrszhou/p/7101270.html

        http://www.pianshen.com/article/440247363/

        https://blog.csdn.net/qq_41545435/article/details/81408789

       这些文章都写的很详细,通俗易懂,很适合我们初学者学习使用,慢慢探索。

  2.FragmentTransaction(事务控制):(activity)+fragment  +Tablayout

  当然如果不太了解这种方式的的话,我推荐一篇实用价值高的文章就能明白了:  https://blog.csdn.net/gsw333/article/details/51858524

 

这里面重要的是fragment  add 添加 fragment  show()/hide()  我就里面文章的一些用法简单的说明一下自己的观点:

事务常用的两种方式: add和replace方式切换

   //显示第一个fragment
    private void initFragment1() {
        //开启事务,fragment的控制是由事务来实现的
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

       /* fragment_one = new Fragment_one();
        transaction.replace(R.id.main_fragment, fragment_one);*/
        //第一种方式(add),初始化fragment并添加到事务中,如果为null就new一个
        if (fragment_one == null) {
            fragment_one = new Fragment_one();
            transaction.add(R.id.main_fragment, fragment_one);
            // transaction.replace(R.id.main_fragment, fragment_one);
        }

        //隐藏所有fragment
        hideFragment(transaction);
        //显示需要显示的fragment
        transaction.show(fragment_one);
        //提交事务
        transaction.commit();
    }

    //显示第二个fragment
    private void initFragment2() {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
      /*  fragment_two = new Fragment_two();
        transaction.replace(R.id.main_fragment, fragment_two);*/

        if (fragment_two == null) {
            fragment_two = new Fragment_two();
            transaction.add(R.id.main_fragment, fragment_two);
            //transaction.replace(R.id.main_fragment, fragment_two);
        }

        hideFragment(transaction);
        transaction.show(fragment_two);
        transaction.commit();
    }

    //显示第三个fragment
    private void initFragment3() {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
     /*   fragment_three = new Fragment_three();
        transaction.replace(R.id.main_fragment, fragment_three);*/

        if (fragment_three == null) {
            fragment_three = new Fragment_three();
            transaction.add(R.id.main_fragment, fragment_three);
            //  transaction.replace(R.id.main_fragment, fragment_three);
        }

        hideFragment(transaction);
        transaction.show(fragment_three);
        transaction.commit();
    }

    //隐藏所有的fragment
    private void hideFragment(FragmentTransaction transaction) {
        if (fragment_one != null) {
            transaction.hide(fragment_one);
        }
        if (fragment_two != null) {
            transaction.hide(fragment_two);
        }
        if (fragment_three != null) {
            transaction.hide(fragment_three);
        }
    }

     使用add的时候,我们刚创建app启动的时候,会先去判断当前的Fragment是否 初始化fragment并添加到事务中,如果为null就new一个,然后在里面写好一个hideFragment()方法,去隐藏所有的fragment,当调用initFragment X () 方法的时候,再显示相应的页面show出来,最后提交事务就行了。

  这样的好处在于第一次初始化fragment页面的时候,生命周期只会oncreate()一次,直到整个宿主activity销毁,他们的fragment的生命周期才会销毁,避免了系统资源的内存重复调用大的开销,反正就是这样说了,不同自己BAIdu 。正如事务本身的优缺点:当个fragment页面数据如果在oncreate()调用了一次,剩下的页面重复展示我的数据怎么办,我这边用的是:

 

  @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (hidden) {
            // Log.i(TAG, "隐藏");
         

        } else {
            //TODO now invisible to user
            // Log.i(TAG, "显示");
         
    }

onHiddenChanged 当我们再去显示相应页面的时候,这个方式很好的帮助我们来查看该fragment的显示或者隐藏状态。从中在里面去处理数据请求或者其他的逻辑问题,这里还有一些问题,就是:

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
    }

这个方法的使用,如果你还想了解fragment的页面保存状态,以及 FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();  //提交事务
        transaction.commit();可以从它的事务下手深入学习。

说了上面的add方式,接下来就说说剩下的replace方式切换,先说他的有缺点吧,它可以根据fragment的页面显示来创建相应的生命周期,这样是很方便我们初学者的理解模式的方式,我却不太推荐这种方式,还是他的内存开销问题,占用问题,重复去创建多个fragment的生命周期是个坏事情,容易导致程序的OOM。举例子单个具体代码调用:

//显示第一个fragment
    private void initFragment1() {
        //开启事务,fragment的控制是由事务来实现的
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

       
        //第一种方式(add),初始化fragment并添加到事务中,如果为null就new一个
        if (fragment_one == null) {
            fragment_one = new Fragment_one();
     
          transaction.replace(R.id.main_fragment, fragment_one);
        }

        //隐藏所有fragment
        hideFragment(transaction);
        //显示需要显示的fragment
        transaction.show(fragment_one);
        //提交事务
        transaction.commit();
    }

也是一行代码的事情   transaction.replace(R.id.main_fragment, fragment_one);就可以实现页面的显示。

     还有很多问题,先总结到这里,剩下的再补充完整,如果你也遇到这些问题,可以留言,我补充其中的问题,以及修改我的错误问题。

你可能感兴趣的:(Android+java)