Android 系列 6.7使用Fragment API构建现代UI

263 篇文章 2 订阅
164 篇文章 0 订阅
6.7使用Fragment API构建现代UI
问题
你想要一个更灵活的部分屏幕的排列。或者,您需要使用一些只能使用Fragments的较新的API。

使用Fragment Manager和布局来排列Fragment视图。
讨论
片段与Android 3.0一起引入,并已变得越来越常见。可以在一个简单的Activity中使用它们,如例6-7所示。
实例6-7。 MainActivity.java的部分
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
令人惊讶的是,对于单个Fragment的最简单的使用,不需要代码。工作在布局中完成,如例6-8所示。
实例6-8。 layout / 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"
android:fitsSystemWindows="true"
tools:context="com.androidcookbook.fragmentsimple.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<fragment
android:id="@+id/fragment"
android:name=".MainActivityFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:layout="@layout/fragment_main" />
</android.support.design.widget.CoordinatorLayout>

注意,与普通的View不同,例如Button和TextView,其中名称是类的简单名称,fragment元素不是大写,而是特殊处理;你总是子类化Fragment所以实际的类名由android:name属性提供。
Fragment本身是我们应用程序中的一个类,因此它作为一个Java类存在,如图所示实例6-9。而且,Fragment有一个View,所以它有一个布局XML文件,如图所示

实例6-8 

实例6-9。简单片段代码

public class MainActivityFragment extends Fragment {
public MainActivityFragment() {
// Constructor with arguments may be needed in more sophisticated apps
}
/** Like Menus, Fragments must be inflated by the developer */
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main, container, false);
}
}
实例6-10。简单的片段布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.androidcookbook.fragmentsdemos.MainActivityFragment"
tools:showIn="@layout/activity_main">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
</RelativeLayout>

在更复杂的活动中,通常使用FragmentManager来动态地将片段加载到活动中。 FragmentManager是基于事务的;一个简单的使用可能是这样的:
Fragment frag = new MyDemoFragment();
FragmentTransaction tx = getFragmentManager();
tx.beginTransaction();
tx.add(container, frag); // Or: tx.replace(container, newFragment);
tx.commit();

这也可以用流利的API风格编写,如:
getFragmentManager().beginTransaction()
.add(container, new MyDemoFragment())
.commit();

在基于支持库的活动中,您将使用getSupportFragmentManager()而不是getFragmentManager()。

片段的主要用途是同时具有多个视图。考虑列表详细信息应用程序。在小屏幕设备中,或者在纵向模式下狭窄的设备中,每次在屏幕上显示单个视图(项目列表或一个项目的详细信息)是有意义的。但是,在横向模式的平板电脑上,您有很多可用的宽度,所以列表和一个项目详细信息并排显示是有意义的(见图6-4)。


图6-4。纵向或横向布局
由于在应用程序中只能有一个屏幕上的活动,如果您尝试使用单个活动来实现它,则需要对View对象进行大量的改动。然而,使用Fragments,使它更容易。
片段可以在某些方面被认为是微型活动,但它们必须驻留在实际活动中。在我们的list-detail例子中,我们将有一个DisplayActivity,其中包含ListFragment和DetailFragment。在纵向模式下,只显示ListFragment,但在横向模式下,在任何合理大小的设备上,两个片段将并排显示。这通常通过使用基于资源系统的不同视图配置来执行,并在代码中触发此操作,以使用Fragment Manager来安装第二个Fragment,或者以活动形式启动Detail活动,以便它显示在列表。在我们的演示中,我们有一个TaskListActivity,它从操作栏中的任务菜单项中启动; TaskListActivity包含示例6-11中的代码(略微简化)。
实例6-11。在片段或活动中显示详细信息

holder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// This view will be created (but empty) on wide devices; show DetailFragment
if (findViewById(R.id.task_detail_container) != null) {
Bundle arguments = new Bundle();
arguments.putString(TaskDetailFragment.ARG_ITEM_ID, holder.mItem.id);
TaskDetailFragment fragment = new TaskDetailFragment();
fragment.setArguments(arguments);
// Replace the empty container with the actual DetailFragment
getSupportFragmentManager().beginTransaction()
.replace(R.id.task_detail_container, fragment)
.commit();
} else {
// Not on a wide device, show the DetailActivity
Context context = v.getContext();
Intent intent = new Intent(context, TaskDetailActivity.class);
intent.putExtra(TaskDetailFragment.ARG_ITEM_ID, holder.mItem.id);
context.startActivity(intent);
}
}
});

容器的布局配置如下:
•res / layout / task_list.xml - 包含其周围没有ViewGroup的List(RecyclerView)
•res / layout-w900dpi / task_list.xml - 包含水平LinearLayout中的列表,它也具有一个带有android:id =“@ + id / task_detail_container”和android:layout_width =“0dp”的空FrameLayout;后者导致它不显示,直到它被Fragment替换。事实上,task_detail_container只存在于宽视图中,在代码中进行测试,以控制Fragment和Activity之间的切换,因此如果在应用程序运行时切换方向,代码将正确显示。
注意,Fragment不是一个Activity。所有相同的生命周期方法(配方1.2)是可用的,但有另外几个。应牢记以下事项:
•在需要Context或Activity引用的API调用的片段中调用getActivity();
•实现onCreateView()以将View与活动的View连接;
•实现onActivityCreated()以在您的所有者活动完全设置时收到通知。
请注意,onCreateView()(而不是onCreate())是您应该创建您的视图,并且您负责自己填充视图,例如,

public View onCreateView(LayoutInflater inf, ViewGroup container) {
return inf.inflate(R.layout.__ThisFragment'sLayout__, container, false);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值