「「第一行代码(第二版)」」学习笔记 5 碎片(连载中)

碎片(Fragment)的定义

碎片是一种可嵌入在活动当中的UI片段,它能让程序更加合理和充分地利用大屏幕空间,因而在平板上的应用得非常广泛。碎片和活动非常的像,同样都能包含布局,同样有自己的生命周期。

碎片的使用方式

写两个碎片平分活动空间。
left_fragment.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="Button"/>

LinearLayout>

right_fragment.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#00ff00">

    <TextView
        android:id="@+id/tetView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:textSize="20dp"
        android:text="This is right fragment."/>
LinearLayout>

然后新建两个类,对应着上面的两个布局,LeftFragment 和 RightFragment,并让它们继承自Fragment.

public class LeftFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
       View view  = inflater.inflate(R.layout.left_fragment,container,false);
       return view;
    }
}

public class RightFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view  = inflater.inflate(R.layout.right_fragment,container,false);
        return view;
    }
}

这里重写了onCreateView()方法,然后在这个方法中通过LayoutInflater的inflate()方法将定义的布局动态加载进来。

最后修改activity_main.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:id="@+id/left_fragment"
        android:name="com.example.fragmenttest.LeftFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"/>

    <fragment
        android:id="@+id/right_fragment"
        android:name="com.example.fragmenttest.RightFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"/>

LinearLayout>

我们使用标签在布局中添加碎片,需要注意的是,这里我们还需要通过android:name属性来显式指明要添加的碎片类名,注意一定要将类的报名也加上。

效果如下
「「第一行代码(第二版)」」学习笔记 5 碎片(连载中)_第1张图片

动态添加碎片
接下来是对上面代码的完善
新建another_right_fragment.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:background="#ffff00"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:textSize="20sp"
        android:text="This is another right fragment."/>

LinearLayout>

然后对应这个布局建一个类 AnotherRightFragment。

public class AnotherRightFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.another_right_fragment,container,false);
        return view;
    }
}

然后修改下activity_main.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:id="@+id/left_fragment"
        android:name="com.example.fragmenttest.LeftFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"/>

    <FrameLayout
        android:id="@+id/right_fragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"/>

LinearLayout>

将右边的碎片换成一个FrameLayout中,然后往FrameLayout中添加内容,从而实现动态添加碎片的功能。
修改MainActivity

public class MainActivity extends AppCompatActivity {

    private Button button;
    private TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = (Button) findViewById(R.id.button);
        textView = (TextView) findViewById(R.id.tetView);
        ButtonOnClickListener listener = new ButtonOnClickListener();
        button.setOnClickListener(listener);
        replaceFragment(new RightFragment());

    }
    class ButtonOnClickListener implements View.OnClickListener{

        @Override
        public void onClick(View view) {
            switch (view.getId()){
                case R.id.button:
                    replaceFragment(new AnotherRightFragment());
                    break;
                default:
                    break;
            }
        }
    }
    private void replaceFragment(Fragment fragment){
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.replace(R.id.right_fragment,fragment);
        transaction.commit();
    }
}

我们给左侧碎片按钮注册一个点击事件,然后调用replaceFragment()方法动态添加RightFragment这个碎片,当点击按钮时,又会调用replaceFragment()方法替换成AnotherRightFragment。结合replaceFragment()方法可以看出,动态添加碎片主要分为5步。
(1)创建待添加的碎片实例
(2)获取FragmentManager,在活动中可以直接通过调用getSupportFragmentManager()方法得到。
(3)开启一个事务,通过调用beginTransaction()方法开启。
(4)向容器内添加或替换碎片,一般使用replace()方法实现,需要传入容器的id和待添加的碎片实例。
(5)提交事务,调用commit()方法来完成。

在碎片中模拟返回栈
FragmentTransaction提供了一个addToBackStack()方法,可以用于将一个事务添加到返回栈中,修改MainActivity代码
这里修改是在replaceFragment方法中添加了一行代码,所以下面只展示这个方法

 private void replaceFragment(Fragment fragment){
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.replace(R.id.right_fragment,fragment);
        transaction.addToBackStack(null);//添加到返回栈
        transaction.commit();
    }

我们在事务提交之前调用了FragmentTransaction的addToBackStack()方法,他可以接收一个名字用于描述返回栈的状态,一般传入null即可。

碎片与活动之间通信
为了方便碎片与活动之间进行通信,FragmentManager提供了一个类似于findViewById()的方法,专门用于从布局文件中获取碎片的实例。代码如下所示

 RightFragment rightFragment = (RightFragment) getFragmentManager().findFragmentById(R.id.right_fragment);
 //获取碎片实例
                                         

碎片的生命周期
和活动一样,碎片也有自己的生命周期,并且它和活动的生命周期实在是太像了。
同样的,Fragment类中也提供了一系列的回调方法,已覆盖碎片生命周期的每一个环节,其中活动中有的回调方法,碎片中几乎都有,不过碎片还提供一些附加的回调方法,那我们就重点看一下这几个回调。
onAttch(),当碎片和活动建立关联的时候调用。
onCreateView。为碎片创建视图(加载布局)时调用
onActivityCreated(),确保与碎片相关联的活动一定已经创建完毕的时候调用。
onDestroyView()。当与碎片关联的视图被移除的时候调用
onDetach()。当碎片与活动解出关联的时候调用

你可能感兴趣的:(#,android,学习笔记)