Fragment高级进阶
一.Fragment回退栈
通过代码,将fragment加入到栈中,按返回键时会将fragment弹栈
public class Main2Activity extends AppCompatActivity {
private FragmentManager supportFragmentManager;
private BlankFragment blankFragment;
private Button butBack;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
initViews();
}
private void initViews() {
supportFragmentManager = getSupportFragmentManager();//获取碎片管理者
FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();//创建事务
blankFragment = new BlankFragment();//创建碎片
butBack = (Button) findViewById(R.id.but_back);
fragmentTransaction.add(R.id.content_layout2, blankFragment);//添加到布局里
fragmentTransaction.addToBackStack("1");//添加到回退栈
fragmentTransaction.commit();//提交事务
butBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
supportFragmentManager.popBackStack();//弹栈
}
});
}
}
添加到回退栈需要用到事务里的 addToBackStack() 方法
而手动弹栈需要用到碎片管理者的 popBackStack() 方法
二.Fragment传值
1.Activity给Fragment传值
在Activity中将Fragment对象调用 setArguments() 方法进行设置传值,该方法的参数是一个 Bundle 对象,需要创建Bundle对象,再将要传递的值设置到Bundle对象里
public class Main3Activity extends AppCompatActivity {
private EditText etText;
private Button butSend;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
initViews();
}
private void initViews() {
etText = (EditText) findViewById(R.id.et_text);
butSend = (Button) findViewById(R.id.but_send);
final FragmentManager manager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = manager.beginTransaction();
BlankFragment3 fragment3 = new BlankFragment3();
fragmentTransaction.replace(R.id.content_lay, fragment3);
fragmentTransaction.commit();
butSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String s = etText.getText().toString();
BlankFragment3 blankFragment3 = new BlankFragment3();
Bundle bundle = new Bundle();//创建Bundle对象
bundle.putString("val",s);
blankFragment3.setArguments(bundle);//传值
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.content_lay,blankFragment3);
transaction.commit();
}
});
}
}
在传递的Fragment中直接调用 getArguments() 方法获取Bundle对象,取出传递的数据(如果在onCreateView()方法中获取到的Bundle需要进行非空判断,否则在创建Fragment对象时会空指针异常)
public class BlankFragment3 extends Fragment {
private TextView textShow;
public BlankFragment3() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_blank_fragment3, container, false);
textShow = (TextView) view.findViewById(R.id.text_show);
Bundle arguments = getArguments();//获取传递的数据
if (arguments != null) {
String val = arguments.getString("val");
textShow.setText(val);
}
return view;
}
}
Activity中的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
tools:context=".Main3Activity">
<EditText
android:id="@+id/et_text"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/but_send"
android:text="发送"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout
android:id="@+id/content_lay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
</LinearLayout>
</LinearLayout>
Fragment中的布局
<?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=".BlankFragment3">
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="@+id/text_show"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
</FrameLayout>
效果展示(上方为Activity中的控件,下方TextView为Fragment中的控件)
2.Fragment给Activity传值
Fragment给Activity传值中,需要用到接口回调的方式进行传值
1.创建接口
2.在Fragment中声明一个接口的对象
3.Activity实现接口
4.使Fragment中的对象=Activity,父类指向子类引用
5.接口的参数就可以在Activity中使用
Activity中的代码
public class Main4Activity extends AppCompatActivity implements BlankFragment4.MyListener {
private TextView teShow;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main4);
teShow = (TextView) findViewById(R.id.te_show);
}
@Override
public void msg(String s) {
teShow.setText(s);
}
}
Fragment中的代码
public class BlankFragment4 extends Fragment {
private EditText et;
private Button buSend;
public BlankFragment4() {
// Required empty public constructor
}
public interface MyListener{
void msg(String s);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
myListener = (MyListener) getActivity();
}
private MyListener myListener;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_blank_fragment4, container, false);
et = (EditText) view.findViewById(R.id.et);
buSend = (Button) view.findViewById(R.id.bu_send);
buSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String s = et.getText().toString();
myListener.msg(s);
}
});
// Inflate the layout for this fragment
return view;
}
}
在Fragment中的接口对象赋值时,要注意比onCreateView()方法先执行,否则接口对象为空,空指针异常
Activity中的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
tools:context=".Main4Activity">
<TextView
android:text="..........."
android:id="@+id/te_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<fragment
android:id="@+id/fr"
android:name="com.example.day2_25.BlankFragment4"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Fragment中的布局
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".BlankFragment4">
<!-- TODO: Update blank fragment layout -->
<EditText
android:id="@+id/et"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/bu_send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送" />
</LinearLayout>
效果展示(上方TextView为Activity中的控件,下方为Fragment中的控件)
3.Fragment给Fragment传值
三种方式
- 在Fragment中获取到另一个Fragment的对象进行操作
动态创建的fragment通过findFragmentByTag得到另一个的Fragment的对象。
静态创建的fragment通过findFragmentById得到另一个的Fragment的对象。
- 通过上述2的接口回调方法,意思相同
- 通过上述1的setArguments,getArguments方法进行传值
下面展示第一种方法
Fragment1中的代码
public class BlankFragment51 extends Fragment {
private TextView fTeShow;
public BlankFragment51() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_blank_fragment51, container, false);
// Inflate the layout for this fragment
fTeShow = (TextView) view.findViewById(R.id.f_teShow);
return view;
}
public void setTextView(String s) {
fTeShow.setText(s);
}
}
Fragment2中的代码
public class BlankFragment52 extends Fragment {
private EditText fEt;
private Button fBut;
public BlankFragment52() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_blank_fragment52, container, false);
fEt = (EditText) view.findViewById(R.id.f_et);
fBut = (Button) view.findViewById(R.id.f_but);
fBut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentManager fragmentManager = getFragmentManager();
BlankFragment51 fragmentById = (BlankFragment51) fragmentManager.findFragmentById(R.id.f1);
fragmentById.setTextView(fEt.getText().toString());
}
});
return view;
}
}
在Fragment1中自定义一个设置的方法将要设置的数据通过参数形式传递
Activity中的布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
tools:context=".Main5Activity">
<fragment
android:id="@+id/f1"
android:name="com.example.day2_25.BlankFragment51"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<fragment
android:id="@+id/f2"
android:name="com.example.day2_25.BlankFragment52"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
Fragment1中的布局文件
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".BlankFragment51">
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="@+id/f_teShow"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="123456" />
</LinearLayout>
Fragment2中的布局文件
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".BlankFragment52">
<!-- TODO: Update blank fragment layout -->
<EditText
android:id="@+id/f_et"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/f_but"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送" />
</LinearLayout>
效果展示(左边为Fragment1中的控件,右边为Fragment2中的控件)
三.Fragment多层嵌套
就是在Fragment布局中引入另一个Fragment
基本操作相同
值得注意的是获取碎片管理者时需要通过
FragmentManager childFragmentManager = getChildFragmentManager()
其余操作一样
来源:CSDN
作者:摇耳朵的小布丁i
链接:https://blog.csdn.net/weixin_45533623/article/details/104502744