静态添加碎片
先新建两个文件:
可以看到多了两个文件:
删除TestFragment_1的其它内容,只保留onCreateView方法:
package com.example.fragmenttest_1;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class TestFragment_1 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_test_1, container, false);
}
}
fragment_test_1随便写个自己喜欢的布局:
fragment_test_1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="button1"
/>
<TextView
android:id="@+id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button1"
android:gravity="center_horizontal"
/>
</LinearLayout>
把activity_main改一下,加上fragment,这一步就是静态添加的意思,把自己写的fragment布局加到一个main布局里去。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<fragment
android:id="@+id/fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:name="com.example.fragmenttest_1.TestFragment_1"
/>
</LinearLayout>
运行一下:
运行过程应该是这样:MainActivity.java
加载activity_main.xml
,发现fragment
,回调TestFragment_1.java
中的onCreateView方法把fragment_test_1.xml
布局加载进来。
这种程序发现fragment
就自己去找的方式就是静态的,写死在activity_main.xml
中,程序运行后不可以控制什么时候去找。
动态添加碎片
和静态一样,创建两个文件,修改方法也一样。唯一不同的,先把activity_main.xml
的内容改成下面的:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<!--作为容器用-->
<FrameLayout
android:id="@+id/fragemnt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
></FrameLayout>
</LinearLayout>
这里把fragment
换成了FrameLayout
程序就不会找了,运行一下看看:
其实不是没去找了,因为FrameLayout(帧布局)中什么都没有,所以它在左上角却看不见。可以自己在里面加点东西,显然要加的是写好的碎片,在MainActivity.java
中去写:
package com.example.fragmenttest_2;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*管理fragment并将视图添加到activity的视图层级结构中*/
FragmentManager fm = getSupportFragmentManager();
/*找到布局中的fragment*/
Fragment fragment = fm.findFragmentById(R.id.fragemnt);
/*如果容器中什么都没有*/
if (fragment == null) {
/*得到一个Fragment子类*/
fragment = new FragmentTest_2();
fm.beginTransaction()
/*把fragment添加到容器里,显然这个容器应该是Fragment的*/
.add(R.id.fragemnt, fragment)
.commit();
/*然后就会自动回调Fragment子类的生命周期方法*/
}
//也可以这样写
/*获取FragmentManager*/
//FragmentManager fragmentManager = getSupportFragmentManager();
/*处理,开启一个事务*/
//FragmentTransaction transaction = fragmentManager.beginTransaction();
/*替换碎片*/
//transaction.replace(R.id.right_layout, fragment);
/*提交事务*/
//transaction.commit();
}
}
replace方法与add方法不同点在于:replace之前会先remove。
动态添加需要一个FrameLayout
容器,这个容器是定在xml
文件中的,而且这个xml
文件最后会被某一个Activity
调用,在这个Activity
中,可以使用Framgment
的一些方法来把写好的碎片加载进来,加载的时机可以自己确定,所以这是动态的。
优化
因为这种动态加载方法比较通用,可以单独写一个抽象类:
SingleFragmentActivity
package com.example.fragmenttest_2;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
public abstract class SingleFragmentActivity extends FragmentActivity {
protected abstract Fragment CreateFragment();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*管理fragment并将视图添加到activity的视图层级结构中*/
FragmentManager fm = getSupportFragmentManager();
/*找到布局中的fragment*/
Fragment fragment = fm.findFragmentById(R.id.fragemnt);
/*如果容器中什么都没有*/
if (fragment == null) {
/*得到一个Fragment子类*/
fragment = CreateFragment();
fm.beginTransaction()
/*把fragment添加到容器里,显然这个容器应该是Fragment的*/
.add(R.id.fragemnt, fragment)
.commit();
/*然后就会自动回调Fragment子类的生命周期方法*/
}
}
}
这里加载的Fragment子类是动态的,用一个抽象方法去获得。这个类继承自FragmentActivity
。
再把MainActivity
改一下其他的不动。
import androidx.fragment.app.Fragment;
public class MainActivity extends SingleFragmentActivity{
@Override
protected Fragment CreateFragment() {
return new FragmentTest_2();
}
}