Android入门教程 | Fragment (加载方法与通信)
Fragment 加载方法
加载方法有两种
- 在xml文件中注册
- 在Java代码中加载
例如在
fragment_demo.xml
中定义
com.rust.fragment.SecondFragment
就是 Fragment 子类在
SecondFragment.java
里复写onCreateView
方法,并返回定义好的viewactivity 中直接加载即可
setContentView(R.layout.fragment_demo);
Java代码中加载
①准备好Fragment xml布局文件
②新建一个类,继承自 Fragment;在这个类中找到 Fragment 布局文件
③在 Activity 中使用 FragmentManager 来操作 Fragment
④别忘了commit
先自定义一个布局文件
fragment_first.xml
新建一个类
FirstFragment.java
,继承自 Fragment。复写 onCreateView
方法。在onCreateView
方法中,可以操作 Fragment 上的控件。@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_first, container,false);
//fragment_first是自定义好的布局
//如果此Fragment上放了控件,比如Button,Edittext等。可以在这里定义动作
btn_fragment1_send = (Button) rootView.findViewById(R.id.btn_fragment1_1);
//...
return rootView;
}
准备一个位置给 Fragment,比如在
activity_main.xml
中用 Framelayout 来占位。
在
MainActivity.java
里,先获得 FragmentManager,得到FragmentTransaction。Fragment 的添加删除等操作由 FragmentTransaction 来完成。f1 = new FirstFragment();
//获取实例
f2 = new SecondFragment();
//
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.layout_container1,f1);
//添加
fragmentTransaction.replace(R.id.layout_container1,f1);
//替换
// 或者也可以写成
fragmentTransaction.replace(R.id.layout_container1,new FirstFragment());
//fragmentTransaction.addToBackStack(null);
//添加到返回栈,这样按返回键的时候能返回已添加的fragment
fragmentTransaction.commit();
//别忘了commit
//移除操作 getFragmentManager().beginTransaction().remove(f1).commit();
相比与 xml 中注册,代码加载更为灵活一些。个人较为喜欢动态加载。
Fragment 与 Activity 之间的配合
Activity 先执行Fragment 间的通信onResume
然后当前 Fragment 执行onResume
当前Fragment 被 replace 掉,再次 replace 回来时,有些状态并未重新初始化。
执行 replace 时会把 Fragment 的声明周期再跑一遍。稳妥的做法是,在onCreateView
中初始化必要的变量。比如重置一些状态值。在多个 Fragment中切换时需要特别注意。
在 Fragment 的 java 文件中,可以使用
getActivity()
来获得调用它的 activity,然后再找到另一个 Fragment,进行通信getActivity().getFragmentManager().findFragmentById(R.id.fragment_list);
但这样做耦合度太高,不方便后续的修改操作
Fragment 与其附着的 Activity 之间的通信,都应该由 Activity 来完成;不能是多个 Fragment 之间直接通信
Fragment与其附着的Activity之间通信方式:
- 在发起事件的Fragment中定义一个接口,接口中声明你的方法
- 在onAttach方法中要求Activity实现该接口
- 在Activity中实现该方法
代码:
ListStoreActivity.java
NewItemFragment.java
ListStoreFragment.java
布局文件为:
liststore.xml
new_item_fragment.xml
准备布局文件:
liststore.xml
用 LinearLayout 中放置了 2 个 fragment,分别指向 2 个Fragment 文件new_item_fragment.xml
中并排放置一个 EditText 和一个按钮ListStoreFragment.java
使用前面定义的界面public class ListStoreFragment extends ListFragment{
/// 继承自ListFragment,已经封装好了listview
/// 不需要自己写ListView了
}
NewItemFragment.java
/**
* 声明一个接口,定义向activity传递的方法
* 绑定的activity必须实现这个方法
*/
public interface OnNewItemAddedListener {
public void newItemAdded(String content);
}
private OnNewItemAddedListener onNewItemAddedListener;
private Button btnAddItem;
/*复写onAttach方法*/
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
onNewItemAddedListener = (OnNewItemAddedListener) activity;
} catch (ClassCastException e){
throw new ClassCastException(activity.toString() + "must implement OnNewItemAddedListener");
}
}
ListStoreActivity.java
加载主视图liststore.xml
;
两个 Fragment 通过
ListStoreActivity
来通信在 onCreate 方法中获取 ListStoreFragment 的实例;并且复写 newItemAdded 方法,在里面加上业务逻辑
public class ListStoreActivity extends Activity implements OnNewItemAddedListener{private ArrayList data;
private ArrayAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.liststore);
data = https://www.it610.com/article/new ArrayList();
// 把data装入adapter中
adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, data);
// ListFragment并不需要再定义一个listview
ListStoreFragment listStoreFragment = (ListStoreFragment) getFragmentManager().findFragmentById(R.id.fragment_listview);
listStoreFragment.setListAdapter(adapter);
}@Override
public void newItemAdded(String content) {
//复写接口中的方法,业务代码在这里实现
if(!content.equals("")) {
data.add(content);
adapter.notifyDataSetChanged();
}
}
}
这样做的缺点是耦合度很高
Fragment跟Activity的几种通信方式
- Activity把自己的handler交给Fragment
- 广播
- EventBus
- 定义接口
【Android入门教程 | Fragment (加载方法与通信)】Android零基础入门教程视频参考
推荐阅读
- android第三方框架(五)ButterKnife
- Android中的AES加密-下
- 带有Hilt的Android上的依赖注入
- android|android studio中ndk的使用
- Android事件传递源码分析
- RxJava|RxJava 在Android项目中的使用(一)
- Android7.0|Android7.0 第三方应用无法访问私有库
- 深入理解|深入理解 Android 9.0 Crash 机制(二)
- android防止连续点击的简单实现(kotlin)
- Android|Android install 多个设备时指定设备