下例中实验了上面所讲的所有内容。此例有一个activity,其含有两个fragment。一个显示莎士比亚剧的播放曲目,另一个显示选中曲目的摘要。此例还演示了如何跟据屏幕大小配置fragment

activity创建layout

@Overrideprotectedvoid onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   setContentView(R.layout.fragment_layout);}

activitylayoutxml文档

<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加载此 layout时初始化 TitlesFragment(用于显示标题列表), TitlesFragment的右边是一个 FrameLayout,用于存放显示摘要的 fragment,但是现在它还是空的, fragment只有当用户选择了一项标题后,摘要 fragment才会被放到 FrameLayout中。

然而,并不是所有的屏幕都有足够的宽度来容纳标题列表和摘要。所以,上述layout只用于横屏,现把它存放于ret/layout-land/fragment_layout.xml

之外,当用于竖屏时,系统使用下面的layout,它存放于ret/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>

这个layout只包含TitlesFragment。这表示当使用竖屏时,只显示标题列表。当用户选中一项时,程序会启动一个新的activity去显示摘要,而不是加载第二个fragment

下一步,你会看到Fragment类的实现。第一个是TitlesFragment,它从ListFragment派生,大部分列表的功能由ListFragment提供。

当用户选择一个Title时,代码需要做出两种行为,一种是在同一个activity中显示创建并显示摘要fragment,另一种是启动一个新的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();        ft.replace(R.id.details, 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);    }  }

第二个 fragmentDetailsFragment显示被选择的 Title的摘要:

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;  }}

如果当前的 layout没有 R.id.detailsView(它被用于 DetailsFragment的容器),那么程序就启动 DetailsActivity来显示摘要。

下面是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会接管它并显示出 TitlesFragmentDetailsFragment。这可以在用户在竖屏时显示在 TitleFragment,但用户旋转了屏幕,使显示变成了横屏。

更多相关文章

  1. 修改编译Nexus5x android7.0.1(N)版本内核(AOSP)
  2. Android(安卓)高清加载长图或大图方案
  3. Android(安卓)Studio自带的底部导航栏 实现从其他Activity跳转到
  4. Android自带的下载功能,不需要断点续传、大文件下载、通知栏显示
  5. Android(安卓)使用SeekBar时动态显示进度且随SeekBar一起移动
  6. Android(安卓)Dialog种类大全,让Activity显示在另外一个Activity
  7. AndroidStudio快捷键
  8. GreenDao使用心得
  9. Android(安卓)一键直接查看Sqlite数据库数据

随机推荐

  1. Android获取窗体信息的Util方法
  2. Android仿“知乎”隐藏标题栏、回答详情
  3. android phoneGap 静态页面中简单的数据
  4. android 8 sdk源码编译时报错Try increas
  5. 新思路_Android同时显示多个跑马灯
  6. 转载:Android uses-permission大全
  7. 十二个android编程技巧
  8. Android 官方文档 Google Services
  9. Android SDK 版本的简称
  10. 手动生成Android的R.java文件