创建List

编写: roya 原文:https://developer.android.com/training/wearables/ui/lists.html

List让用户在可穿戴设备上很容易地从一组选项中选择一个项目。这个课程介绍了如何在Android Wear应用中创建List。

Wearable UI库包含了WearableListView类,该类是对可穿戴设备进行优化的List实现。

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

为了在Android Wear应用中创建List,我们需要:

  1. 添加WearableListView元素到activity的layout定义中。
  2. 为List选项创建一个自定义的layout实现。
  3. 使用这个实现为List选项创建一个layout定义文件。
  4. 创建一个adapter以填充List。
  5. 指定这个adapter到WearableListView元素。

下面的章节有这些步骤的详细描述。

创建List - 图1

Figure 3: 在Android Wear上的List View.

添加List View

下面的layout使用BoxInsetLayout添加了一个List view到activity中,所以这个List可以正确地显示在圆形和方形两种设备上:

  1. <android.support.wearable.view.BoxInsetLayout
  2. xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. android:background="@drawable/robot_background"
  5. android:layout_height="match_parent"
  6. android:layout_width="match_parent">
  7. <FrameLayout
  8. android:id="@+id/frame_layout"
  9. android:layout_height="match_parent"
  10. android:layout_width="match_parent"
  11. app:layout_box="left|bottom|right">
  12. <android.support.wearable.view.WearableListView
  13. android:id="@+id/wearable_list"
  14. android:layout_height="match_parent"
  15. android:layout_width="match_parent">
  16. </android.support.wearable.view.WearableListView>
  17. </FrameLayout>
  18. </android.support.wearable.view.BoxInsetLayout>

为List选项创建一个Layou实现

在许多例子中,每个List选项都由一个图标和一个描述组成。Android SDK中的Notifications 例子实现了一个自定义layout:继承LinearLayout以合并两元素到每个List选项。这个layout也实现了 WearableListView.OnCenterProximityListener接口里的方法,以实现在用户在List中滚动时,因WearableListView的事件而改变选项图标颜色和渐隐文字:

  1. public class WearableListItemLayout extends LinearLayout
  2. implements WearableListView.OnCenterProximityListener {
  3. private ImageView mCircle;
  4. private TextView mName;
  5. private final float mFadedTextAlpha;
  6. private final int mFadedCircleColor;
  7. private final int mChosenCircleColor;
  8. public WearableListItemLayout(Context context) {
  9. this(context, null);
  10. }
  11. public WearableListItemLayout(Context context, AttributeSet attrs) {
  12. this(context, attrs, 0);
  13. }
  14. public WearableListItemLayout(Context context, AttributeSet attrs,
  15. int defStyle) {
  16. super(context, attrs, defStyle);
  17. mFadedTextAlpha = getResources()
  18. .getInteger(R.integer.action_text_faded_alpha) / 100f;
  19. mFadedCircleColor = getResources().getColor(R.color.grey);
  20. mChosenCircleColor = getResources().getColor(R.color.blue);
  21. }
  22. // Get references to the icon and text in the item layout definition
  23. @Override
  24. protected void onFinishInflate() {
  25. super.onFinishInflate();
  26. // These are defined in the layout file for list items
  27. // (see next section)
  28. mCircle = (ImageView) findViewById(R.id.circle);
  29. mName = (TextView) findViewById(R.id.name);
  30. }
  31. @Override
  32. public void onCenterPosition(boolean animate) {
  33. mName.setAlpha(1f);
  34. ((GradientDrawable) mCircle.getDrawable()).setColor(mChosenCircleColor);
  35. }
  36. @Override
  37. public void onNonCenterPosition(boolean animate) {
  38. ((GradientDrawable) mCircle.getDrawable()).setColor(mFadedCircleColor);
  39. mName.setAlpha(mFadedTextAlpha);
  40. }
  41. }

我们也可以创建animator对象以放大List中间选项的图标。我们可以使用WearableListView.OnCenterProximityListener接口的onCenterPosition()onNonCenterPosition()回调方法来管理animator对象。更多关于animator对象的信息请查看Animating with ObjectAnimator

为Items创建Layout解释

在为List选项实现自定义layout之后,我们需要提供一个layout解释文件以具体说明list item中的组件参数。下面的layout使用先前的自定义layout实现,并且定义图标和文本view,这两个view的ID对应layout实现类的ID:

