创建2D Picker

编写: roya 原文:https://developer.android.com/training/wearables/ui/2d-picker.html

Android Wear中的2D Picker模式允许用户像换页一样从一组选项中导航和选择。Wearable UI库让我们可以容易地用一个page grid来实现这个模式。其中,page grid是一个layout管理器,它允许用户垂直和水平滚动页面。

要实现这个模式,我们需要添加一个GridViewPager元素到activity的layout中,然后实现一个继承FragmentGridPagerAdapter类的adapter以提供一组页面。

Note: Android SDK中的GridViewPager例子示范了如何在应用中使用 GridViewPager layout。这个例子的位于android-sdk/samples/android-20/wearable/GridViewPager目录中。

添加Page Grid

像下面一样添加一个GridViewPager元素到layout描述文件:

  1. <android.support.wearable.view.GridViewPager
  2. xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:id="@+id/pager"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent" />

我们可以使用任何定义Layouts技术以保证2D picker可以工作在圆形和方形两种设备上。

实现Page Adapter

Page Adapter提供一组页面以填充GridViewPager部件。要实现这个adapter,需要继承Wearable UI库中的FragmentGridPageAdapter类。

举个例子,Android SDK内的GridViewPager例子中包含了下面的adapter实现,该实现提供一组静态的具有自定义背景图片的card:

  1. public class SampleGridPagerAdapter extends FragmentGridPagerAdapter {
  2. private final Context mContext;
  3. public SampleGridPagerAdapter(Context ctx, FragmentManager fm) {
  4. super(fm);
  5. mContext = ctx;
  6. }
  7. static final int[] BG_IMAGES = new int[] {
  8. R.drawable.debug_background_1, ...
  9. R.drawable.debug_background_5
  10. };
  11. // A simple container for static data in each page
  12. private static class Page {
  13. // static resources
  14. int titleRes;
  15. int textRes;
  16. int iconRes;
  17. ...
  18. }
  19. // Create a static set of pages in a 2D array
  20. private final Page[][] PAGES = { ... };
  21. // Override methods in FragmentGridPagerAdapter
  22. ...
  23. }

picker调用getFragmentgetBackground来取得内容以显示到grid的每个位置中。

  1. // Obtain the UI fragment at the specified position
  2. @Override
  3. public Fragment getFragment(int row, int col) {
  4. Page page = PAGES[row][col];
  5. String title =
  6. page.titleRes != 0 ? mContext.getString(page.titleRes) : null;
  7. String text =
  8. page.textRes != 0 ? mContext.getString(page.textRes) : null;
  9. CardFragment fragment = CardFragment.create(title, text, page.iconRes);
  10. // Advanced settings (card gravity, card expansion/scrolling)
  11. fragment.setCardGravity(page.cardGravity);
  12. fragment.setExpansionEnabled(page.expansionEnabled);
  13. fragment.setExpansionDirection(page.expansionDirection);
  14. fragment.setExpansionFactor(page.expansionFactor);
  15. return fragment;
  16. }
  17. // Obtain the background image for the page at the specified position
  18. @Override
  19. public ImageReference getBackground(int row, int column) {
  20. return ImageReference.forDrawable(BG_IMAGES[row % BG_IMAGES.length]);
  21. }

getRowCount方法告诉picker有多少行内容是可获得的,getColumnCount方法告诉picker每行中有多少列内容是可获得的。

  1. // Obtain the number of pages (vertical)
  2. @Override
  3. public int getRowCount() {
  4. return PAGES.length;
  5. }
  6. // Obtain the number of pages (horizontal)
  7. @Override
  8. public int getColumnCount(int rowNum) {
  9. return PAGES[rowNum].length;
  10. }

adapter是实现细节取决于我们指定的某组页面。由adapter提供的每个页面是Fragement类型。在这个例子中,每个页面是一个使用默认card layouts的CardFragment实例。然而,我们可以在同一个2D picker混合不同类型的页面,比如cards,action icons,和自定义layouts,由具体情况决定。

不是所有行都需要有同样数量的页面。注意这个例子中的每行有不同的列数。我们也可以用一个 GridViewPager 组件实现只有一行或一列的1D picker。

创建2D Picker - 图1

Figure 1: GridViewPager例子

对于那些超出设备屏幕大小的card,GridViewPager为它们提供了滚动支持。这个例子配置了每张card可以按照需要进行展开,所以用户可以滚动卡片的内容。当用户滚动到card的尽头,向同一方向滑动将显示grid中的下一页(如果下一页存在的话)。

我们可以使用getBackground()方法自定义每页的背景。当用户在页面间滑动时,GridViewPager自动在不同的背景之间使用视差滚动和淡出效果。

分配adapter实例给page grid

在activity中,分配一个adapter实现实例给GridViewPager组件:

  1. public class MainActivity extends Activity {
  2. @Override
  3. protected void onCreate(Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. setContentView(R.layout.activity_main);
  6. ...
  7. final GridViewPager pager = (GridViewPager) findViewById(R.id.pager);
  8. pager.setAdapter(new SampleGridPagerAdapter(this, getFragmentManager()));
  9. }
  10. }