Fragment 加载办法
加载办法有两种
- 在xml文件中注册
- 在Java代码中加载
xml中注册:
例如在 fragment_demo.xml
中定义
<?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="vertical" > <fragment android:id="@+id/main_fragment_up" android:name="com.rust.fragment.FirstFragment" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> <fragment android:id="@+id/main_fragment_bottom" android:name="com.rust.fragment.SecondFragment" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /></LinearLayout>
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
<?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="vertical" android:background="#0011ff" ><!-- <Button android:id="@+id/btn_fragment1_1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/btn_fragment1" android:textSize="16sp" /><EditText /> --></LinearLayout>
新建一个类 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 来占位。
<FrameLayout android:id="@+id/layout_container1" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="4" > </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); //增加到返回栈,这样按返回键的时候能返回已增加的fragmentfragmentTransaction.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<String> data; private ArrayAdapter<String> adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.liststore); data = new ArrayList<String>(); // 把data装入adapter中 adapter = new ArrayAdapter<String>(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零根底入门教程视频参考