深入解析:Android Studio新手开发第二十四天
2025-11-19 22:42 tlnshuju 阅读(0) 评论(0) 收藏 举报目录
碎片Fragment
Fragment(碎片)是 Android 中非常重要的组件,它代表 Activity 中的一部分行为或用户界面。它有自己的生命周期,但受宿主 Activity 影响而且能够被多个Activity重复使用。每个碎片都有对应的xml布局文件,它有两种使用方式:静态注册以及动态注册,两者的对比如下表所示。
| 静态注册 | 动态注册 | |
|---|---|---|
| 定义方式 | 在XML布局文件中使用<fragment>标签声明 | 在Java/Kotlin代码中使用FragmentTransaction操作 |
| 传参方式 | 困难。无法在布局中直接传递参数 | 方便。可通过Bundle和setArguments()方法传递参数 |
| 适用场景 | 界面固定不变的通用UI部件(如公共头部、底部) | 界面需要动态变化的情况(如标签页、ViewPager) |
| 灵活性 | 低。布局固定,难以在运行时替换 | 高。可在运行时灵活地添加、移除、替换碎片 |
碎片的静态注册
静态注册是指在xml文件中直接添加Fragment节点,可以看做是一个普通的控件能够被多个布局文件重复使用。该注册方式多用于界面固定不变的场景如广告条等,每个活动页面均可直接使用该部件。碎片除了与活动页面一样的基本生命周期方法onCreate、onStart、onStop、onResume、onPause、onDestroy之外还有五个生命周期方法,说明如下:
onAttach:与活动页面结合。
onCreateView:创建碎片视图。
onActivityCreated:在活动页面创建完毕后调用。
onDestroyView:回收碎片视图。
onDetach:与活动页面分离。
下面将展示静态注册的示例代码以及碎片生命周期。先右键依次选择New、Fragment新建一个Fragment,然后重写上述方法。
碎片的布局文件代码如下。
碎片的部分Java代码如下。
private final String TAG = "StaticRegisterFragment";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
Log.d(TAG, "onCreate");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d(TAG, "onCreateView");
return inflater.inflate(R.layout.fragment_static_register, container, false);
}
@Override
public void onAttach(@NonNull Context context) {
Log.d(TAG, "onAttach");
super.onAttach(context);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
Log.d(TAG, "onViewCreated");
super.onViewCreated(view, savedInstanceState);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.d(TAG, "onActivityCreated");
}
@Override
public void onStart() {
super.onStart();
Log.d(TAG, "onStart");
}
@Override
public void onResume() {
super.onResume();
Log.d(TAG, "onResume");
}
@Override
public void onPause() {
super.onPause();
Log.d(TAG, "onPause");
}
@Override
public void onStop() {
super.onStop();
Log.d(TAG, "onStop");
}
@Override
public void onDestroyView() {
super.onDestroyView();
Log.d(TAG, "onDestroyView");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
}
@Override
public void onDetach() {
super.onDetach();
Log.d(TAG, "onDetach");
}
页面布局文件代码如下,其中Fragment节点必须要有id以及Name的值为指定碎片的完整路径。
页面部分Java代码如下。
public class FragmentActivity extends AppCompatActivity {
private final String TAG = "FragmentActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);
Button button = findViewById(R.id.button_fragment);
TextView textView = findViewById(R.id.textView_fragment);
button.setOnClickListener(view -> {
Toast.makeText(FragmentActivity.this, "点击了碎片中的按钮!", Toast.LENGTH_SHORT).show();
textView.setText("点击了碎片中的按钮!");
imageView.setImageResource(R.drawable.image_2);
});
Log.d(TAG, "onCreate");
}
@Override
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart");
}
@Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause");
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume");
}
}
效果图如下,可以看到碎片能够正确显示,而且能够在页面的Java代码中获取碎片中的视图实例并做出操作,如给按钮添加监听器,修改文本视图的文本内容,更改图片视图的图片。


在Android Studio下方的Logcat能够看到碎片已经活动页面的部分生命周期。可以看到先加载碎片在加载这个页面。