res/layout/list_item.xml

  1. <com.example.android.support.wearable.notifications.WearableListItemLayout
  2. xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:gravity="center_vertical"
  4. android:layout_width="match_parent"
  5. android:layout_height="80dp">
  6. <ImageView
  7. android:id="@+id/circle"
  8. android:layout_height="20dp"
  9. android:layout_margin="16dp"
  10. android:layout_width="20dp"
  11. android:src="@drawable/wl_circle"/>
  12. <TextView
  13. android:id="@+id/name"
  14. android:gravity="center_vertical|left"
  15. android:layout_width="wrap_content"
  16. android:layout_marginRight="16dp"
  17. android:layout_height="match_parent"
  18. android:fontFamily="sans-serif-condensed-light"
  19. android:lineSpacingExtra="-4sp"
  20. android:textColor="@color/text_color"
  21. android:textSize="16sp"/>
  22. </com.example.android.support.wearable.notifications.WearableListItemLayout>

创建Adapter以填充List

Adapter用内容填充WearableListView。下面的adapter基于strings数组元素填充了List:

  1. private static final class Adapter extends WearableListView.Adapter {
  2. private String[] mDataset;
  3. private final Context mContext;
  4. private final LayoutInflater mInflater;
  5. // Provide a suitable constructor (depends on the kind of dataset)
  6. public Adapter(Context context, String[] dataset) {
  7. mContext = context;
  8. mInflater = LayoutInflater.from(context);
  9. mDataset = dataset;
  10. }
  11. // Provide a reference to the type of views you're using
  12. public static class ItemViewHolder extends WearableListView.ViewHolder {
  13. private TextView textView;
  14. public ItemViewHolder(View itemView) {
  15. super(itemView);
  16. // find the text view within the custom item's layout
  17. textView = (TextView) itemView.findViewById(R.id.name);
  18. }
  19. }
  20. // Create new views for list items
  21. // (invoked by the WearableListView's layout manager)
  22. @Override
  23. public WearableListView.ViewHolder onCreateViewHolder(ViewGroup parent,
  24. int viewType) {
  25. // Inflate our custom layout for list items
  26. return new ItemViewHolder(mInflater.inflate(R.layout.list_item, null));
  27. }
  28. // Replace the contents of a list item
  29. // Instead of creating new views, the list tries to recycle existing ones
  30. // (invoked by the WearableListView's layout manager)
  31. @Override
  32. public void onBindViewHolder(WearableListView.ViewHolder holder,
  33. int position) {
  34. // retrieve the text view
  35. ItemViewHolder itemHolder = (ItemViewHolder) holder;
  36. TextView view = itemHolder.textView;
  37. // replace text contents
  38. view.setText(mDataset[position]);
  39. // replace list item's metadata
  40. holder.itemView.setTag(position);
  41. }
  42. // Return the size of your dataset
  43. // (invoked by the WearableListView's layout manager)
  44. @Override
  45. public int getItemCount() {
  46. return mDataset.length;
  47. }
  48. }

连接Adapter和设置Click Listener

在我们的activity中,从layout中取得WearableListView元素的引用,分配一个adapter实例以填充List,然后设置一个click listener以完成当用户选择了一个特定的List选项的动作。

  1. public class WearActivity extends Activity
  2. implements WearableListView.ClickListener {
  3. // Sample dataset for the list
  4. String[] elements = { "List Item 1", "List Item 2", ... };
  5. @Override
  6. protected void onCreate(Bundle savedInstanceState) {
  7. super.onCreate(savedInstanceState);
  8. setContentView(R.layout.my_list_activity);
  9. // Get the list component from the layout of the activity
  10. WearableListView listView =
  11. (WearableListView) findViewById(R.id.wearable_list);
  12. // Assign an adapter to the list
  13. listView.setAdapter(new Adapter(this, elements));
  14. // Set a click listener
  15. listView.setClickListener(this);
  16. }
  17. // WearableListView click listener
  18. @Override
  19. public void onClick(WearableListView.ViewHolder v) {
  20. Integer tag = (Integer) v.itemView.getTag();
  21. // use this data to complete some action ...
  22. }
  23. @Override
  24. public void onTopEmptyRegionClick() {
  25. }
  26. }