Fragment生命周期的四种状态
Fragment和Activity类似,也存在运行状态、暂停状态、停止状态和销毁状态。
- 运行状态:当前Fragment位于前台展示,可见,可获取焦点。
- 暂停状态:其他Activity位于前台,该Fragment可见,不能获取焦点。
- 停止状态:当前Fragment不可见,失去焦点。
- 销毁状态:当前Fragment被删除,或所在Activity被结束。
Fragment的回调函数
Fragment为11个,与比Activity不同的有5个。分别为:
- onAttach():在片段已与 Activity 关联时调用(Activity 传递到此方法内)。
- onCreateView():调用它可创建与片段关联的视图层次结构。
- onActivityCreated():在 Activity 的 onCreate() 方法已返回时调用。
- onDestroyView():在移除与片段关联的视图层次结构时调用。
- onDetach():在取消片段与 Activity 的关联时调用。
与四种状态结合,如下图:
Fragment相当于Activity的一个片段,被包含在Activity中,一个Activity中可含有多个Fragment,一个Fragment也可以附属在多个Activity上Fragment也可包含Fragment。
结合Viewpage、TabLayout、RecyclerView实现多个Fragment的切换以及页面的滑动效果
以下为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"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<com.google.android.material.tabs.TabItem
android:id="@+id/tabItem_follow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="关注" />
<com.google.android.material.tabs.TabItem
android:id="@+id/tabItem_recommend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="推荐" />
<com.google.android.material.tabs.TabItem
android:id="@+id/tabItem_digital"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="数码" />
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager.widget.ViewPager
android:id="@+id/id_page_vp"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
以下为fragment_main.xml布局文件
<?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:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
android:id="@+id/close_comment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_marginBottom="375dp"
android:background="#0000"
android:visibility="gone"
tools:visibility="visible" />
<FrameLayout
android:id="@+id/comment_frameLayout"
android:layout_width="match_parent"
android:layout_height="375dp"
android:layout_alignParentBottom="true"
android:visibility="gone" />
</RelativeLayout>
以下为video_data.xml布局文件(RecyclerView所对应的一个item的布局文件)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/line4"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="15dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="51dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.example.testapp1.control.RoundImageButton
android:id="@+id/imageButton"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@drawable/cir1"
android:scaleType="fitXY" />
<com.example.testapp1.control.RoundImageButton
android:id="@+id/imageButton1"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_gravity="bottom|right"
android:background="@drawable/cir1" />
</FrameLayout>
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:text="某某某博主"
android:textSize="8pt" />
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="@+id/button4"
android:layout_width="50dp"
android:layout_height="30dp"
android:background="#00000000"
android:text="+关注"
android:textColor="@color/design_default_color_error"
android:textSize="6pt" />
<Button
android:id="@+id/button44"
android:layout_width="50dp"
android:layout_height="30dp"
android:background="#00000000"
android:text="已关注"
android:textColor="@android:color/darker_gray"
android:textSize="6pt"
android:visibility="invisible" />
</FrameLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dp"
android:ellipsize="end"
android:maxEms="13"
android:maxLines="2"
android:text="emmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm"
android:textColor="@color/black"
android:textSize="10pt" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/tv5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="25万次播放"
android:textSize="5pt" />
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="180dp">
<ImageButton
android:id="@+id/imageButton2"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="@mipmap/detail_sharebar_like"
android:visibility="visible" />
<ImageButton
android:id="@+id/imageButton22"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="@mipmap/detail_sharebar_likehighlighted"
android:visibility="invisible" />
</FrameLayout>
<TextView
android:id="@+id/tv3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="1dp"
android:text="22268"
android:textColor="@color/black"
android:textSize="6pt" />
<ImageButton
android:id="@+id/imageButton3"
android:layout_width="23dp"
android:layout_height="23dp"
android:layout_marginLeft="7dp"
android:background="@mipmap/comment_immersive_v4_5_white_big"
tools:src="@android:drawable/ic_menu_view" />
<TextView
android:id="@+id/tv6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="1dp"
android:text="268"
android:textColor="@color/black"
android:textSize="6pt" />
<ImageButton
android:id="@+id/imageButton4"
android:layout_width="23dp"
android:layout_height="23dp"
android:layout_marginLeft="7dp"
android:background="@mipmap/halo_share_icon"
tools:src="?attr/actionModeShareDrawable" />
</LinearLayout>
</LinearLayout>
<VideoView
android:id="@+id/video_view"
android:layout_width="match_parent"
android:layout_height="250dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_marginTop="10dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<VideoView
android:id="@+id/video_view1"
android:layout_width="match_parent"
android:layout_height="250dp"
android:layout_marginTop="25dp" />
</LinearLayout>
以下为MainActivity.java
public class MainActivity extends FragmentActivity {
private static final String TAG = "--MainActivity---甘---";
private List<Fragment> mFragmentList = new ArrayList<Fragment>();
private FragmentAdapter mFragmentAdapter;
private ViewPager mPageVp;
private FollowVideoFragment mFollowVideoFragment;
private RecommendVideoFragment mRecommendVideoFragment;
private DigitalVideoFragment mDigitalVideoFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "-----------onCreate-------------");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPageVp = this.findViewById(R.id.id_page_vp);
//绑定viewpage与TabLayout
TabLayout tabLayout = findViewById(R.id.tabs);
mPageVp.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mPageVp));
init();
}
private void init() {
mFollowVideoFragment = new FollowVideoFragment();
mRecommendVideoFragment = new RecommendVideoFragment();
mDigitalVideoFragment = new DigitalVideoFragment();
mFragmentList.add(mFollowVideoFragment);
mFragmentList.add(mRecommendVideoFragment);
mFragmentList.add(mDigitalVideoFragment);
mFragmentAdapter = new FragmentAdapter(this.getSupportFragmentManager(), mFragmentList);
mPageVp.setAdapter(mFragmentAdapter);
mPageVp.setCurrentItem(1);
}
@Override
protected void onStart() {
super.onStart();
Log.i(TAG, "-----------onStart-------------");
}
@Override
protected void onRestart() {
super.onRestart();
Log.i(TAG, "-----------onRestart-------------");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG, "-----------onResume-------------");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "-----------onPause-------------");
}
@Override
protected void onStop() {
super.onStop();
Log.i(TAG, "-----------onStop-------------");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "-----------onDestroy-------------");
}
}
以下为FollowVideoFragment.java
public class FollowVideoFragment extends Fragment {
private static final String TAG = "--FollowVideoFragment---甘---";
@Override
public void onAttach(@NonNull Context context) {
Log.i(TAG,"--------onAttach---------");
super.onAttach(context);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
Log.i(TAG, "--------onCreate---------");
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.i(TAG, "--------onCreateView---------");
super.onCreateView(inflater, container, savedInstanceState);
View videoView = inflater.inflate(R.layout.fragment_main, container, false);
//此处通过RecyclerView实现页面的滑动效果
RecyclerView recyclerView = videoView.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(videoView.getContext());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
return videoView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
Log.i(TAG, "--------onActivityCreated---------");
super.onActivityCreated(savedInstanceState);
}
@Override
public void onStart() {
Log.i(TAG, "--------onStart---------");
super.onStart();
}
@Override
public void onResume() {
Log.i(TAG, "--------onResume---------");
super.onResume();
}
@Override
public void onPause() {
Log.i(TAG, "--------onPause---------");
super.onPause();
}
@Override
public void onStop() {
Log.i(TAG, "--------onStop---------");
super.onStop();
}
@Override
public void onDestroyView() {
Log.i(TAG, "--------onDestroyView---------");
super.onDestroyView();
}
@Override
public void onDestroy() {
Log.i(TAG, "--------onDestroy---------");
super.onDestroy();
}
@Override
public void onDetach() {
Log.i(TAG, "--------onDetach---------");
super.onDetach();
}
其他两个Fragment的代码和FollowVideoFragment几乎一样,此处不在列出。此处三个Fragment对应同一Adapter(适配器),每一个Fragment都要有与其对应的适配器。本人在Adapter后还建立了holder用于对应一个item的绑定数据。
VideoAdapter.java
public class VideoAdapter extends RecyclerView.Adapter<VideoViewHolder> {
private List<BaseData> dataList;
private Context mContext;
public VideoAdapter(List<BaseData> list, Context context) {
dataList = list;
mContext = context;
}
//为RecyclerView的item创建view
@Override
public VideoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View viewVideo = LayoutInflater.from(parent.getContext()).inflate(R.layout.video_data, parent, false);
VideoViewHolder videoViewHolder = new VideoViewHolder(viewVideo, mContext);
return videoViewHolder;
}
//为item绑定数据
@Override
public void onBindViewHolder(VideoViewHolder holder, int position) {
holder.bindData(dataList.get(position));
}
@Override
public int getItemCount() {
return dataList.size();
}
}
VideoViewHolder.java,因本人demo的实体类数据不同且需放同一list中,并为绑定数据方便,实现多态,封装了一个BaseHolder的方法,读者可将继承改为RecyclerView.ViewHolder
public class VideoViewHolder extends RecyclerView.ViewHolder<VideoData> {
private VideoView videoView;
TextView personName;
//RoundImageButton与RoundImageButton是自定义控件
RoundImageButton personHeadId;
RoundImageButton personLevelid;
TextView personIntroduction;
TextView videoNumber;
TextView goodNumber;
TextView commentNumber;
VideoView video1;
VideoView video2;
RecyclerView recyclerView;
private Context mContext;
@Override
public void bindData(VideoData videoData) {
personName.setText(videoData.getName());
personHeadId.setImageResource(videoData.getHeadId());
personLevelid.setImageResource(videoData.getLevelId());
personIntroduction.setText(videoData.getIntroduction());
videoNumber.setText(videoData.getVideoNumber());
goodNumber.setText(videoData.getGoodNumber());
commentNumber.setText(videoData.getCommentNumber());
itemView.findViewById(R.id.imageButton4).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(view.getContext(), NextActivity.class);
view.getContext().startActivity(intent);
}
});
}
public VideoViewHolder(View view, Context mContext) {
super(view);
this.mContext = mContext;
personName = view.findViewById(R.id.tv1);
personHeadId = view.findViewById(R.id.imageButton);
personLevelid = view.findViewById(R.id.imageButton1);
personIntroduction = view.findViewById(R.id.tv4);
videoNumber = view.findViewById(R.id.tv5);
goodNumber = view.findViewById(R.id.tv3);
commentNumber = view.findViewById(R.id.tv6);
video1 = view.findViewById(R.id.video_view);
video2 = view.findViewById(R.id.video_view1);
recyclerView = view.findViewById(R.id.recycler_view1);
}
}
tips:以上代码可能有些绕,简单来说就是Activity包含Fragment,又因为想实现滑动效果,Fragment中包含了RecyclerView,Adapter作为适配器为RecyclerView创建item对应的view并可绑定数据(holder的代码可以放入其中),holder为item绑定数据。
通过打Log观察一个或多个Fragment的生命周期变化
一个Fragment
- 运行app:
- 按home键:
- 锁屏:
- 按返回键:
多个Fragment
- tablayout中默认选中中间的Fragment,此时运行APP:
- 滑动至FollowVideoFragment:
- 从FollowVideoFragment滑动至RecommendVideoFragment再滑动至DigitalVideoFragment:
- 在DigitalVideoFragment进行home键操作:
- 回到APP,在DigitalVideoFragment再进行锁屏键操作:
- 解锁,再按back键:
Activity的Fragment和另一个Activity之间的切换观察Fragment的生命周期
三个Fragment的生命周期变化:
MainActivity与另一个Activity的变化:
tips:Viewpage、TabLayout、RecyclerView将在笔者后续博客中。