调用Fragment

前言:

Fragment一般有两种使用情况:

  • 配合ViewPager和TabLayout来进行页面的展示
  • 使用一个FrameLayout布局来当容器,而每个Fragment被add到FrameLayout里

用FrameLayout容器来展示Fragment:

  • 核心类FragmentTransaction:

得到FragmentTransaction对象:
Activity里通过getSupportFragmentManager().beginTransaction()得到
Fragment里通过getActivity().getSupportFragmentManager().beginTransaction()得到

  • FragmentTransaction常用方法:

使用空标记添加containerViewId为FrameLayoutId,fragment为fragment实例化的对象
add(int containerViewId, Fragment fragment)  
使用标记添加Fragment
add(int containerViewId, Fragment fragment, String tag)
将此事务添加到后台堆栈,name可参考对象.getClass().getSimpleName()
addToBackStack(String name)
安排提交此交易
commit()
同commit()但允许在保存活动状态后执行提交。
commitAllowingStateLoss()
同步提交此事务。
commitNow()
同commitNow()但允许在保存活动状态后执行提交。
commitNowAllowingStateLoss()
隐藏现有片段
hide(Fragment fragment)
如果允许将此FragmentTransaction添加到后台堆栈,则返回true
boolean isAddToBackStackAllowed()
删除现有fragment
remove(Fragment fragment)
把现有Fragment替换后再添加到容器里。
replace(int containerViewId, Fragment fragment, String tag)
把现有Fragment替换后再添加到容器里,使用空标记
replace(int containerViewId, Fragment fragment)
为此事务选择标准过渡动画,系统自带可参考FragmentTransaction.TRANSIT_FRAGMENT_CLOSE
setTransition(int transit)
设置将用于解析传输动画的自定义样式资源。
setTransitionStyle(int styleRes)
显示以前隐藏过的片段。
show(Fragment fragment)

  • 示例
  • 先声明FrameLayout:

    <FrameLayout
        android:id="@+id/fl_container"            //id
        android:layout_width="match_parent"        //宽度
        android:layout_height="match_parent" />        //高度

  • 代码里add

getSupportFragmentManager().beginTransaction().add(R.id.fl_container, AmateurWorkFragment.getInstance()).commit();

  • 代码里replace

getSupportFragmentManager().beginTransaction().replace(R.id.vp_home, AmateurWorkFragment.getInstance(), AmateurWorkFragment.getInstance().getClass().getSimpleName())
                .commit();

ViewPager和TabLayout来进行页面的展示:

声明TabLayout:

  • 引入依赖

//noinspection GradleCompatible
    implementation 'com.android.support:design:27.1.1'

  • xml里声明

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tbl_work_declare"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:background="@color/white"
        app:layout_constraintHeight_percent="0.07"
        app:layout_constraintTop_toBottomOf="@+id/ctl_title"
        app:tabIndicatorColor="@color/colorGreen"
        app:tabTextColor="@color/colorGrey"
        app:tabRippleColor = "@android:color/transparent"
        app:tabSelectedTextColor="@color/colorFluorescent">

    </com.google.android.material.tabs.TabLayout>

  • 代码里初始化

TabLayout tblWorkDeclare = findViewById(R.id.tbl_work_declare);
//指示器的宽度对应标题的宽度
tblWorkDeclare.setTabIndicatorFullWidth(false);
// 将每一页要显示的和菜单关联
tblWorkDeclare.setupWithViewPager(vpWorkDeclare);

设置指示器高度,0即为不显示:app:tabIndicatorHeight="0dp"
代码设置指示器高度:tblRecruit.setSelectedTabIndicatorHeight(source);
代码设置文本颜色(选中和未选中都是这个颜色):tblRecruit.setTabTextColors(ColorStateList.valueOf(getResources().getColor(R.color.colorThinBlack)));
设置选中颜色和未选中颜色(参数1未选中,参数2选中):
tblRecruit.setTabTextColors(getResources().getColor(R.color.colorGray), getResources().getColor(R.color.colorFluorescent));

声明ViewPager:

  • xml里声明

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/vp_work_declare"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tbl_work_declare">
        
    </androidx.viewpager.widget.ViewPager>

  • 代码里初始化

ViewPager vpWorkDeclare = findViewById(R.id.vp_work_declare);
//设置适配器
vpWorkDeclare.setAdapter(new viewPageAdapter(getSupportFragmentManager())); 

  • 声明Adapter

    class viewPageAdapter extends FragmentPagerAdapter {
    //用来存储多个不同菜单的页面,顺序与上面的菜单显示对应
        private List<Fragment> fragments = new ArrayList<>();

         viewPageAdapter(FragmentManager fm) {
            super(fm);
            fragments.add(new AllWorkFragment());
            fragments.add(new HaveDeclareFragment());
            fragments.add(new AcceptedFragment());
            fragments.add(new HaveReachedFragment());
            fragments.add(new HaveIncomeFragment());
        }

        @Override
        public Fragment getItem(int position) {
            return fragments.get(position);
        }

        @Override
        public int getCount() {
            return fragments.size();
        }

        //需要额外重写一个方法,绑定每一个窗口的标题
        @Nullable
        @Override
        public CharSequence getPageTitle(int position) {
            return titles[position];

        }
    }

  • 懒加载

