多个Fragment的跳转
现在的很多软件都要涉及多个页面的切换,这里就可以使用Fragment来做到,若使用Fragment来实现这个效果就会有一个问题,那就如何做到多个Fragment的切换,这里介绍一下Fragment的俩种切换方式,
在Android中,Fragment的切换主要有两种方式:使用replace方法和使用hide/show方法。
replace方式 - 基本每次replace都会创建一次Fragment实例,
transaction.replace(R.id.fragnment, fragment1);
add-hide-show方式-
开发中教常用的一种方式,减少了不必要的开销`
transaction.add(R.id.fragnment, fragment1);
transaction.hide(fragment1);
transaction.show(fragment2);
俩种方法各有优劣,第一种方法它会将一个Fragment完全替换掉另一个Fragment,每次都会创建一个新的Fragement,销毁旧的Fragment,可能会浪费资源看起来第二个好像比第一个好,但是,看方法名字应该可以想到,第二个方法没有将Fargment 销毁,只是将其隐藏了起来而已,所以如果你有大量的Fragment需要切换,那么这些Fragment都会占用内存,可能会导致内存溢出。在实际开发还是根据实际需要选择合适的方法,
范例
只是这样说可能没有什么感觉无法理解,使用也不知道该如何使用,这里给出一个小的范例
这个demo中我会给出部分代码(所有代码观看体验并不太好),方便理解,所以
首先就是主活动布局,然后会给出一个Fragment及布局,最后就是核心的跳转,
主活动布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white2">
<LinearLayout
android:id="@+id/ll_tab"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal"
android:layout_alignParentBottom="true">
<LinearLayout
android:id="@+id/fragment1"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1"
android:layout_gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/thid1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/bottom1" />
</LinearLayout>
<LinearLayout
android:id="@+id/fragment2"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1"
android:layout_gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/thid2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/bottomht2"
/>
</LinearLayout>
<LinearLayout
android:id="@+id/fragment3"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1"
android:layout_gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/thid3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/bottom3"
/>
</LinearLayout>
<LinearLayout
android:id="@+id/fragment4"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1"
android:layout_gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/thid4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/bottomht4"
/>
</LinearLayout>
<LinearLayout
android:id="@+id/fragment5"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1"
android:layout_gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/thid5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/bottomht5"
/>
</LinearLayout>
</LinearLayout>
<FrameLayout
android:id="@+id/fl_Demo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/ll_tab"
>
</FrameLayout>
</RelativeLayout>
在这里并没有什么特殊的点,如果你想简单实现,你可以考虑将ImageView换成TextView,
Fragment及布局
public class Fragment1 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment1, null);
return view;
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是一个示例 Fragment1"
android:textSize="20sp"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="16dp" />
<Button
android:id="@+id/button_toast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="显示消息 1111" />
</LinearLayout>
俩个都是毫无特点
Fragment的跳转
//为了更好的理解删除了部分代码
public class MainActivity extends AppCompatActivity {
private LinearLayout m1;//五个按钮
private LinearLayout m2;
private LinearLayout m3;
private LinearLayout m4;
private LinearLayout m5;
private ImageView v1;
private ImageView v2;
private ImageView v3;
private ImageView v4;
private ImageView v5;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();//获取各个实例
initState();//初始化应用的初始状态
initEvent();//初始化视图的点击事件监听器
}
//获取各个实例
private void initView() {
m1 = findViewById(R.id.fragment1);
m2 = findViewById(R.id.fragment2);
m3 = findViewById(R.id.fragment3);
m4 = findViewById(R.id.fragment4);
m5 = findViewById(R.id.fragment5);
v1 = findViewById(R.id.thid1);
v2 = findViewById(R.id.thid2);
v3 = findViewById(R.id.thid3);
v4 = findViewById(R.id.thid4);
v5 = findViewById(R.id.thid5);
}
//初始化应用状态
private void initState() {
// 初始化
FragmentUtils.replaceFragment(MainActivity.this, R.id.fl_Demo,
new Fragment1());
}
//设置点击事件, checkState方法删除了,作用是处理点击更换图标的效果;
private void initEvent() {
m1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentUtils.replaceFragment(MainActivity.this, R.id.fl_Demo,
new Fragment1());
checkState(1);
}
});
m2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentUtils.replaceFragment(MainActivity.this, R.id.fl_Demo,
new Fragment2());
checkState(2);
}
});
m3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
bottomSheetDialog.show();
}
});
m4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentUtils.replaceFragment(MainActivity.this, R.id.fl_Demo,
new Fragment4());
checkState(4);
}
});
m5.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentUtils.replaceFragment(MainActivity.this, R.id.fl_Demo,
new Fragment5());
checkState(5);
}
});
}
}
可能你看完好没有找的我前面说的跳转相关API,反而多出了一个 FragmentUtils.replaceFragment 方法,下面就展示这个类中的内容
public class FragmentUtils {
public static void replaceFragment(FragmentActivity activity,int viewID,Fragment fragment){
activity.getSupportFragmentManager().beginTransaction().replace(viewID, fragment).commit();
}
public static void show(FragmentActivity activity, int viewID,Fragment fragment){
activity.getSupportFragmentManager().beginTransaction().add(viewID, fragment).show(fragment).commit();
}
public static void hide(FragmentActivity activity,Fragment fragment){
activity.getSupportFragmentManager().beginTransaction().hide(fragment).commit();
}
}
这几个方法的前面都是activity.getSupportFragmentManager().beginTransaction(),后面都是commit(), 先解释一下这个,
activity: 这是一个 FragmentActivity
对象,他是Activity
的一个子类,这个FragmentActivity
的实例通常是你当前正在进行操作的活动
getSupportFragmentManager(): 这是
FragmentActivity的一个方法,它返回一个
FragmentManager 对象。
FragmentManager是用来管理
Fragment 的
beginTransaction: 这是 FragmentManager
的一个方法,它返回一个 FragmentTransaction
对象。FragmentTransaction
代表了一系列的 Fragment
操作,这些操作会被组合到一起作为一个事务进行执行。通过 beginTransaction()
开始一个新的事务。
这里注意Fragment的操作(如添加、替换、隐藏、显示等)都是通过事务(Transaction)来完成的。事务可以理解为一系列的Fragment操作集合,这些操作要么全部执行,要么全部不执行,。
commit() :而在事务中的所有操作都需要在最后提交,这里调用commit()
方法来提交这个事务,提交事务就是让事务中的操作立即执行。如果事务没有被提交,那么事务中的操作就不会立即执行。这就是commit()
方法的作用。
在上面我们使用了第一种方法进行替换,现在使用第二种方法进行替换。
// 当需要显示 Fragment 时
FragmentUtils.show(MainActivity.this, R.id.fl_Demo,fragment1); // 显示 fragment1
FragmentUtils.hide(MainActivity.this, fragment2); // 隐藏 fragment2