共计 5076 个字符,预计需要花费 13 分钟才能阅读完成。
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); // 增加到返回栈,这样按返回键的时候能返回已增加的 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<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 零根底入门教程视频参考