Fragment必须嵌入在Activity中使用,因此,虽然Fragment有自己的生命周期,但会受它所在的Activity的生命周期的控制
在MainActivity中使用Fragment
①创建fragment
创建一个普通的fragment
创建完毕后会自动生成对应的xml布局
②修改BlankFragment.java
删掉其中无用的代码
删除完毕后
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import android.os.Bundle; import androidx.fragment.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup;
public class BlankFragment extends Fragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); }
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_blank, container, false); } }
|
优化onCreateView
1 2 3 4 5 6 7 8 9 10
| private View root; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (root == null){ root = inflater.inflate(R.layout.fragment_blank,container,false); } return root; }
|
③修改两个Fragment的布局
BlankFragment1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <?xml version="1.0" encoding="utf-8"?> <LinearLayout android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" android:gravity="center_horizontal" xmlns:android="http://schemas.android.com/apk/res/android"> <TextView android:text="BlankFragment1" android:textSize="20sp" android:textColor="@color/black" android:textStyle="bold" android:id="@+id/blankFragmentText" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <Button android:text="按钮" android:id="@+id/blankFragmentButton" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>
|
BlankFragment2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <?xml version="1.0" encoding="utf-8"?> <LinearLayout android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" android:gravity="center_horizontal" xmlns:android="http://schemas.android.com/apk/res/android"> <TextView android:text="BlankFragment2" android:textSize="20sp" android:textColor="#ff0033" android:textStyle="bold" android:id="@+id/blankFragmentText2" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <Button android:text="按钮" android:id="@+id/blankFragmentButton2" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>
|
④添加至MainActivity布局
打开MainActivity的布局资源文件activity_main.xml,在其中插入fragment
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| <?xml version="1.0" encoding="utf-8"?> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android"> <Button android:text="replaceFragment1" android:textAllCaps="false" android:id="@+id/replaceFragment1" android:layout_alignParentBottom="true" android:layout_marginBottom="60dp" android:layout_width="wrap_content" android:layout_marginLeft="20dp" android:layout_height="wrap_content"/> <Button android:text="replaceFragment2" android:textAllCaps="false" android:id="@+id/replaceFragment2" android:layout_marginRight="20dp" android:layout_marginBottom="60dp" android:layout_alignParentRight="true" android:layout_alignParentBottom="true" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <FrameLayout android:background="#ccffcc" android:id="@+id/frameLayout1" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/linearLayout1" android:orientation="vertical">
<fragment android:id="@+id/mainActivityFragment1" android:name="com.a.fragment.BlankFragment1" android:layout_width="match_parent" android:layout_weight="1" android:layout_height="match_parent"/> <fragment android:id="@+id/mainActivityFragment2" android:name="com.a.fragment.BlankFragment2" android:layout_width="match_parent" android:layout_weight="1" android:layout_height="match_parent"/> </LinearLayout> </FrameLayout> </RelativeLayout>
|
1. 插入在activity_main.xml中的fragment一定要有id
2. 插入在activity_main.xml中的fragment一定要有name(BlankFragment的完整类名)属性
给fragment添加事件
fragment首次绘制界面时调用onCreateView,所以可以在onCreateView下写代码
给BlankFragment的按钮写事件(两个fragment一样的)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| import android.os.Bundle; import androidx.fragment.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.TextView;
public class BlankFragment1 extends Fragment implements View.OnClickListener{ private View root; private TextView blankFragmentText; private Button blankFragmentButton; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); }
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (root == null){ root = inflater.inflate(R.layout.fragment_blank1,container,false); } blankFragmentButton = root.findViewById(R.id.blankFragmentButton); blankFragmentText = root.findViewById(R.id.blankFragmentText);
blankFragmentButton.setOnClickListener(this); return root; }
@Override public void onClick(View v) { blankFragmentText.setText("Welcome BlankFragment1"); } }
|
③效果
MainActivity页显示两个Fragment互不影响(两个Fragment甚至可以来自同一个BlankFragment.java,即name属性都为com.a.fragment.BlankFragment1)
动态添加fragment
在动态添加fragment前一定要搞懂FragmentManager类
①两种fragment
fragment分为app包内的fragment和v4包内的fragment
二者在使用上的区别:
- app包中的fragment兼容自3.0起以后的版本,v4包中的fragment可以兼容到1.6的版本
- app.fragment使用标签时。v4.fragment使用标签时,当这个Activity的布局中有标签,必须,如果不继成FragmentActivity的话 编译系统会把认为是app包中的Fragment来处理。但是此时我们导入的是v4包中的Fragment,所以会报错
- 对应的是v4包,对应的是app包
在3.0版本之前使用fragment需借助V4包的getSupportFragmentManager()方法来间接获取FragmentManager()对象,3.0版本之后,可以通过Fragment的api直接使用getFragmentManager()方法获取FragmentManager()对象
为什么我的MainActivity布局中使用v4的fragment,却继承AppCompatActivity而不是FragmentActivity?
因为AppCompatActivity继承FragmentActivity,这样的话,MainActivity -继承-> AppCompatActivity -继承-> FragmentActivity
Android studio创建MainActivity自动extends AppCompatActivity,为什么不extends Activity
AppCompatActivity继承v4包的FragmentAvtivity,并且加入了很多新特性,可以更好的兼容旧系统
②FragmentManager(Fragment的管理)
- 顾名思义FragmentManager是Fragment的管理类
- getSupportFragmentManager()获取所在fragment 的父容器的管理器(getFragmentManager()同理)
- getSupportFragmentManager()或者getFragmentManager()获得FragmentManager对象, 可以认为Activity是FragmentManager的宿主环境类
1 2 3 4 5 6 7 8 9 10 11
| FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frameLayout, fragment);
fragmentTransaction.commit();
|
③动态添加
1、创建至MainActivity
1 2 3 4 5 6 7 8
| FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frameLayout1,fragment);
fragmentTransaction.commit();
|
2、fragment入栈
在FragmentManager.transaction.addToBackStack();向栈中添加Fragment,从而实现添加Fragment后,可以实现按返回键依次返回上个Fragment
1 2
| fragmentTransaction.addToBackStack(null);
|
3、完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.FrameLayout; import android.widget.LinearLayout;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private Button replaceFragment1,replaceFragment2; private FrameLayout frameLayout1; private LinearLayout linearLayout1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
replaceFragment1 = findViewById(R.id.replaceFragment1); replaceFragment2 = findViewById(R.id.replaceFragment2); frameLayout1 = findViewById(R.id.frameLayout1); linearLayout1 = findViewById(R.id.linearLayout1);
replaceFragment1.setOnClickListener(this); replaceFragment2.setOnClickListener(this); }
@Override
public void onClick(View v) {
linearLayout1.setVisibility(View.GONE); switch (v.getId()){
case R.id.replaceFragment1:
BlankFragment1 blankFragment1 = new BlankFragment1(); setReplaceFragment(blankFragment1); break;
case R.id.replaceFragment2:
BlankFragment2 blankFragment2 = new BlankFragment2(); setReplaceFragment(blankFragment2); break; } }
private void setReplaceFragment (Fragment fragment){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frameLayout1,fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit(); } }
|
Fragment入栈后在回退时可以一个一个的返回
fragment的数据传递
fragment数据传递分三种模式,即
- Activity向Fragment传递数据(Activity发送,Fragment接收)
- Fragment向Activity传递数据(Fragment发送,Activity接收)
- Fragment向Fragment传递数据
①原生Bundle传递数据
Bundle传递的数据,是以key-value(键值对)的形式存在的;传递的数据可以是boolean、byte、int、long、float、double、string等基本类型或它们对应的数组,也可以是对象或对象数组;当Bundle传递的是对象或对象数组时,必须实现Serializable 或Parcelable接口
传递基本类型
在MainActivity中发送
1 2 3 4 5 6 7 8 9 10
| Bundle bundle = new Bundle();
bundle.putString("message1","Bundle方式传递的数据");
BlankFragment1 blankFragment1 = new BlankFragment1();
blankFragment1.setArguments(bundle);
setReplaceFragment(blankFragment1);
|
在Fragment中接收
1 2 3 4 5 6
| Bundle bundle = this.getArguments();
String msg = bundle.getString("message");
Toast.makeText(getActivity(),msg,Toast.LENGTH_SHORT).show();
|
写入MainActivity和Fragment
先去删掉activity_main中FrameLayout的LinearLayout
MainActivity
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| 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; import android.widget.FrameLayout;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private Button replaceFragment1,replaceFragment2; private FrameLayout frameLayout1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
replaceFragment1 = findViewById(R.id.replaceFragment1); replaceFragment2 = findViewById(R.id.replaceFragment2); frameLayout1 = findViewById(R.id.frameLayout1);
replaceFragment1.setOnClickListener(this); replaceFragment2.setOnClickListener(this); }
@Override
public void onClick(View v) {
Bundle bundle = new Bundle(); switch (v.getId()){
case R.id.replaceFragment1: BlankFragment1 blankFragment1 = new BlankFragment1();
blankFragment1.setArguments(bundle);
bundle.putString("message1","Bundle方式向BlankFragment1传递的数据"); setReplaceFragment(blankFragment1); break;
case R.id.replaceFragment2: BlankFragment2 blankFragment2 = new BlankFragment2();
blankFragment2.setArguments(bundle);
bundle.putString("message1","Bundle方式向BlankFragment2传递的数据"); setReplaceFragment(blankFragment2); break; } }
private void setReplaceFragment (Fragment fragment){ FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.replace(R.id.frameLayout1,fragment); fragmentTransaction.addToBackStack(null); fragmentTransaction.commit(); } }
|
两个BlankFragment类似
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| import android.os.Bundle; import androidx.fragment.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.TextView; import android.widget.Toast;
public class BlankFragment1 extends Fragment implements View.OnClickListener{ private View root; private TextView blankFragmentText; private Button blankFragmentButton; private String msg;
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
Bundle bundle = this.getArguments();
msg = bundle.getString("message1"); Toast.makeText(getActivity(),msg,Toast.LENGTH_SHORT).show(); }
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (root == null){ root = inflater.inflate(R.layout.fragment_blank1,container,false); } blankFragmentButton = root.findViewById(R.id.blankFragmentButton); blankFragmentText = root.findViewById(R.id.blankFragmentText); blankFragmentButton.setOnClickListener(this); return root; }
@Override public void onClick(View v) { blankFragmentText.setText("Welcome BlankFragment1"); } }
|
②使用接口传递数据
创建接口
1 2 3 4
| public interface CallBack { String getMessage(); void sendMessage(String msg); }
|
BlankFragment中
1、让BlankFragment再继承一个OnLongClickListener,使单击时从MianActivity获取,长按时向MainActivity发送
2、用接口定义变量,并创建setCallBack方法供MainActivity调用
1 2 3 4 5 6
| private CallBack callBack;
public void setCallBack(CallBack callBack){ this.callBack = callBack; }
|
3、按钮单击时获取
1 2
| String str = callBack.getMessage(); Toast.makeText(getActivity(),"BlankFragment1:" + str,Toast.LENGTH_SHORT).show();
|
4、按钮长按时发送
1 2
| callBack.sendMessage("BlankFragment1发送的数据"); return true;
|
BlankFragment1.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| import android.os.Bundle; import androidx.fragment.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.TextView; import android.widget.Toast;
public class BlankFragment1 extends Fragment implements View.OnClickListener,View.OnLongClickListener{ private View root; private TextView blankFragmentText; private Button blankFragmentButton; private String msg;
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
Bundle bundle = this.getArguments();
msg = bundle.getString("message1"); Toast.makeText(getActivity(),msg,Toast.LENGTH_SHORT).show(); }
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (root == null){ root = inflater.inflate(R.layout.fragment_blank1,container,false); } blankFragmentButton = root.findViewById(R.id.blankFragmentButton); blankFragmentText = root.findViewById(R.id.blankFragmentText);
blankFragmentButton.setOnClickListener(this); blankFragmentButton.setOnLongClickListener(this); return root; }
private CallBack callBack;
public void setCallBack(CallBack callBack){ this.callBack = callBack; }
@Override public void onClick(View v) { blankFragmentText.setText("Welcome BlankFragment1"); String str = callBack.getMessage(); Toast.makeText(getActivity(),"BlankFragment1:" + str,Toast.LENGTH_SHORT).show(); }
@Override public boolean onLongClick(View v) { callBack.sendMessage("BlankFragment1发送的数据"); return true; } }
|
MainActivity中
1、调用setCallBack方法
在按钮单击事件下通过已经创建好的blankFragment对象调用
1 2 3 4 5 6 7 8 9 10
| blankFragment1.setCallBack(new CallBack() { @Override public String getMessage() { return "MainActivity获取的数据"; } @Override public void sendMessage(String msg) { Toast.makeText(MainActivity.this,"MainActivity:" + msg,Toast.LENGTH_SHORT).show(); } });
|
2、按钮二
1 2 3 4 5 6 7 8 9 10
| blankFragment2.setCallBack(new CallBack() { @Override public String getMessage() { return "MainActivity获取的数据"; } @Override public void sendMessage(String msg) { Toast.makeText(MainActivity.this,"MainActivity:" + msg,Toast.LENGTH_SHORT).show(); } });
|
MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
| 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; import android.widget.FrameLayout; import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private Button replaceFragment1,replaceFragment2; private FrameLayout frameLayout1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
replaceFragment1 = findViewById(R.id.replaceFragment1); replaceFragment2 = findViewById(R.id.replaceFragment2); frameLayout1 = findViewById(R.id.frameLayout1);
replaceFragment1.setOnClickListener(this); replaceFragment2.setOnClickListener(this); }
@Override
public void onClick(View v) {
Bundle bundle = new Bundle(); switch (v.getId()){
case R.id.replaceFragment1: BlankFragment1 blankFragment1 = new BlankFragment1();
blankFragment1.setArguments(bundle);
bundle.putString("message1","Bundle方式向BlankFragment1传递的数据");
setReplaceFragment(blankFragment1);
blankFragment1.setCallBack(new CallBack() { @Override public String getMessage() { return "MainActivity获取的数据"; } @Override public void sendMessage(String msg) { Toast.makeText(MainActivity.this,"MainActivity:" + msg,Toast.LENGTH_SHORT).show(); } }); break;
case R.id.replaceFragment2: BlankFragment2 blankFragment2 = new BlankFragment2();
blankFragment2.setArguments(bundle);
bundle.putString("message1","Bundle方式向BlankFragment2传递的数据");
setReplaceFragment(blankFragment2);
blankFragment2.setCallBack(new CallBack() { @Override public String getMessage() { return "MainActivity获取的数据"; } @Override public void sendMessage(String msg) { Toast.makeText(MainActivity.this,"MainActivity:" + msg,Toast.LENGTH_SHORT).show(); } }); break; } }
private void setReplaceFragment (Fragment fragment){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frameLayout1,fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit(); } }
|
效果图