Android应用组件之片段(Fragment)介绍5
来源:互联网 发布:电信网络新型诈骗 编辑:程序博客网 时间:2024/06/16 10:22
1 示例
为了将本文阐述的所有内容融会贯通,以下提供了一个示例,其中的 Activity 使用两个片段来创建一个双窗格布局。 下面的 Activity 包括两个片段:一个用于显示莎士比亚戏剧标题列表,另一个用于从列表中选定戏剧时显示其摘要。 此外,它还展示了如何根据屏幕配置提供不同的片段配置。
主 Activity 会在 onCreate() 期间以常规方式应用布局:
@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.fragment_layout);}
应用的布局为 fragment_layout.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 class="com.example.android.apis.app.FragmentLayout$TitlesFragment" android:id="@+id/titles" android:layout_weight="1" android:layout_width="0px" android:layout_height="match_parent" /> <FrameLayout android:id="@+id/details" android:layout_weight="1" android:layout_width="0px" android:layout_height="match_parent" android:background="?android:attr/detailsElementBackground" /></LinearLayout>
通过使用此布局,系统可在 Activity 加载布局时立即实例化 TitlesFragment(列出戏剧标题),而 FrameLayout(用于显示戏剧摘要的片段所在位置)则会占用屏幕右侧的空间,但最初处于空白状态。 正如您将在下文所见的那样,用户从列表中选择某个项目后,系统才会将片段放入 FrameLayout。
不过,并非所有屏幕配置都具有足够的宽度,可以并排显示戏剧列表和摘要。 因此,以上布局仅用于横向屏幕配置(布局保存在 res/layout-land/fragment_layout.xml)。因此,当屏幕纵向显示时,系统会应用以下布局(保存在 res/layout/fragment_layout.xml):
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment class="com.example.android.apis.app.FragmentLayout$TitlesFragment" android:id="@+id/titles" android:layout_width="match_parent" android:layout_height="match_parent" /></FrameLayout>
此布局仅包括 TitlesFragment。这意味着,当设备纵向显示时,只有戏剧标题列表可见。 因此,当用户在此配置中点击某个列表项时,应用会启动一个新 Activity 来显示摘要,而不是加载另一个片段。
接下来,您可以看到如何在片段类中实现此目的。第一个片段是 TitlesFragment,它显示莎士比亚戏剧标题列表。该片段扩展了 ListFragment,并依靠它来处理大多数列表视图工作。
当您检查此代码时,请注意,用户点击列表项时可能会出现两种行为:系统可能会创建并显示一个新片段,从而在同一 Activity 中显示详细信息(将片段添加到 FrameLayout),也可能会启动一个新 Activity(在该 Activity 中可显示片段),具体取决于这两个布局中哪一个处于活动状态。
public static class TitlesFragment extends ListFragment { boolean mDualPane; int mCurCheckPosition = 0; @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // Populate list with our static array of titles. setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_activated_1, Shakespeare.TITLES)); // Check to see if we have a frame in which to embed the details // fragment directly in the containing UI. View detailsFrame = getActivity().findViewById(R.id.details); mDualPane = detailsFrame != null && detailsFrame.getVisibility() == View.VISIBLE; if (savedInstanceState != null) { // Restore last state for checked position. mCurCheckPosition = savedInstanceState.getInt("curChoice", 0); } if (mDualPane) { // In dual-pane mode, the list view highlights the selected item. getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); // Make sure our UI is in the correct state. showDetails(mCurCheckPosition); } } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt("curChoice", mCurCheckPosition); } @Override public void onListItemClick(ListView l, View v, int position, long id) { showDetails(position); } /** * Helper function to show the details of a selected item, either by * displaying a fragment in-place in the current UI, or starting a * whole new activity in which it is displayed. */ void showDetails(int index) { mCurCheckPosition = index; if (mDualPane) { // We can display everything in-place with fragments, so update // the list to highlight the selected item and show the data. getListView().setItemChecked(index, true); // Check what fragment is currently shown, replace if needed. DetailsFragment details = (DetailsFragment) getFragmentManager().findFragmentById(R.id.details); if (details == null || details.getShownIndex() != index) { // Make new fragment to show this selection. details = DetailsFragment.newInstance(index); // Execute a transaction, replacing any existing fragment // with this one inside the frame. FragmentTransaction ft = getFragmentManager().beginTransaction(); if (index == 0) { ft.replace(R.id.details, details); } else { ft.replace(R.id.a_item, details); } ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); ft.commit(); } } else { // Otherwise we need to launch a new activity to display // the dialog fragment with selected text. Intent intent = new Intent(); intent.setClass(getActivity(), DetailsActivity.class); intent.putExtra("index", index); startActivity(intent); } }}
第二个片段 DetailsFragment
显示从 TitlesFragment
的列表中选择的项目的戏剧摘要:
public static class DetailsFragment extends Fragment { /** * Create a new instance of DetailsFragment, initialized to * show the text at 'index'. */ public static DetailsFragment newInstance(int index) { DetailsFragment f = new DetailsFragment(); // Supply index input as an argument. Bundle args = new Bundle(); args.putInt("index", index); f.setArguments(args); return f; } public int getShownIndex() { return getArguments().getInt("index", 0); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (container == null) { // We have different layouts, and in one of them this // fragment's containing frame doesn't exist. The fragment // may still be created from its saved state, but there is // no reason to try to create its view hierarchy because it // won't be displayed. Note this is not needed -- we could // just run the code below, where we would create and return // the view hierarchy; it would just never be used. return null; } ScrollView scroller = new ScrollView(getActivity()); TextView text = new TextView(getActivity()); int padding = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, getActivity().getResources().getDisplayMetrics()); text.setPadding(padding, padding, padding, padding); scroller.addView(text); text.setText(Shakespeare.DIALOGUE[getShownIndex()]); return scroller; }}
从 TitlesFragment
类中重新调用,如果用户点击某个列表项,且当前布局“根本不”包括 R.id.details
视图(即 DetailsFragment
所属视图),则应用会启动 DetailsActivity
Activity 以显示该项目的内容。以下是 DetailsActivity
,它简单地嵌入了 DetailsFragment
,以在屏幕为纵向时显示所选的戏剧摘要:
public static class DetailsActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { // If the screen is now in landscape mode, we can show the // dialog in-line with the list so we don't need this activity. finish(); return; } if (savedInstanceState == null) { // During initial setup, plug in the details fragment. DetailsFragment details = new DetailsFragment(); details.setArguments(getIntent().getExtras()); getFragmentManager().beginTransaction().add(android.R.id.content, details).commit(); } }}
请注意,如果配置为横向,则此 Activity 会自行完成,以便主 Activity 可以接管并沿 TitlesFragment
显示 DetailsFragment
。如果用户在纵向显示时启动 DetailsActivity
,但随后旋转为横向(这会重启当前 Activity),就可能出现这种情况。
- Android应用组件之片段(Fragment)介绍5
- Android应用组件之片段(Fragment)介绍1
- Android应用组件之片段(Fragment)介绍2
- Android应用组件之片段(Fragment)介绍3
- Android应用组件之片段(Fragment)介绍4
- Android之片段Fragment的介绍(一)
- Android学习之Fragment(片段)
- Android之片段Fragment的实践(二)
- Android应用组件之Activity介绍1
- Android应用组件之Activity介绍2
- Android应用组件之Activity介绍3
- 四大组件之Activity的瘦身版Fragment(片段)
- Android之---Fragment介绍
- Android开发者指南-片段(Fragment)
- Android-Fragment碎片-片段
- Android之fragment介绍及fragment详解
- 【Android基础】Fragment 详解之Fragment介绍
- 片段(Fragment)
- UE4 崩溃记录(随时更新)
- 疯牛
- n&1 判断奇偶
- 【Java多线程与并发库】07 Java中的13个原子操作类
- Irrlicht 源码学习笔记 【plane3d.h】【plane3dex.h】
- Android应用组件之片段(Fragment)介绍5
- 如何设置Tomcat使域名指向指定的文件夹
- Eslint 配置规则大全
- Adobe Audition
- PHP PDO操作MYSQL
- 滑动冲突解决
- 【OpenCV3.3】特征值、奇异值分解与图像矩阵重构
- 19muduo_base库源码分析(十)
- 2017CCPC网赛1003