Android Fragment(2)

来源:互联网 发布:java 定义空的数组 编辑:程序博客网 时间:2024/06/05 22:32

参考:

片段:https://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity
Fragment 使用(1):http://blog.csdn.net/u012005313/article/details/55215552


主要内容

  1. 动态添加,替换和移除 fragment
  2. 返回栈的使用
  3. activity 通信

动态添加,替换和移除 fragment

设置 3 个按钮,分别用来添加,替换和移除 fragment

MainActivity.java 如下:

public class MainActivity extends AppCompatActivity{    private static final String TAG = "MainActivity";    private Button btnAdd;    private Button btnReplace;    private Button btnRemove;    private FrameLayout flContainer;    private FragmentManager fragmentManager;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();    }    private void initView() {        btnAdd = (Button) findViewById(R.id.btn_add);        btnReplace = (Button) findViewById(R.id.btn_replace);        btnRemove = (Button) findViewById(R.id.btn_remove);        flContainer = (FrameLayout) findViewById(R.id.fl_container);        fragmentManager = getSupportFragmentManager();        btnAdd.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                addFragment();            }        });        btnReplace.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                replaceFragment();            }        });        btnRemove.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                removeFragment();            }        });    }    private void addFragment() {        OneFragment onefragment = new OneFragment();        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();        fragmentTransaction.add(R.id.fl_container, onefragment);        fragmentTransaction.commit();        btnAdd.setEnabled(false);        btnReplace.setEnabled(true);    }    private void replaceFragment() {        TwoFragment fragment = new TwoFragment();        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();        fragmentTransaction.replace(R.id.fl_container, fragment, "twoFragment");        fragmentTransaction.commit();        btnReplace.setEnabled(false);        btnRemove.setEnabled(true);    }    private void removeFragment() {        TwoFragment fragment = (TwoFragment)fragmentManager.findFragmentByTag("twoFragment");        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();        fragmentTransaction.remove(fragment);        fragmentTransaction.commit();        btnRemove.setEnabled(false);        btnAdd.setEnabled(true);    }}

activity_main.xml 如下:

<?xml version="1.0" encoding="utf-8"?><android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.zj.fragmentdemo.MainActivity">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="vertical">        <LinearLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:orientation="horizontal">            <Button                android:id="@+id/btn_add"                style="?android:attr/buttonBarButtonStyle"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:layout_weight="1"                android:text="ADD" />            <Button                android:id="@+id/btn_replace"                style="?android:attr/buttonBarButtonStyle"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:layout_weight="1"                android:enabled="false"                android:text="REPLACE" />            <Button                android:id="@+id/btn_remove"                style="?android:attr/buttonBarButtonStyle"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:layout_weight="1"                android:enabled="false"                android:text="REMOVE" />        </LinearLayout>        <FrameLayout            android:id="@+id/fl_container"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_weight="1"            android:background="@color/colorAccent" />    </LinearLayout></android.support.design.widget.CoordinatorLayout>

activity 中进行 fragment 的添加,替换和移除,使用 FragmentTransaction

FragmentTransaction 通过 FragmentManager 获得:

FragmentManager fragmentManager = getSupportFragmentManager();FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

Note 1:每次进行 fragment 操作,必须重新获取 FragmentTransaction

Note 2:每次进行 fragment 更改后,必须调用 commit 方法

添加

add 方法有多种重载,介绍其中两种:

/** * Calls {@link #add(int, Fragment, String)} with a null tag. */public abstract FragmentTransaction add(@IdRes int containerViewId, Fragment fragment);/** * Add a fragment to the activity state.  This fragment may optionally * also have its view (if {@link Fragment#onCreateView Fragment.onCreateView} * returns non-null) into a container view of the activity. *  * @param containerViewId Optional identifier of the container this fragment is * to be placed in.  If 0, it will not be placed in a container. * @param fragment The fragment to be added.  This fragment must not already * be added to the activity. * @param tag Optional tag name for the fragment, to later retrieve the * fragment with {@link FragmentManager#findFragmentByTag(String) * FragmentManager.findFragmentByTag(String)}. *  * @return Returns the same FragmentTransaction instance. */public abstract FragmentTransaction add(@IdRes int containerViewId, Fragment fragment,        @Nullable String tag);

第一个参数 containerViewId 指定 activity 中放置 fragment 的位置

第二个参数 fragment 指定要添加的片段

第三个参数 tag 表示该 fragment 的标识符,之后可以通过函数 findFragmentByTag 找回该 fragment

替换

replace 函数有 2 个重载方法:

