需求
从一个activity进入到第二个activity里面,我会传一个值(值为1,2,3,4),第二个activity里面有四个fragment,当接收到第一个activity传的值(1,2,3,4)后,会自动加载对应的fragment.
实现
1.在 MainActivity 中启动 SecondActivity 并传递一个值:
// 启动 SecondActivity 并传递一个值
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtra("value", 3);
startActivity(intent);
2.在 SecondActivity 中接收传递过来的值:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
// 接收传递过来的值
int value = getIntent().getIntExtra("value", 0);
loadFragment(value);
}
3.定义一个 loadFragment() 方法用于加载对应的 Fragment:
private void loadFragment(int value) {
Fragment fragment = null;
switch (value) {
case 1:
fragment = new Fragment1();
break;
case 2:
fragment = new Fragment2();
break;
case 3:
fragment = new Fragment3();
break;
case 4:
fragment = new Fragment4();
break;
default:
return;
}
// 加载对应的 Fragment
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, fragment)
.commit();
}
在 loadFragment() 方法中,我们根据传递过来的值选择对应的 Fragment,然后使用 replace() 方法将其替换掉 activity_second.xml 布局文件中的 FrameLayout 容器,并通过 commit() 方法提交更改。
需要注意的是,我们在 switch 语句中加了一个 default 分支,如果传递过来的值不是1、2、3或4,则直接返回,这可以避免加载不必要的 Fragment。
OVER???
还没有
接下来看看xml布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">
<fragment
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
有问题没????
如果就这样使用的话,就会报错
Caused by: android.view.InflateException: Binary XML file line xxxxxxxx Error inflating class fragment
???
Error inflating class fragment
是一个常见的错误,通常会在使用 <fragment>
标签时出现。它的含义是无法创建 Fragment 类的实例
,因此出现了错误。
这个错误可能的原因如下:
1.忘记在 AndroidManifest.xml 文件中注册 Fragment 类。
2.在 标签中使用了无效或错误的 android:name 属性。
3.Fragment 类的构造函数抛出了异常,导致实例无法创建。
4.Fragment 类依赖的资源文件、主题或其他内容无法加载或不存在。
针对第 1 种情况,可以在 AndroidManifest.xml 文件中为你的 Fragment 类添加 标记,并使用 android:name 属性来指定其类名。例如:
<activity
android:name=".YourFragmentClass" />
对于第 2 种情况,你需要确保使用了正确的类名。如果你使用的是 Kotlin,类名可能包含有其它字符,例如 $。此时,你还需要注意要对类名进行反引号括起来,例如:
<fragment
android:name="com.example.yourapp.YourFragmentClass$InnerClass"
... />
针对第 3 和第 4 种情况,你需要检查代码并确保没有抛出异常或错误。同时,你还需要检查项目的资源文件、主题和其他内容是否存在或有效。
所以为什么报错?
Fragment 布局是专门为 Fragment 定义的一种布局方式,它与普通布局有所不同。在使用 Fragment 布局时,我们使用<fragment>
标签来声明 Fragment,例如:
<fragment
android:name="com.example.MyFragment"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
这里,我们使用了 android:name 属性
来指定要显示的 Fragment 的类名,使用 android:id 属性来设置该 Fragment 的 ID。Fragment 布局只能放置一个 Fragment
,而不能包含其他 View。
我们的需求是什么?
是动态替换Fragment,这样就代表我们是要有4个Fragment
的。
问题解决
在 Android 中,FrameLayout 是常规布局容器之一,可以用来放置一个或多个 View 或 Layout。它只会显示其中的一个子 View,而其他子 View 会被隐藏。
如果你想在一个布局中动态替换多个 Fragment,建议使用 FrameLayout,因为它具有更大的灵活性和可替换性。你可以在一个 FrameLayout 中动态地添加、替换、移除多个 Fragment,而无需修改布局文件。
所以
我们的布局应该是
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".ui.DataInfoActivity">
<!--把这个fragment替换成FrameLayout-->
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>