您的位置:首页 > 编程语言

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

2015-09-03 23:38 323 查看

碎片是什么

碎片(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之后引入的.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: