一、Fragment简介:
- Fragment可以说是轻量级的Activity,是Android3.0新增的概念。
- Fragment不能独立存在,必须嵌入到Activity中,一个Activity可以嵌入多个Fragment。
- Fragment具有自己的生命周期,接收它自己的事件,并可以在Activity运行时被添加或删除。
- Fragment的生命周期直接受所在的Activity的影响。如:当Activity暂停时,它拥有的所有Fragment们都暂停。
二、Fragment生命周期:
onAttach(Context context)//fragment附加到Activity时调用,context就是当前的Activity的对象
onCreate()//系统创建Fragment对象后回调该方法,实现代码中只初始化想要在Fragment中保持的必要控件,当Fragment被暂停或者停止后可以恢复。
onCreateView()//当Activity要得到Fragment的layout时,会回调该方法,Fragment在其中创建自己的layout界面。该方法必须返回一个View,该View也就是该Fragment要显示的view。
onActivityCreated()//当Fragment所在的Activity被启动完成后回调该方法。
onStart()//启动Fragment时被回调
onResume()//Fragment进入前台获得焦点时被回调,onStart()方法后一定会回调onResume()方法。
onPause()//暂停该Fragment时将会回调该方法。
onStop()//停止Fragment时被回调
onDestroyView()//销毁该Fragment所包含的View时被调用。
onDestroy()//销毁该Fragment。
onDetach()//将该Fragment从Activity中解除关联。onDestroy方法一定会回调onDetach()方法。
三、Fragment的创建:
关于LayoutInflater解析器:
是一个用于加载布局的系统服务,将xml布局文件创建成一个view对象。
LayoutInflater不能直接使用,获取LayoutInflater实例对象的三种方法:
LayoutInflater inflater1 = LayoutInflater.from(this);
LayoutInflater inflater2 = getLayoutInflater();
LayoutInflater inflater3 = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
方法一:静态创建Fragment:
第一步:创建Fragment的子类,实现onCreateView方法
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
return inflater.inflate(R.layout.fragment,container,false);
//第一个参数:要引入的布局文件的ID,在这里是Fragment对应的布局文件
//第二个参数:该布局对应的父布局container
//第三个参数:是否将该布局放到作为父布局container中。true表示该布局是附着在container中的,返回父布局的view,false表示该布局不附着在container中,返回第一个参数对应的布局。
}
//第一个参数:LayoutInflater:获取layout布局文件,将布局文件实例化
//第二个参数:container是将你的fragment layout插入的activity layout中的父ViewGroup
//第三个参数:savedInstanceState是一个Bundle,如果Fragment是被恢复的,它提供Fragment之前的实例的数据。
第二步:在layout文件夹下建该Fragment对应的布局文件,并在第一步中引入布局
第三步:将Fragment加入对应Activity的XML布局文件
<fragment
android:name="com.example.MyFragment"
android:id="@+id/frag1"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!--name就是我们的fragment类-->
方法二:动态创建Fragment:
第一步:创建Fragment的子类,实现onCreateView方法
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View view = inflater.inflate(R.layout.fragment,container,false);
return view;
//第一个参数:要引入的布局文件的ID,在这里是Fragment对应的布局文件
//第二个参数:该布局对应的父布局container
//第三个参数:是否将该布局放到作为父布局container中。true表示该布局是附着在container中的,返回父布局的view,false表示该布局不附着在container中,返回第一个参数对应的布局。
}
//第一个参数:LayoutInflater:获取layout布局文件,将布局文件实例化
//第二个参数:container是将你的fragment layout插入的activity layout中的父ViewGroup
//第三个参数:savedInstanceState是一个Bundle,如果Fragment是被恢复的,它提供Fragment之前的实例的数据。
第二步:在layout文件夹下建该Fragment对应的布局文件,并在第一步中引入布局
第三步:在Activity的XML布局文件中创建一个带id的布局管理器,用于动态创建Fragment时容纳Fragment
<LinearLayout
android:id="@+id/layout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
第四步:在Activity里动态创建Fragment
注意:Activity需要继承FragmentActivity
//第一步:创建Fragment的实例对象
Fragment fragment = new Fragment();
//第二步:调用activity的getSupportFragmentManager()获取FragmentManager对象
普通版本使用:FragmentManager fragmentManager = getSupportFragmentManager();
高版本使用:FragmentManager fragmentManager = getFragmentManager();
//第三步:获取FragmentTrasction对象
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
//第四步:FragmentTrasction对象调用需要执行的方法add()、replace()、remove()
fragmentTransaction.add(R.id.layout1,fragment);
//第五步:FragmentTrasction对象调用commit()方法提交事务到Activity
fragmentTransaction.commit();
关于add()、replace()、remove()方法添加、修改、移除Fragment:
/*
1.replace方法用于修改Fragment:
public FragmentTransaction replace(int containerViewId, Fragment fragment)
第一个参数Activity里用于容纳Fragment的layout标签的ID
第二个参数是新的Fragment对象
调用replace方法会将布局管理器中加载的Fragment替换,原来的Fragment会被移除。
2.add方法用于修改Fragment:
public FragmentTransaction add(int containerViewId, Fragment fragment)
第一个参数Activity里用于容纳Fragment的layout标签的ID
第二个参数是Fragment对象
3.addToBackStack方法类似add方法:
如果多次往一个布局管理器中调用addToBackStack方法添加多个Fragment,
布局管理器会形成一个类似栈的结构,先进先出,
新添加的Fragment会覆盖掉原有的Fragment,
如果点击屏幕下面的返回按钮,会执行出栈操作,
当前页面加载的的Fragment对象会被移出栈,位于栈顶的Fragment对象会被加载到页面上。
*/
四、案例:多Fragment的使用:
效果图:
1.首先创建Activity:
package com.example.t.androidproject.test;
import androidx.annotation.RequiresApi;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity2 extends FragmentActivity {
EditText search;
LinearLayout frame;
Button dialog;
Button people;
Button set;
TextView top;
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
search = findViewById(R.id.srearch);
frame = findViewById(R.id.frame);
dialog = findViewById(R.id.dialog);
people = findViewById(R.id.people);
set = findViewById(R.id.set);
top = findViewById(R.id.top);
Fragment1 fragment1 = new Fragment1();
Fragment2 fragment2 = new Fragment2();
Fragment3 fragment3 = new Fragment3();
dialog.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame,fragment1);
top.setText(dialog.getText());
dialog.setBackgroundColor(getResources().getColor(R.color.gray3));
people.setBackgroundColor(getResources().getColor(R.color.gray));
set.setBackgroundColor(getResources().getColor(R.color.gray));
fragmentTransaction.commit();
}
});
people.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame,fragment2);
top.setText(people.getText());
dialog.setBackgroundColor(getResources().getColor(R.color.gray));
people.setBackgroundColor(getResources().getColor(R.color.gray3));
set.setBackgroundColor(getResources().getColor(R.color.gray));
fragmentTransaction.commit();
}
});
set.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame,fragment3);
top.setText(set.getText());
dialog.setBackgroundColor(getResources().getColor(R.color.gray));
people.setBackgroundColor(getResources().getColor(R.color.gray));
set.setBackgroundColor(getResources().getColor(R.color.gray3));
fragmentTransaction.commit();
}
});
}
}
2.Activity布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:orientation="vertical"
android:layout_height="match_parent"
android:layout_width="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/blue">
<TextView
android:id="@+id/top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textSize="30sp"
android:textColor="@color/gray2"
android:text="会话"/>
</androidx.appcompat.widget.Toolbar>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="@color/gray">
<EditText
android:id="@+id/srearch"
android:layout_width="400dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:background="@color/white"
android:drawableLeft="@drawable/ic_baseline_search_24"
android:gravity="center_vertical"
android:hint="搜索"
android:textColor="@color/gray2"
android:textSize="20sp" />
</FrameLayout>
<LinearLayout
android:id="@+id/frame"
android:background="@color/gray"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical"></LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:orientation="horizontal">
<Button
android:id="@+id/dialog"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:drawableTop="@drawable/ic_baseline_question_answer_24"
android:text="会话"
android:textSize="20sp"
android:gravity="center"
android:textColor="@color/black"/>
<Button
android:id="@+id/people"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:drawableTop="@drawable/ic_baseline_people_24"
android:text="通讯录"
android:textSize="20sp"
android:gravity="center"
android:textColor="@color/black"/>
<Button
android:id="@+id/set"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:drawableTop="@drawable/ic_baseline_reorder_24"
android:gravity="center"
android:text="设置"
android:textColor="@color/black"
android:textSize="20sp" />
</LinearLayout>
</LinearLayout>
3.ListView单行布局文件:
<?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="horizontal"
android:background="@color/white"
android:layout_marginBottom="10dp">
<ImageView
android:id="@+id/img"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginTop="15dp"
android:src="@color/gray"/>
<LinearLayout
android:layout_marginTop="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/text1"
android:layout_width="80dp"
android:layout_height="20dp"/>
<TextView
android:id="@+id/text2"
android:layout_width="80dp"
android:layout_height="20dp"
android:layout_marginTop="5dp"/>
</LinearLayout>
<TextView
android:layout_marginTop="15dp"
android:id="@+id/time"
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_weight="1"
android:gravity="right"/>
</LinearLayout>
4.创建三个Fragment:
Fragment1类:
package com.example.t.androidproject.test;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Fragment1 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_1, container, false);
//获取ListView
ListView listview1 = view.findViewById(R.id.listview);
//获取数据list(map())
List list = new ArrayList();
Map<String,Object> map1 = new HashMap();
map1.put("1","江南");
map1.put("2","[语音]");
map1.put("3","上午11:00");
map1.put("4",R.drawable.ic_baseline_people_24);
list.add(map1);
Map<String,Object> map2 = new HashMap();
map2.put("1","江北");
map2.put("2","你好");
map2.put("3","上午10:30");
map2.put("4",R.drawable.ic_baseline_people_24);
list.add(map2);
Map<String,Object> map3 = new HashMap();
map3.put("1","江西");
map3.put("2","/doge");
map3.put("3","上午8:00");
map3.put("4",R.drawable.ic_baseline_people_24);
list.add(map3);
SimpleAdapter adapter = new SimpleAdapter(this.getActivity(), list, R.layout.one, new String[]{"1","2","3","4"}, new int[]{R.id.text1, R.id.text2, R.id.time,R.id.img});
//ListView绑定适配器对象
listview1.setAdapter(adapter);
return view;
}
}
Fragment1的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Fragment1">
<!-- TODO: Update blank fragment layout -->
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
Fragment2类:
package com.example.t.androidproject.test;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
public class Fragment2 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_2, container, false);
}
}
Fragment2的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="222222"
android:textSize="50sp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Fragment3类:
package com.example.t.androidproject.test;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
public class Fragment3 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_3, container, false);
}
}
Fragment3的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="3333333"
android:textSize="50sp"/>
</androidx.constraintlayout.widget.ConstraintLayout>