Android入门教程 | Fragment (加载方法与通信)

Fragment 加载方法
加载方法有两种

  • 在xml文件中注册
  • 在Java代码中加载
xml中注册:
例如在 fragment_demo.xml 中定义

com.rust.fragment.SecondFragment 就是 Fragment 子类
SecondFragment.java里复写onCreateView方法,并返回定义好的view
activity 中直接加载即可
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 先执行 onResume 然后当前 Fragment 执行 onResume 当前Fragment 被 replace 掉,再次 replace 回来时,有些状态并未重新初始化。
执行 replace 时会把 Fragment 的声明周期再跑一遍。稳妥的做法是,在 onCreateView中初始化必要的变量。比如重置一些状态值。在多个 Fragment中切换时需要特别注意。
Fragment 间的通信
在 Fragment 的 java 文件中,可以使用 getActivity() 来获得调用它的 activity,然后再找到另一个 Fragment,进行通信
getActivity().getFragmentManager().findFragmentById(R.id.fragment_list);

但这样做耦合度太高,不方便后续的修改操作
Fragment 与其附着的 Activity 之间的通信,都应该由 Activity 来完成;不能是多个 Fragment 之间直接通信
Fragment与其附着的Activity之间通信方式:
  • 在发起事件的Fragment中定义一个接口,接口中声明你的方法
  • 在onAttach方法中要求Activity实现该接口
  • 在Activity中实现该方法
例如一个 activity 中布置了 2 个 Fragment,它们之间的通信要依靠 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
  • 定义接口
除了上面提到的几种方法,也可以用 Activity 和 Fragment 共用 ViewModel的方式实现通信。
【Android入门教程 | Fragment (加载方法与通信)】Android零基础入门教程视频参考

    推荐阅读