为什么要写这篇文章,一是我本人经历过的一些坑,从中的学习和思考,二是,我们在入门开发这一门的时候,我们也要花费多点思考,采用什么的具体方式来开发现在的业务,以及他可行性,会出现的各种技术上的问题,或者优缺点,是否影响我们整个项目的正常跑通。当前比较流行的多个标签点击切换相应布局页面有以下两种比较常用的方式:
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
分享一个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
这些文章都写的很详细,通俗易懂,很适合我们初学者学习使用,慢慢探索。
当然如果不太了解这种方式的的话,我推荐一篇实用价值高的文章就能明白了: 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);
}
}
这样的好处在于第一次初始化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);就可以实现页面的显示。
还有很多问题,先总结到这里,剩下的再补充完整,如果你也遇到这些问题,可以留言,我补充其中的问题,以及修改我的错误问题。