《第一行代码》读书笔记(四)----碎片

碎片是什么

碎片(Fragment)是可以嵌入在活动中的UI片段, 能让程序更合理使用大屏幕的空间. 可理解成一个迷你型的活动. 同活动一样, 能包含布局, 有自己的生命周期.

碎片的使用方式

简单用法

目标: 在一个活动中添加两个碎片, 并让这两个碎片评分活动空间.

步骤:

第一, 新建左侧碎片布局和右侧碎片布局, 左侧布局放置一个居中显示的按钮, 右侧放置一个TextView, 用于显示一段文本.

第二, 新建左侧碎片类和右侧碎片类, 继承自 android.app.Fragment . 两个类的代码大同小异, 比如左侧碎片类:

public class LeftFragment extends Fragment {

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

第三, 修改主活动的布局文件:

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

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

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

</LinearLayout>

使用 <fragment> 标签在布局中添加碎片, 这里注意 android:name 属性用来显式指明要添加的碎片类名, 要把包名也加上.

动态加载碎片

再新建一个右侧碎片, 包含一个TextView, 显示不同的文字. 再新建一个右侧碎片类, 代码都一样.

修改 主活动的布局:

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

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

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

        <fragment
            android:id="@+id/right_fragment"
            android:name="me.zipstream.fragment.RightFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </FrameLayout>
</LinearLayout>

将右侧碎片放在了一个 FrameLayout 中.

然后, 在主活动的代码中动态替换 FrameLayout 中的内容, 实现动态添加碎片:

public class MainActivity extends Activity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button:
                AnotherRightFragment fragment = new AnotherRightFragment();
                FragmentManager manager = getFragmentManager();
                FragmentTransaction transaction = manager.beginTransaction();
                transaction.replace(R.id.right_layout, fragment);
                transaction.commit();
                break;
            default:
                break;
        }
    }
}

总结动态添加碎片的步骤:
1, 创建待添加碎片的实例.
2, 获取到 FragmentManager , 通过 getFragmentManager() 方法.
3, 开启一个事务, 通过 beginTransaction() 方法.
4, 向容器内加入碎片, 通过 replace() 方法. 注意, 传入的是 容器的id, 和待添加碎片的实例.
5, 提交事务.

碎片中模拟返回栈

模拟返回栈的效果, 按下Back键返回到上一个碎片而不是退出程序.
很简单, FragmentTransaction 提供了一个 addToBackStack() 方法.
只需要在加入碎片后添加一行代码, 就可以了.

transaction.addToBackStack(null); 

碎片和活动之间进行通信

调用 FragmentManager 的 findFragmentById() 方法, 可以在活动中得到碎片的实例:

RightFragment rightFragment = (RightFragment) getFragmentManager().findFragmentById(R.id.right_fragment);

调用 getActivity() 方法, 可以在碎片中得到和当前碎片相关联的活动的实例:

MainActivity activity = (MainActivity) getActivity();

另外, 当碎片中需要使用 Context 对象时, 也可以使用 getActivity() 方法.

那么, 碎片和碎片之间怎么通信呢?
很简单, 首先在一个碎片中得到与之相关联的活动的实例, 再通过这个活动获取另外一个碎片.

碎片的生命周期

活动中有的回调方法, 碎片中都有, 但是碎片还提供了一些附加的回调方法:
* onAttach(): 碎片和活动建立关联时调用.
* onCreateView(): 为碎片创建视图(加载布局)时调用.
* onActivityCreate(): 确保与碎片相关联的活动一定创建完毕时调用.
* onDestroyView(): 与碎片相关联的视图被移除时调用.
* onDetach(): 碎片和活动解除关联时调用.

动态加载布局的技巧

使程序在运行时能够根据分辨率或屏幕大小来决定加载哪个布局.

使用限定符

限定符(Qualifiers).
修改activity_main.xml, 只留下一个左侧碎片:

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

    <fragment
        android:id="@+id/left_fragment"
        android:name="me.zipstream.fragment.LeftFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

在 res 目录下新建一个文件夹 layout-large, 新建布局, 也叫activity_main, 代码:

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

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

    <fragment
        android:id="@+id/right_fragment"
        android:name="me.zipstream.fragment.RightFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="3" />

</LinearLayout>

large 就是一个限定符. 那些屏幕被认为是large的设备就会自动加载 layout_large 文件夹下的布局, 而小屏幕设备还会加载 layout 文件夹下的布局.

android中常见的限定符:
按大小分:
* small: 小屏幕设备
* normal: 中等
* large: 大
* xlarge: 超大

按分辨率分:
* ldpi: 低分辨率(120dpi以下)
* mdpi: 中分辨率(120dpi 到 160dpi)
* hdpi: 高分辨率(160dpi 到 240dpi)
* xhdpi: 超高分辨率(240dpi 到 320dpi)

按方向分:
* land: 横屏设备
* port: 竖屏设备

使用最小宽度限定符

最小宽度限定符(Smallest-width Qualifier).
对屏幕的宽度指定一个最小值(以dp为单位), 屏幕宽度大于这个值的设备就加载这个布局, 小于则加载另一个布局.
比如在res目录下新建一个layout-sw600dp文件夹, 那么屏幕大于600dp的设备就会加载这个目录下的布局.小于则加载默认的布局.

最小宽度限定符是在Android3.2之后引入的.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值