Fragment
博客已经搬至掘金
碎片是什么
碎片是一种可以嵌入在活动当中的UI片段,它能让程序更加合理和充分地利用大屏幕的空间。
碎片的使用方式
碎片的简单用法
新建一个左侧碎片布局和一个右侧碎片布局。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="@color/purple_200"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="#00ff00"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello,world"
android:layout_gravity="center"/>
</LinearLayout>
接着新建两个类,继承fragment,并且重写onCreateView方法吗,分别引入左右布局。
package com.study.fragmenttest;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
public class LeftFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.left_fragment,container,false);
return view;
}
}
package com.study.fragmenttest;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
public class RightFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.right_fragment,container,false);
return view;
}
}
在Activity_Main.xml中引入这两个View
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="0dp"
android:id="@+id/left_fragment"
android:name="com.study.fragmenttest.LeftFragment"/>
<fragment
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/right_fragment"
android:name="com.study.fragmenttest.RightFragment"/>
</LinearLayout>
动态添加碎片
动态添加碎片也很简单。
先用FrameLayout替换fragment
由于只需要放一个碎片,不需要其他东西,因此用FrameLayout非常合适。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="0dp"
android:id="@+id/left_fragment"
android:name="com.study.fragmenttest.LeftFragment"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/right_layout"/>
</LinearLayout>
接着在创建一个Fragment和与其对应的xml用于体现动态添加。
AnotherRightFragment
package com.study.fragmenttest;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
public class AnotherRightFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.another_rightframe,container,false);
return view;
}
}
<?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:background="@color/black">
</LinearLayout>
在MainActivity中动态添加。
package com.study.fragmenttest;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button=findViewById(R.id.button);
//先将之前的Right碎片动态添加进去
replaceFragment(new RightFragment());
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//通过按钮触发另一个碎片的动态添加
replaceFragment(new AnotherRightFragment());
}
});
}
/*
替换碎片
*/
private void replaceFragment(Fragment rightFragment) {
//得到一个FragmentManager
FragmentManager fragmentManager=getSupportFragmentManager();
//开启一个事务
FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
//向容器中替换碎片
fragmentTransaction.replace(R.id.right_layout,rightFragment);
//提交事务
fragmentTransaction.commit();
}
}
在碎片中模拟返回栈
效果: 按下Back可以返回上一个被替换的碎片
添加一行代码即可
private void replaceFragment(Fragment rightFragment) {
//得到一个FragmentManager
FragmentManager fragmentManager=getSupportFragmentManager();
//开启一个事务
FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
//向容器中替换碎片
fragmentTransaction.replace(R.id.right_layout,rightFragment);
//addToBackStack的参数用来描述返回栈的状态
fragmentTransaction.addToBackStack(null);
//提交事务
fragmentTransaction.commit();
}
碎片和活动之间的通信
Activity得到Fragment
RightFragment rightFragment=(RightFragment)getSupportFragmentManager().findFragmentById(R.id.right_layout);
Fragment中获得Activity
MainActivity mainActivity=(MainActivity)getActivity();
Fragment中获得Fragment
可以用Activity作为中介。
碎片的生命周期
碎片的生命周期一共有11个。
onAttach: 于Activity建立关联
onCreate: 碎片被创建
onCreateView:碎片的视图被创建。
onActivityCreated: 当Activity被创建时。
onStart: 启动
onResume: 就绪
onPause: 暂停
onStop:停止
onDestroyView:碎片视图被破坏
onDestroy: 碎片被破坏。
onDetach: 解绑
当第一次创建加载到屏幕时会一直运行到onResume状态,当被替换掉时会到onDestroyView状态,当从返回栈出来时会重新到onCreateView状态。
动态加载布局的技巧
由于程序可以要运行在不同的设备上,所以需要设置不同的布局,然后在通过限定符来判别(如large)进行加载。还可以通过最小宽度限定符进行更加灵活的加载。