ViewPager默认有懒加载,也就是说,它在滑动到第一个Fragement的时候,第二个Fragement里的代码就会自动执行
如果一直向下滑动,那么就会一直按顺序的往下加载,超过懒加载的数量之前最早滑动过的则会销毁,懒加载数量默认为1,如果不设置也是为1
可以在绑定Adapter以后通过ViewPager对象名.setOffscreenPageLimit(int x)来设置懒加载数量:        
// 设置viewpager预加载fragment的数量
mViewPager.setOffscreenPageLimit(2);

  • Fragment里判断是否显示
重写方法
   @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        //isVisibleToUser为true是显示,false为不显示
    }

注意事项:

Activity崩溃后Fragment恢复显示不出来:

在你的Fragment依赖的Activity下添加如下代码(注意只能是一个参数的构造函数):
@Override
protected void onSaveInstanceState(Bundle outState) {
//主页面状态不保存
}


VIewPage:

添加滑动监听:

        vpAmateurContent.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            //position 当前所在页面
            //positionOffset 当前所在页面偏移百分比,取值0.1-1
            //positionOffsetPixels 当前所在页面偏移量
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
            }

            @Override
            public void onPageScrollStateChanged(int state) {
                /**
                 * 参数state有三种取值:
                 * 0:结束
                 * 1:按下
                 * 2:抬起
                 *
                 * 打印了一下滑动过程的顺序:
                 * 从滑动开始依次为:
                 * argo== (1,2,0)
                 */
                if (state == 2) {
                    List<Integer> titles = new ListUtils<Integer>().add(R.id.tv_amateur_work_all, R.id.tv_amateur_work_short, R.id.tv_amateur_work_long);
                    switch (vpAmateurContent.getCurrentItem()) {
                        case JobConfig.ALL_WORK:
                            MyViewUtils.checkType(myView, titles.get(0), titles, R.color.colorGreen, R.color.colorElegantBlack, 0, 0);
                            break;
                        case JobConfig.SHORT_PERIOD:
                            MyViewUtils.checkType(myView, titles.get(1), titles, R.color.colorGreen, R.color.colorElegantBlack, 0, 0);
                            break;
                        case JobConfig.LONG_PERIOD:
                            MyViewUtils.checkType(myView, titles.get(2), titles, R.color.colorGreen, R.color.colorElegantBlack, 0, 0);
                            break;
                    }
                }
            }
        });


onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
这个方法会在屏幕滚动过程中不断被调用
第一个position(这个参数要特别注意一下):位置
当用手指滑动时
如果手指按在页面上不动,position和当前页面index是一致的
如果手指向左拖动(相应页面向右翻动),这时候position大部分时间和当前页面是一致的,只有翻页成功的情况下最后一次调用才会变为目标页面
如果手指向右拖动(相应页面向左翻动),这时候position大部分时间和目标页面是一致的,只有翻页不成功的情况下最后一次调用才会变为原页面
当直接设置setCurrentItem翻页时
如果是相邻的情况(比如现在是第二个页面,跳到第一或者第三个页面)
如果页面向右翻动,大部分时间是和当前页面是一致的,只有最后才变成目标页面
如果向左翻动,position和目标页面是一致的。这和用手指拖动页面翻动是基本一致的。
如果不是相邻的情况
比如我从第一个页面跳到第三个页面,position先是0,然后逐步变成1,然后逐步变成2
我从第三个页面跳到第一个页面,position先是1,然后逐步变成0,并没有出现为2的情况
positionOffset:当前页面因滑动而偏移了多少比例
如果页面向右翻动,这个值不断变大,最后在趋近1的情况后突变为0
如果页面向左翻动,这个值不断变小,最后变为0。
positionOffsetPixels:当前页面因滑动而偏移了多少像素
变化情况和positionOffset一致
一次滑动实例:

 

onPageSelected(int position)
共同
position是滑动结果,也就是新页面的的index
必须切到一个跟上一个不一样的页面才会调用(另两个不需要)
手指滑动
用手指滑动翻页的时候,如果翻动成功了(滑动的距离够长),手指抬起来一瞬间就会立即执行这个方法,不是在滑动结束的时候回调
setCurrentItem翻页
这种情况在onPageScrolled执行方法前就会立即执行
 
onPageScrollStateChanged(int state)
共同
state有三个值:0(END),1(PRESS) , 2(UP)
手指滑动
(滑动时)手指按下去的时候会触发这个方法,state值为1
手指抬起时,如果发生了滑动(即使很小),就会触发这个方法,这个值会变为2
最后滑动结束,页面停止的时候,也会触发这个方法,值变为0
所以一次手指滑动会执行这个方法三次
一种特殊情况是手指按下去以后一点滑动也没有发生,这个时候只会调用这个方法两次,state值分别是1,0 
setCurrentItem翻页
会执行这个方法两次,state值分别为2 , 0 
 

 
用手指拖动翻页时,三个方法的执行顺序为:
最先执行一遍onPageScrollStateChanged(1)
然后不断执行onPageScrolled
放手指的时候,直接立即执行一次onPageScrollStateChanged(2)
然后立即执行一次onPageSelected
然后再不断执行onPageScrolled
最后执行一次onPageScrollStateChanged(0)

设置当前页面:

vpAmateurContent.setCurrentItem(1);

 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值