/** * Calls {@link #replace(int, Fragment, String)} with a null tag. */public abstract FragmentTransaction replace(@IdRes int containerViewId, Fragment fragment);/** * Replace an existing fragment that was added to a container.  This is * essentially the same as calling {@link #remove(Fragment)} for all * currently added fragments that were added with the same containerViewId * and then {@link #add(int, Fragment, String)} with the same arguments * given here. *  * @param containerViewId Identifier of the container whose fragment(s) are * to be replaced. * @param fragment The new fragment to place in the container. * @param tag Optional tag name for the fragment, to later retrieve the * fragment with {@link FragmentManager#findFragmentByTag(String) * FragmentManager.findFragmentByTag(String)}. *  * @return Returns the same FragmentTransaction instance. */public abstract FragmentTransaction replace(@IdRes int containerViewId, Fragment fragment,        @Nullable String tag);

其参数和 add 方法一致

移除

remove 方法:

/** * Remove an existing fragment.  If it was added to a container, its view * is also removed from that container. *  * @param fragment The fragment to be removed. *  * @return Returns the same FragmentTransaction instance. */public abstract FragmentTransaction remove(Fragment fragment);

需要提供要移除的 fragment 对象

实现:

这里写图片描述


返回栈的使用

由上面操作可知,进行 fragment 的操作如下

  • 获取 FragmentTransaction 对象
  • 执行 add / replace / remove 操作
  • 执行 commit 提交更改

可以将 fragment 更改记录下来,方法是在 commit 之前调用函数 addToBackStack:

/** * Add this transaction to the back stack.  This means that the transaction * will be remembered after it is committed, and will reverse its operation * when later popped off the stack. * * @param name An optional name for this back stack state, or null. */public abstract FragmentTransaction addToBackStack(@Nullable String name);

当执行上面的操作后,点击 返回键 能够回退到上一步的 fragment

或者调用 FragmentManager.popBackStack 模拟返回键操作:

/** * Pop the top state off the back stack.  Returns true if there was one * to pop, else false.  This function is asynchronous -- it enqueues the * request to pop, but the action will not be performed until the application * returns to its event loop. */public abstract void popBackStack();

修改 MainActivity.java 如下:

public class MainActivity extends AppCompatActivity {    ...    private void initView() {        ...        btnRemove.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {//                removeFragment();                popFragment();            }        });    }    private void addFragment() {        ...        fragmentTransaction.add(R.id.fl_container, onefragment);        fragmentTransaction.addToBackStack(null);        fragmentTransaction.commit();        btnAdd.setEnabled(false);        btnReplace.setEnabled(true);        btnRemove.setEnabled(true);    }    private void replaceFragment() {        ...        fragmentTransaction.replace(R.id.fl_container, fragment, "twoFragment");        fragmentTransaction.addToBackStack(null);        fragmentTransaction.commit();        ...    }    private void removeFragment() {        ...//        btnRemove.setEnabled(false);//        btnAdd.setEnabled(true);    }    private void popFragment() {        fragmentManager.popBackStack();    }}

这里写图片描述

监听器

还可以设置 FragmentManager.addOnBackStackChangedListener 对返回栈操作进行监听:

/** * Interface to watch for changes to the back stack. */public interface OnBackStackChangedListener {    /**     * Called whenever the contents of the back stack change.     */    public void onBackStackChanged();}

修改 MainActivity.java 如下:

public class MainActivity extends AppCompatActivity implements FragmentManager.OnBackStackChangedListener {    private static final String TAG = "MainActivity";    ...s    @Override    public void onBackStackChanged() {        Log.e(TAG, "onBackStackChanged: "+fragmentManager.getBackStackEntryCount());    }    private void initView() {        ...        fragmentManager = getSupportFragmentManager();        fragmentManager.addOnBackStackChangedListener(this);        ...    }    ...}

activity 的事件回调

可以在 fragment 中创建一个回调接口,在 activity 实现该接口即可

比如,在 fragment 中创建一个点击事件:

public interface OnClickListener {    void onFragmentClick(View var1);}

在创建 fragment 时进行绑定:

public class OneFragment extends Fragment {    OnClickListener mListener;    ...    @Override    public void onAttach(Activity activity) {        super.onAttach(activity);        try {            mListener = (OnClickListener) activity;        } catch (ClassCastException e) {            throw new ClassCastException(activity.toString() + " must implement OnClickListener");        }    }    ...}

activity 中实现 onFragmentClick 方法即可

Note:ClassCastException 属于运行时异常

原创粉丝点击