碎片的动态注册
动态注册是在代码执行时才动态添加碎片。动态生成的碎片一般是给翻页视图使用。之前讲过翻页视图的数据适配器是PagerAdapter,但如果要结合使用碎片就需要使用另一种适配器FragmentPagerAdapter碎片适配器。该适配器增加了一个方法getItem用于获取指定位置的碎片同时去掉了三个方法,分别为isViewFromObject、instantiateItem与destroyItem。示例代码如下。
碎片的布局文件代码。
碎片的Java部分代码,主要看构造函数以及方法onCreateView。
public class DynamicRegisterFragment extends Fragment {
public DynamicRegisterFragment() {
// Required empty public constructor
}
private Context mContext;
private View mView;
private int position;
private int image_id;
// private int number;
private String number_english;
public static DynamicRegisterFragment newInstance(int position, int image_id, String number_english) {
DynamicRegisterFragment fragment = new DynamicRegisterFragment();
Bundle args = new Bundle();
args.putInt("position", position);
args.putInt("image_id", image_id);
args.putString("number_english", number_english);
fragment.setArguments(args);
return fragment;
}
private final String TAG = "DynamicRegisterFragment";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d(TAG, "onCreateView");
mContext = getActivity();
if(getArguments() != null){
image_id = getArguments().getInt("image_id");
position = getArguments().getInt("position");
number_english = getArguments().getString("number_english");
}
mView = inflater.inflate(R.layout.fragment_dynamic_register,container,false);
ImageView imageView = mView.findViewById(R.id.imageView_fragment);
TextView textView = mView.findViewById(R.id.textView_fragment);
Button button = mView.findViewById(R.id.button_fragment);
imageView.setImageResource(image_id);
textView.setText(number_english);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(mContext,String.format("点击了第%d个碎片中的按钮!",position+1),Toast.LENGTH_SHORT).show();
}
});
return mView;
}
@Override
public void onAttach(@NonNull Context context) {
Log.d(TAG, "onAttach");
super.onAttach(context);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
Log.d(TAG, "onViewCreated");
super.onViewCreated(view, savedInstanceState);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.d(TAG, "onActivityCreated");
}
@Override
public void onStart() {
super.onStart();
Log.d(TAG, "onStart");
}
@Override
public void onResume() {
super.onResume();
Log.d(TAG, "onResume");
}
@Override
public void onPause() {
super.onPause();
Log.d(TAG, "onPause");
}
@Override
public void onStop() {
super.onStop();
Log.d(TAG, "onStop");
}
@Override
public void onDestroyView() {
super.onDestroyView();
Log.d(TAG, "onDestroyView");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
}
@Override
public void onDetach() {
super.onDetach();
Log.d(TAG, "onDetach");
}
}
页面布局文件代码如下。
页面的部分Java代码如下,主要看碎片适配器的内容。
public class FragmentActivity extends AppCompatActivity {
private final String TAG = "FragmentActivity";
private int[] image_id = {R.drawable.one, R.drawable.two, R.drawable.three, R.drawable.four, R.drawable.five,
R.drawable.six, R.drawable.seven, R.drawable.eight, R.drawable.nine, R.drawable.zero};
private Integer[] number = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
private String[] number_english = {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "zero"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);
MyFragmentPagerAdapter myFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(),this,getList());
ViewPager viewPager = findViewById(R.id.viewPager);
viewPager.setAdapter(myFragmentPagerAdapter);
viewPager.setCurrentItem(1);
Log.d(TAG, "onCreate");
}
public List getList() {
List numberInfoList = new ArrayList();
for (int i = 0; i < number.length; i++) {
NumberInfo numberInfo = new NumberInfo(image_id[i],number[i],number_english[i]);
numberInfoList.add(numberInfo);
}
return numberInfoList;
}
class NumberInfo {
private int image_id;
private int number;
private String number_english;
public NumberInfo(int image_id,int number,String number_english){
this.image_id = image_id;
this.number = number;
this.number_english = number_english;
}
}
class MyFragmentPagerAdapter extends FragmentPagerAdapter{
private List numberInfoList;
private Context mContext;
public MyFragmentPagerAdapter(FragmentManager fragmentManager, Context context, List numberInfoList){
super(fragmentManager,BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
this.mContext = context;
this.numberInfoList = numberInfoList;
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return numberInfoList.get(position).number_english;
}
@NonNull
@Override
public Fragment getItem(int position) {
return DynamicRegisterFragment.newInstance(position,numberInfoList.get(position).image_id,numberInfoList.get(position).number_english);
}
@Override
public int getCount() {
return numberInfoList.size();
}
}
@Override
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart");
}
@Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause");
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume");
}
}
效果图如下,点击按钮有所反应。


动态注册碎片的生命周期如下。无论当前位于哪一页,系统只会加载当前页面以及左右两页,最多加载三页。这种方式可以节省系统资源,减少浪费,这是普通翻页视图所没有的。

浙公网安备 33010602011771号