Fragment 是 android 中比 Activity 更加轻量级的视图与逻辑结合的碎片, 我们可以在应用中使用,更方便的达到一些业务需求。
使用 Fragment,我们要创建一个类继承自 Fragment,一般我们选择继承 v4 包下面的 Fragment,兼容更好:
public class TestFragment extends Fragment {
private TextView tag;
private TextView name;
private Button addCount;
private Icom icom;
private int count = 0;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_test, container, false);
return view;
}
}
我们需要重写其 onCreateView() 方法,来为 Fragment 引入视图,所以我们需要创建 xml 文件,如上面的 fragment_test.xml :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#69de99">
<TextView
android:id="@+id/fragment_test_tag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/>
<TextView
android:id="@+id/fragment_test_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:layout_centerInParent="true"/>
<Button
android:id="@+id/fragment_test_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
接下来我们就需要在 Activity 中使用 Fragment 了,首先是在 Activity 的布局中使用 Fragment:
主要属性:
属性名 | 说明 |
android:tag="" | 标签,在代码中可以通过标签找到 Fragment |
android:name="" | 选择 布局默认的 Fragment |
<RelativeLayout
android:id="@+id/layout_fragment_test"
android:layout_width="match_parent"
android:layout_height="200dp">
<fragment
android:id="@+id/layout_fragment_test1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:tag="normal tag"
android:name="com.example.a01378359.testapp.fragment.TestFragment"/>
</RelativeLayout>
<RelativeLayout
android:layout_marginTop="10dp"
android:id="@+id/layout_fragment_add"
android:layout_width="match_parent"
android:layout_height="200dp">
</RelativeLayout>
这里需要注意,如果以后要动态的添加替换 Fragment,那么 Fragment 的父标签一定要添加 id,因为在代码中添加和替换 Fragment 时,是需要传入父布局的 id 的。如何在布局使用 Fragment 呢:
为布局添加 Fragment:
// 添加 fragment
private void addFragment(){
Fragment fragment = new TestFragment();
Bundle bundle = new Bundle();
bundle.putString("name","new Fragment");
fragment.setArguments(bundle);
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
// 需要传入父布局 id 和 fragment
transaction.add(R.id.layout_fragment_add,fragment);
transaction.commit();
}
为布局替换 Fragment:
// 替换 fragment
private void replaceFragment(){
Fragment fragment = new TestFragment();
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
// 需要传入父布局 id 和 fragment
transaction.replace(R.id.layout_fragment_test,fragment);
transaction.commit();
}
注意:一次 Fragment 的事务(Transaction)的实例只能提交一次,多次提交需要重新创建实例。
我们能够注意到,在 Activity 中,我们添加替换再多的 Fragment,当我们按下返回键,就会销毁 Activity,当然,这么多的 Fragment 也被销毁了,一些临时数据就也不能保存,那么我们通过什么方法可以时按下返回键是返回上次的 Fragment 状态呢?添加 BackStack:
// 设置 BackStack
private void setBackStack(){
Fragment fragment1 = new TestFragment();
Fragment fragment2 = new TestFragment();
Bundle bundle = new Bundle();
bundle.putString("name","new Fragment");
fragment1.setArguments(bundle);
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.layout_fragment_add,fragment1);
transaction.replace(R.id.layout_fragment_test,fragment2);
// 添加 BackStack
transaction.addToBackStack(null);
transaction.commit();
}
还有一个问题来了,我们怎么实现 Fragment 与 Activity 的通信呢?除了众所周知的一些网络呀、文件、数据库等等通用操作,有没有一些更加便利的操作呢?比如下图:
一个 Activity 中有一个绿色的 Fragment,我们怎么在 Fragment 中点击 + 按钮,使得 Activity 中显示点击的次数呢?这个时候 Fragment 的生命周期方法:onAttach() 方法就起到作用了:
我们先创建一个接口,来设置点击数量:
public interface Icom {
public void setCount(int count);
}
我们使 Activity 实现 Icom 的接口,实现其 setCount(int count) 方法,在里面为 TextView 设置文字:
@Override
public void setCount(int count) {
clickCount.setText(count+"");
}
接下来就是实现绑定:
@Override
public void onAttach(Activity context) {
super.onAttach(context);
// 先判断 Activity 是否实现了 Icom
if (context instanceof Icom){
icom = (Icom) context;
}
}
项目地址:
源代码