Creating Custom UIs for Wear Devices

<翻译>创建自定义的手表设备UIs Previous Next Get started

Dependencies and Prerequisites

  • Android 4.4W (API level 20) or higher on the wearable device

User interfaces for wearable apps differ significantly from those built for handheld devices. Apps for wearables should follow the Android Weardesign principles and implement the recommendedUI patterns, which ensure a consistent user experience across apps that is optimized for wearables.

This class teaches you how to create custom UIs for your wearable apps and custom notifications that look good on any Android Wear device by implementing these UI patterns:

  • Cards
  • Countdowns and confirmations
  • Long press to dismiss
  • 2D Pickers
  • Selection lists

The Wearable UI Library, which is part of the Google Repository in the Android SDK, provides classes that help you implement these patterns and create layouts that work on both round and square Android Wear devices.

Note: We recommend using Android Studio for Android Wear development, as it provides project setup, library inclusion, and packaging conveniences. This training assumes you are using Android Studio.

<翻译>依赖和前提准备 手表设备版本为Android 4.4(API level 20)或者更高 手表应用的用户界面和建立在手机上麦你的用户界面有着本质的区别。手表端的应用应该遵循 design principles原则并且实现推荐的 UI patterns,这些保证了为手表端优化过的应用的用户体验始终如一。
这个课程教你如何给  wearable apps 和  custom notifications 创建自定义的UIs,这个UIs通过实现了下面的UI 模式让他们在android wear设备上面显示的很好: 1:卡片 2:读秒Countdowns和确认。 3:长按去解除 4:2D Pickers 5:选择列表
手表UI的库,是Android SDK 中Google 资源库(Repository)中的一部分,提供了一些类,这些类帮助你实现这些模版并且创建可以在圆形和方形的手表设备上面都能运行的布局。 注意:我们建议使用Android Studio 去开发Android Wear。

Lessons



Defining Layouts
Learn how to create layouts that look good on round and square Android Wear devices.
Creating Cards
Learn how to create cards with custom layouts.
Creating Lists
Learn how to create lists that are optimized for wearable devices.
Creating a 2D Picker
Learn how to implement the 2D Picker UI pattern to navigate through pages of data.
Showing Confirmations
Learn how to display confirmation animations when users complete actions.
Exiting Full-Screen Activities
Learn how to implement the long-press-to-dismiss UI pattern to exit full-screen activities.
<翻译> 课程
1: 定义布局 学习怎么创建在方形和圆形的手表设备上面可以很好展示的布局, 2:创建卡片 学习如何创建自定义布局的卡片 3:创建列表 学习如何创建为手表设备优化了的列表 4:创建一个2D Picker,( 注意了,2D Picker就是二维选择器,这里的二维就是左右上下,例如可以左右的翻页,上下的查看,1D Picker就是一维选择器,例如listview。D代表了Direction 方向学习实现2D Picker 界面模式,然后通过也的数据导航 5:显示确认页面 学习如何展示确认动画单用户完成了actions 6:推出全屏的activitys 学习 如何实现长按接触的UI 模式去推出全屏的activities

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

1:定义布局

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Defining Layouts

Previous Next

This lesson teaches you to

  1. Add the Wearable UI Library
  2. Specify Different Layouts for Square and Round Screens
  3. Use a Shape-Aware Layout

You should also read

  • Android Wear Design Principles

Video

  • Full Screen Apps for Android Wear

Wearables use the same layout techniques as handheld Android devices, but need to be designed with specific constraints. Do not port functionality and the UI from a handheld app and expect a good experience. For more information on how to design great wearable apps, read the Android Wear Design Guidelines.

When you create layouts for Android Wear apps, you need to account for devices with square and round screens. Any content placed near the corners of the screen may be cropped on round Android Wear devices, so layouts designed for square screens do not work well on round devices. For a demonstration of this type of problem, see the video Full Screen Apps for Android Wear.

<翻译>手表端和手机端使用相同的布局技术,但是需要用特定的限制(constraint)来设计。布局方面不要使用使用手机端的应用端口功能和UI来实现很好的体验。关于更多的信息请查看怎么设计手表应用,阅读Android Wear Design Guidelines.

当你创建了一个Android 手表应用,你需要考虑圆形后方形的界面。任何的放在边角的内容在运行的android手表设备上面都有可能会阶段。所以为方形的布局设计在运行的设备上面运行的不好。关于这个类型的问题,可以查看这个视频Full Screen Apps for Android Wear.

例如,图片1显示布局在圆形和方形的界面上面的显示

For example, figure 1 shows how the following layout looks on square and round screens:

Android Wear 进阶 - 3 Creating Custom UIs for Wear Devices 创建自定义的手表设备UIs_第1张图片

Figure 1. Demonstration of how a layout designed for square screens does not work well on round screens.

图片1:演示怎么在圆形和方形的手表上面不能运行正常

 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"    android:orientation="vertical">            android:id="@+id/text"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="@string/hello_square" />

The text does not display correctly on devices with round screens.

The Wearable UI Library provides two different approaches to solve this problem:

  • Define different layouts for square and round devices. Your app detects the shape of the device screen and inflates the correct layout at runtime.
  • Use a special layout included in the library for both square and round devices. This layout applies different window insets depending on the shape of the device screen.

You typically use the first approach when you want your app to look different depending on the shape of the device screen. You use the second approach when you want to use a similar layout on both screen shapes without having views cropped near the edges of round screens.

<翻译>

内容在环行的屏幕上面显示不正确。

手表UI库提供了两个不同的方法去解决这个问题:
给圆形的和方形的设备定义不同的布局。你的应用在运行的时候检测到设备的界面并且填充正确的布局
使用特别的布局包含了给环行和方形的设备的库。这个布局依据设备的尺寸来应用不同的窗口插入(inset)

Add the Wearable UI Library添加手表UI库



Android Studio includes the Wearable UI Library on your wear module by default when you use the Project Wizard. To compile your project with this library, ensure that the Extras > Google Repository package is installed in the Android SDK manager and that the following dependency is included in the build.gradle file of yourwear module:

dependencies {    compile fileTree(dir: 'libs', include: ['*.jar'])    compile 'com.google.android.support:wearable:+'    compile 'com.google.android.gms:play-services-wearable:+'}

The 'com.google.android.support:wearable' dependency is required to implement the layout techniques shown in the following sections.

Browse the API reference documentation for the Wearable UI Library classes.

<翻译>当你使用项目向导的时候,Android Studio 默认的情况下是将手表UI 库包含在了wear 的模型中了。为了让你的项目编译这些库,保证在Extras->Google 资源库(Repository)包已经安装在Android SDK 管理其中,下面的依赖已经包含在你的wear模型的build.gradle的文件中了

这个 'com.google.android.support:wearable' 依赖对于实现下面章节的布局显示是必须的。展开 API reference documentation 查看手表UI库的类

Specify Different Layouts for Square and Round Screens

方形和圆形屏幕制定不同的布局

The WatchViewStub class included in the Wearable UI Library lets you specify different layout definitions for square and round screens. This class detects the screen shape at runtime and inflates the corresponding layout.

To use this class for handling different screen shapes in your app:

  1. Add WatchViewStub as the main element of your activity's layout.
  2. Specify a layout definition file for square screens with the rectLayout attribute.
  3. Specify a layout definition file for round screens with the roundLayout attribute.

Define your activity's layout as follows:

<翻译>WatchViewStub 类是包含了手表UI的库,可以是你制定不同的布局定义给方形和圆形的界面。这个类在运行的时候检测了屏幕的尺寸并且填充正确的布局

在你的应用中为了使用这个类来处理不同的屏幕尺寸:

1:将WatchViewStub 作为你的activity 布局的main element

2:通过rectLayout 属性来指定方形屏幕的布局定义

3:通过roundLayout属性来指定圆形的屏幕的布局定义

定义你的acitivyt布局如下

    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:id="@+id/watch_view_stub"    android:layout_width="match_parent"    android:layout_height="match_parent"    app:rectLayout="@layout/rect_activity_wear"   app:roundLayout="@layout/round_activity_wear">

Inflate this layout in your activity:

@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_wear);}

Then create different layout definition files for square and round screens. In this example, you need to create the files res/layout/rect_activity_wear.xml and res/layout/round_activity_wear.xml. You define these layouts in the same way that you create layouts for handheld apps, but taking into account the constraints of wearable devices. The system inflates the correct layout at runtime depending on the screen shape.

<翻译>然后创建不同的布局定义文件给方形和圆形的界面。在这个例子里面,你需要创建两个文件:res/layout/rect_activity_wear.xml and res/layout/round_activity_wear.xml.(对应的就是上面的属性里面的值)。你定义这些布局可以和你在手机端应用创建布局一样,但是要考虑手表设备的一致性。这个系统运行时依赖屏幕尺寸来添加正确的布局。

Accessing layout views访问布局view视图(很重要)

The layouts that you specify for square or round screens are not inflated until WatchViewStub detects the shape of the screen, so your app cannot access their views immediately. To access these views, set a listener in your activity to be notified when the shape-specific layout has been inflated:

<翻译>你给方形和圆形屏幕制定的布局,只有在WatchViewStub 检测到了屏幕尺寸的时候才会来填充这个布局。所以你的应用不能够立马访问到他们的view视图。

为了访问到这些视图,设置一个监听器在你的activity 中,当特定尺寸布局被填充的时候会通知这个监听器。

@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_wear);    WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);    stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {        @Override public void onLayoutInflated(WatchViewStub stub) {            // Now you can access your views            TextView tv = (TextView) stub.findViewById(R.id.text);            ...        }    });}

Use a Shape-Aware Layout 使用尺寸感应布局。





Android Wear 进阶 - 3 Creating Custom UIs for Wear Devices 创建自定义的手表设备UIs_第2张图片Figure 2. Window insets on a round screen.

The BoxInsetLayout class included in the Wearable UI Library extends FrameLayout and lets you define a single layout that works for both square and round screens. This class applies the required window insets depending on the screen shape and lets you easily align views on the center or near the edges of the screen.

The gray square in figure 2 shows the area whereBoxInsetLayout can automatically place its child views on round screens after applying the required window insets. To be displayed inside this area, children views specifythe layout_boxatribute with these values:

  • A combination of topbottomleft, and right. For example, "left|top" positions the child's left and top edges inside the gray square in figure 2.
  • The all value positions all the child's content inside the gray square in figure 2.

On square screens, the window insets are zero and the layout_box attribute is ignored.

<翻译>BoxInsetLayout (Inset 有插入,插图的意思)类包含了手表UI库,它集成了FrameLayout并且可以让你定义一个单独的布局,这个布局可以在方形和圆形的手表上面很好的运行。这个类依据屏幕尺寸应用需要的窗口插入,这个类还让你容易把view视图对其到中心或者靠近屏幕的边缘的位置。

在图片2中的灰色的正方形中显示了区域,BoxInsetLayout在应用了需要的窗口视图时候,可以自动的将他的子视图view 放到这个区域。为了能够显示在这个区域,子视图需要制定layout_box属性为一下的值:

top,bottom,left和right的合并,例如“left|top” 表示 子视图的位置 显示在灰色方块的 左上 边缘

all的值将所有的子视图内容放置在灰色区域内部

在方形屏幕,这个窗口插入是0,并且layout_box 属性会被忽略。

Android Wear 进阶 - 3 Creating Custom UIs for Wear Devices 创建自定义的手表设备UIs_第3张图片


Figure 3. A layout definition that works on both square and round screens.

The layout shown in figure 3 uses the  element and works on square and round screens:

<翻译> 图片3 一个在方形和圆形屏幕上面都运行的很好的布局定义

在图片3中布局使用了 项目并且布局在方形和圆形屏上面运行的很好

<android.support.wearable.view.BoxInsetLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:background="@drawable/robot_background"    android:layout_height="match_parent"    android:layout_width="match_parent"    android:padding="15dp">            android:layout_width="match_parent"        android:layout_height="match_parent"        android:padding="5dp"        app:layout_box="all">                    android:gravity="center"            android:layout_height="wrap_content"            android:layout_width="match_parent"            android:text="@string/sometext"            android:textColor="@color/black" />                    android:background="@null"            android:layout_gravity="bottom|left"            android:layout_height="50dp"            android:layout_width="50dp"            android:src="@drawable/ok" />                    android:background="@null"            android:layout_gravity="bottom|right"            android:layout_height="50dp"            android:layout_width="50dp"            android:src="@drawable/cancel" />    

Notice the parts of the layout marked in bold:

  • android:padding="15dp"

    This line assigns padding to the  element. Because the window insets on round devices are larger than 15dp, this padding only applies to square screens.

  • android:padding="5dp"

    This line assigns padding to the inner FrameLayout element. This padding applies to both square and round screens. The total padding between the buttons and the window insets is 20 dp on square screens (15+5) and 5 dp on round screens.

  • app:layout_box="all"

    This line ensures that the FrameLayout element and its children are boxed inside the area defined by the window insets on round screens.This line has no effect on square screens.

<翻译> 注意上面的布局中标识为粗体(bold)的部分: android:padding="15dp" 这行将padding 赋值给  项目,因为窗口插入在圆形设备上面大雨15dp, 这个padding 只是应用在方形设备上面的额。
android:padding="5dp" 这行赋值给FrameLayout项目,这个padding 在方形和圆形屏幕上面都应用,所以呢,总共的padding值在按钮和窗口插入之间的在方形上面是20(15+5),在圆形上面是5
app:layout_box="all" 这行保证了在圆形屏幕上面,FrameLayout项目和他的子项目会被放置在窗口插入定义的区域。 对于方形屏幕,这个行是没有用的。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

2: Creating Cards 创建卡片

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Creating Cards

Previous Next

This lesson teaches you to

  1. Create a Card Fragment
  2. Add a Card to Your Layout

You should also read

  • Android Wear Design Principles

Cards present information to users with a consistent look and feel across different apps. This lesson shows you how to create cards in your Android Wear apps.

The Wearable UI Library provides implementations of cards specifically designed for wearable devices. This library contains the CardFrame class, which wraps views inside a card-styled frame with a white background, rounded corners, and a light-drop shadow. A CardFrame instance can only contain one direct child, usually a layout manager, to which you can add other views to customize the content inside the card.

<翻译>

卡片向用户展示信息,在不同的应用之间使用同意的外观。这个课程教你如何在Android 手表应用中去创建卡片。

手表UI库提供了卡片实现需要的手表设备的特殊设计。这个库包含了CardFrame这个类,他将视图view包含在内部的一个卡片样式的frame,这个frame有白色的北京,圆形的脚和一个高亮的下拉的隐藏。一个CardFrame实力只能包含一个直接的子组件。一般这个子组件就是布局管理器,通过这个布局管理器,你可以将其他的视图添加进来自定义卡片内部的内容。

You can add cards to your app in two ways:<翻译>你可以通过一下的两种方式来添加卡片

  • Use or extend the CardFragment class.<翻译>使用或者扩展CardFragment的类
  • Add a card inside a CardScrollView instance in your layout.<翻译>在你布局的CardScrollView实例里面添加一个card

Note: This lesson shows you how to add cards to Android Wear activities. Android notifications on wearable devices are also displayed as cards.For more information, see Adding Wearable Features to Notifications.<翻译>注意了:这节课告诉你如何去添加卡片到android wear的activity。在手表设备上面的android 通知就是是使用卡片来显示的。更多的信息,请查看 Adding Wearable Features to Notifications

Create a Card Fragment创建一个卡片fragment(CardFragment)



The CardFragment class provides a default card layout with a title, a description, and an icon. Use this approach to add cards to your app if the default card layout shown in figure 1 meets your needs.<翻译> CardFragment 提供了一个默认的卡片布局,一个标题,一个描述,一个icon图表。如果默认的卡片布局在下面的图表1中符合你的要求,那么使用这个方法去添加cards到你的应用里面。

Android Wear 进阶 - 3 Creating Custom UIs for Wear Devices 创建自定义的手表设备UIs_第4张图片


Figure 1. The default CardFragment layout.

To add a CardFragment instance to your app:

  1. In your layout, assign an ID to the element that contains the card
  2. Create a CardFragment instance in your activity
  3. Use the fragment manager to add the CardFragment instance to its container

The following sample code shows the code for the screen display shown in figure 1:

<翻译>图表1:默认的CardFragment布局:

如何添加一个CardFragment实例到你的应用中:

1:在你布局里面FrameLayout或者其他包含了卡片的布局上面添加id

2:在activity 中添加CardFragment 实例

3:使用fragment 管理器将CardFragment的实例添加到包含卡片的布局中。

下面的实例代码展示了图片一种屏幕展示的代码

xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:background="@drawable/robot_background"android:layout_height="match_parent"android:layout_width="match_parent">            android:id="@+id/frame_layout"        android:layout_width="match_parent"        android:layout_height="match_parent"        app:layout_box="bottom">    

The following code adds the CardFragment instance to the activity in figure 1:

protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_wear_activity2);    FragmentManager fragmentManager = getFragmentManager();    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();    CardFragment cardFragment = CardFragment.create(getString(R.string.cftitle),                                                    getString(R.string.cfdesc),                                                    R.drawable.p);    fragmentTransaction.add(R.id.frame_layout, cardFragment);    fragmentTransaction.commit();}

To create a card with a custom layoutusing the CardFragment class, extend the class and override itsonCreateContentView method.

<翻译>为了创建一个有自定义的布局的卡片使用CardFragment类,扩展这个类,并且重写onCreateContentView的方法。

Add a CardFrame to Your Layout 将CardFrame 添加到你的布局中



You can also add a card directly to your layout definition, as shown in figure 2. Use this approach when you want to define a custom layout for the card inside a layout definition file.<翻译>你也可以向图表2中所示的直接将卡片添加到你的布局定义中。使用这个方法如果你想要定义一个自定义的卡片布局包含了布局定义的文件。

Android Wear 进阶 - 3 Creating Custom UIs for Wear Devices 创建自定义的手表设备UIs_第5张图片

Figure 2. Adding a CardFrame to your layout.

The following layout code sample demonstrates a vertical linear layout with two elements. You can create more complex layouts to fit the needs of your app.

<图表2> 添加一个CardFrame 到你的布局:

下面的代码实例演示了一个有两个部分的纵向的线性布局。你可以创建更加复杂的布局去适应你的应用需求

xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:background="@drawable/robot_background"android:layout_height="match_parent"android:layout_width="match_parent">    <android.support.wearable.view.CardScrollView        android:id="@+id/card_scroll_view"        android:layout_height="match_parent"        android:layout_width="match_parent"        app:layout_box="bottom">        <android.support.wearable.view.CardFrame            android:layout_height="wrap_content"            android:layout_width="fill_parent">                            android:layout_height="wrap_content"                android:layout_width="match_parent"                android:orientation="vertical"                android:paddingLeft="5dp">                                    android:fontFamily="sans-serif-light"                    android:layout_height="wrap_content"                    android:layout_width="match_parent"                    android:text="@string/custom_card"                    android:textColor="@color/black"                    android:textSize="20sp"/>                                    android:fontFamily="sans-serif-light"                    android:layout_height="wrap_content"                    android:layout_width="match_parent"                    android:text="@string/description"                    android:textColor="@color/black"                    android:textSize="14sp"/>                    CardFrame>    CardScrollView>

The  element detects the shape of the screen and displays the card differently on round and square devices, using wider side margins on round screens. However, placing the  element inside a  and using the layout_box="bottom" attribute is useful to align the card to the bottom of round screens without cropping its content.

<翻译>   部分检测屏幕的尺寸并且在手表的环形和方形的设备上面展示不同card样式,在圆形的屏幕上面使用宽的边界margin。

然而,将 放在  里面并且使用layout_box="bottom" 的属性对于对齐卡片到环形屏幕的底部并且没有截断它的内容很有用。

Next: Creating Lists Get news & tips 



+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

3:创建list 

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Creating Lists

Previous Next

This lesson teaches you to

  1. Add a List View
  2. Create a Layout Implementation for List Items
  3. Create a Layout Definition for Items
  4. Create an Adapter to Populate the List
  5. Associate the Adapter and Set a Click Listener

Related Samples

  • Notifications

You should also read

  • Android Wear Design Principles

Lists let users select an item from a set of choices easily on wearable devices. This lesson shows you how to create lists in your Android Wear apps.

The Wearable UI Library includes the WearableListView class, which is a list implementation optimized for wearable devices.

<翻译>list 可以让用户在手表设备上面从一个选择的集合中简单选择。这个课程将会告诉你如何创建手表应用的list。

手表UI库要包含 WearableListView class,这个类是一个转么为手表端设备优化后的list

To create a list in your Android Wear apps:

  1. Add a WearableListView element to your activity's layout definition.
  2. Create a custom layout implementation for your list items.
  3. Use this implementation to create a layout definition file for your list items.
  4. Create an adapter to populate the list.
  5. Assign the adapter to the WearableListView element.

Figure 1. A list view on Android Wear.

These steps are described in detail in the following sections.

<翻译>为了创建你的android 手表应用:(其实和我们在手机端的listview 是一个道理,就是listview 变成了WearableListView了)

1:添加一个 WearableListView 项到你的activity的布局定义中

2:创建一个自定义的布局实现你的list的项目

3:使用这个实现布局去创建一个布局定义文件给你的list的项目

4:创建adapter 

5:将adapter 赋值给这个 WearableListView 项

图表1:一个android wear上面的list视图

这些步骤会在下面的章节中详细的讲解。


Android Wear 进阶 - 3 Creating Custom UIs for Wear Devices 创建自定义的手表设备UIs_第6张图片

Add a List View 添加一个listview



The following layout adds a list view to an activity using a  element, so the list is displayed properly on both round and square devices:

<翻译> 下面的代码添加了list View 到一个使用了  的activitity中。所以list 可以在方形和圆形的设备上面显示好。

BoxInsetLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:background="@drawable/robot_background"    android:layout_height="match_parent"    android:layout_width="match_parent">    <FrameLayout        android:id="@+id/frame_layout"        android:layout_height="match_parent"        android:layout_width="match_parent"        app:layout_box="left|bottom|right">        <android.support.wearable.view.WearableListView            android:id="@+id/wearable_list"            android:layout_height="match_parent"            android:layout_width="match_parent">            

Create a Layout Implementation for List Items

创建一个布局来实现list items

In many cases, each list item consists of an icon and a description. The Notifications sample implements a custom layout that extends LinearLayout to incorporate these two elements inside each list item. This layout also implements the methods in the WearableListView.OnCenterProximityListener interface to change the color of the item's icon and fade the text in response to events from the WearableListView element as the user scrolls through the list.

<翻译>很多的情况下,list view 是由icon和描述来著称的。通知的例子实现了一个自定义的布局,这个布局集成了LinearLayout去将这两个部分集合在每一个list item 上面。这个不也也实现了在 WearableListView.OnCenterProximityListener 中接口去改变item的icon的颜色,当检测到WearableListView的内容在list 滚动的时候将text文字部分淡去。

public class WearableListItemLayout extends LinearLayout             implements WearableListView.OnCenterProximityListener {    private ImageView mCircle;    private TextView mName;    private final float mFadedTextAlpha;    private final int mFadedCircleColor;    private final int mChosenCircleColor;    public WearableListItemLayout(Context context) {        this(context, null);    }    public WearableListItemLayout(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public WearableListItemLayout(Context context, AttributeSet attrs,                                  int defStyle) {        super(context, attrs, defStyle);        mFadedTextAlpha = getResources()                         .getInteger(R.integer.action_text_faded_alpha) / 100f;        mFadedCircleColor = getResources().getColor(R.color.grey);        mChosenCircleColor = getResources().getColor(R.color.blue);    }    // Get references to the icon and text in the item layout definition    @Override    protected void onFinishInflate() {        super.onFinishInflate();        // These are defined in the layout file for list items        // (see next section)        mCircle = (ImageView) findViewById(R.id.circle);        mName = (TextView) findViewById(R.id.name);    }    @Override    public void onCenterPosition(boolean animate) {        mName.setAlpha(1f);        ((GradientDrawable) mCircle.getDrawable()).setColor(mChosenCircleColor);    }    @Override    public void onNonCenterPosition(boolean animate) {        ((GradientDrawable) mCircle.getDrawable()).setColor(mFadedCircleColor);        mName.setAlpha(mFadedTextAlpha);    }}

You can also create animator objects to enlarge the icon of the center item in the list. You can use theonCenterPosition() and onNonCenterPosition() callback methods in theWearableListView.OnCenterProximityListener interface to manage your animators. For more information about animators, see Animating with ObjectAnimator.

<翻译>你也可以创建动画对象去将list 中间的item变大,你可以使用eonCenterPosition() and onNonCenterPosition() 接口回调的方法WearableListView.OnCenterProximityListener 去管理你的动画。更多的信息,请查看 Animating with ObjectAnimator.

Create a Layout Definition for Items给items 创建一个布局定义



After you implement a custom layout for list items, you provide a layout definition file that specifies the layout parameters of each of the components inside a list item. The following layout definition uses the custom layout implementation from the previous section and defines an icon and a text view whose IDs match those in the layout implementation class:

<翻译>在你实现了一个自定义的list items以后,你提供一个布局定义的文件,这个文件指定了每个list item 里面的布局参数。

下面的布局定义使用在上面章节实现了的自定义的布局,然后定义了一个icon 和text view 这些ids 和实现的类中是一致的,例如circle

res/layout/list_item.xml

WearableListItemLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:gravity="center_vertical"    android:layout_width="match_parent"    android:layout_height="80dp">            android:id="@+id/circle"        android:layout_height="20dp"        android:layout_margin="16dp"        android:layout_width="20dp"        android:src="@drawable/wl_circle"/>            android:id="@+id/name"        android:gravity="center_vertical|left"        android:layout_width="wrap_content"        android:layout_marginRight="16dp"        android:layout_height="match_parent"        android:fontFamily="sans-serif-condensed-light"        android:lineSpacingExtra="-4sp"        android:textColor="@color/text_color"        android:textSize="16sp"/>

Create an Adapter to Populate the List 创建一个adapter 去展示落户在这个list上



The adapter populates the WearableListView.OnCenterProximityListener element with content. The following simple adapter populates the list with elements based on an array of strings:

<翻译>adapter 将 WearableListView.OnCenterProximityListener 和内容结合起来。下面简单的adapter 落户在list 上面,数据来自一个字符数组。

private static final class Adapter extends WearableListView.Adapter {    private String[] mDataset;    private final Context mContext;    private final LayoutInflater mInflater;    // Provide a suitable constructor (depends on the kind of dataset)    public Adapter(Context context, String[] dataset) {        mContext = context;        mInflater = LayoutInflater.from(context);        mDataset = dataset;    }    // Provide a reference to the type of views you're using    public static class ItemViewHolder extends WearableListView.ViewHolder {        private TextView textView;        public ItemViewHolder(View itemView) {            super(itemView);            // find the text view within the custom item's layout            textView = (TextView) itemView.findViewById(R.id.name);        }    }    // Create new views for list items    // (invoked by the WearableListView's layout manager)    @Override    public WearableListView.ViewHolder onCreateViewHolder(ViewGroup parent,                                                          int viewType) {        // Inflate our custom layout for list items        return new ItemViewHolder(mInflater.inflate(R.layout.list_item, null));    }    // Replace the contents of a list item    // Instead of creating new views, the list tries to recycle existing ones    // (invoked by the WearableListView's layout manager)    @Override    public void onBindViewHolder(WearableListView.ViewHolder holder,                                 int position) {        // retrieve the text view        ItemViewHolder itemHolder = (ItemViewHolder) holder;        TextView view = itemHolder.textView;        // replace text contents        view.setText(mDataset[position]);        // replace list item's metadata        holder.itemView.setTag(position);    }    // Return the size of your dataset    // (invoked by the WearableListView's layout manager)    @Override    public int getItemCount() {        return mDataset.length;    }}

Associate the Adapter and Set a Click Listener

将adapter 和list view 绑定,然后设置一个点击事件

In your activity, obtain a reference to the WearableListView.OnCenterProximityListener element from your layout, assign an instance of the adapter to populate the list, and set a click listener to complete an action when the user selects a particular list item.

<在你的activity 中,从你的布局中获取一个 WearableListView.OnCenterProximityListener 的项目的参考,分配一个adapter 的实例去落户于list 上面,然后设置一个点击的事件去完成用户选中其中一个list 项的事件。

public class WearActivity extends Activity                          implements WearableListView.ClickListener {    // Sample dataset for the list    String[] elements = { "List Item 1", "List Item 2", ... };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.my_list_activity);        // Get the list component from the layout of the activity        WearableListView listView =            (WearableListView) findViewById(R.id.wearable_list);        // Assign an adapter to the list        listView.setAdapter(new Adapter(this, elements));        // Set a click listener        listView.setClickListener(this);    }    // WearableListView click listener    @Override    public void onClick(WearableListView.ViewHolder v) {        Integer tag = (Integer) v.itemView.getTag();        // use this data to complete some action ...    }    @Override    public void onTopEmptyRegionClick() {    }}


+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

4: 创建2D Picker

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Creating a 2D Picker

注意了,2D Picker就是二维选择器,这里的二维就是左右上下,例如可以左右的翻页,上下的查看,1D Picker就是一维选择器,例如listview
Previous Next

This lesson teaches you to

  1. Add a Page Grid
  2. Implement a Page Adapter

Related Samples

  • GridViewPager

You should also read

  • Android Wear Design Principles

The 2D Picker pattern in Android Wear allows users to navigate and choose from a set of items shown as pages. The Wearable UI Library lets you easily implement this pattern using a page grid, which is a layout manager that allows users to scroll vertically and horizontally through pages of data.

To implement this pattern, you add a GridViewPager element to the layout of your activity and implement an adapter that provides a set of pages by extending theFragmentGridPagerAdapter class.

<翻译>2D Picker 的模式在android 手表上面允许用户去导航和从一个显示为page的项目集合中选择。(这个和list View 有点区别,listView 是在一页,这个是在不同的页page)。手表UI库允许你通过page grid 来简单的实现这个模式,这个pagegrid 是一个布局管理器,它允许用户去在数据页面通过水平或者垂直滑动

Add a Page Grid添加PageGrid



Add a GridViewPager element to your layout definition as follows:

GridViewPager    xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/pager"    android:layout_width="match_parent"    android:layout_height="match_parent" />

You can use any of the techniques described in Defining Layouts to ensure that your 2D picker works on both round and square devices.

<翻译>你可以使用在 Defining Layouts 中定义的任何的技术去保证你的2D Picker 在圆形和方形的设备上面运行正常。

Implement a Page Adapter 实现一个Page Adapter



A page adapter provides a set of pages to populate a GridViewPager component. To implement this adapter, you extend the FragmentGridPagerAdapter class from the Wearable UI Library

The following snippet shows how to provide a set of static cards with custom background images:

<翻译>一个Page Adapter提供了一个页面的集合去落户GridViewPager的组件。为了实现这个这个adapter,你需要从手表UI库继承 FragmentGridPagerAdapter 类。

下面的片段显示了怎么提供一个静态卡片的集合,这个静态卡片有自定义的背景图片。

public class SampleGridPagerAdapter extends FragmentGridPagerAdapter {    private final Context mContext;    private List mRows;    public SampleGridPagerAdapter(Context ctx, FragmentManager fm) {        super(fm);        mContext = ctx;    }    static final int[] BG_IMAGES = new int[] {        R.drawable.debug_background_1, ...        R.drawable.debug_background_5    };    // A simple container for static data in each page    private static class Page {        // static resources        int titleRes;        int textRes;        int iconRes;        ...    }    // Create a static set of pages in a 2D array    private final Page[][] PAGES = { ... };    // Override methods in FragmentGridPagerAdapter    ...}

The adapter calls getFragment() and getBackgroundForRow() to retrieve the content to display for each row:

<翻译>adapter调用getFragment()和getBackgroundForRow()去取回内容去展示每个行

// Obtain the UI fragment at the specified position@Overridepublic Fragment getFragment(int row, int col) {    Page page = PAGES[row][col];    String title =        page.titleRes != 0 ? mContext.getString(page.titleRes) : null;    String text =        page.textRes != 0 ? mContext.getString(page.textRes) : null;    CardFragment fragment = CardFragment.create(title, text, page.iconRes);    // Advanced settings (card gravity, card expansion/scrolling)    fragment.setCardGravity(page.cardGravity);    fragment.setExpansionEnabled(page.expansionEnabled);    fragment.setExpansionDirection(page.expansionDirection);    fragment.setExpansionFactor(page.expansionFactor);    return fragment;}// Obtain the background image for the row@Overridepublic Drawable getBackgroundForRow(int row) {    return mContext.getResources().getDrawable(            (BG_IMAGES[row % BG_IMAGES.length]), null);}

The following example shows how to retrieve the background to display for a specific page in the grid:

<翻译>下面的例子展示了怎么取回背景去展示在grid 上面的特定page:

// Obtain the background image for the specific page@Overridepublic Drawable getBackgroundForPage(int row, int column) {    if( row == 2 && column == 1) {        // Place image at specified position        return mContext.getResources().getDrawable(R.drawable.bugdroid_large, null);    } else {        // Default to background image for row        return GridPagerAdapter.BACKGROUND_NONE;    }}


The getRowCount() method tells the adapter how many rows of content are available, and thegetColumnCount() method tells the adapter how many columns of content are available for each of the rows.

<翻译> getRowCount方法告诉adapter 有多少行的content 可以使用。getColumnCount方法告诉adapter 每一行有多少的列可以使用

// Obtain the number of pages (vertical)@Overridepublic int getRowCount() {    return PAGES.length;}// Obtain the number of pages (horizontal)@Overridepublic int getColumnCount(int rowNum) {    return PAGES[rowNum].length;}

The adapter implementation details depend on your particular set of pages. Each page provided by the adapter is of type Fragment. In this example, each page is a CardFragment instance that uses one of the default card layouts. However, you can combine different types of pages in the same 2D picker, such as cards, action icons, and custom layouts depending on your use cases.

Android Wear 进阶 - 3 Creating Custom UIs for Wear Devices 创建自定义的手表设备UIs_第7张图片

Figure 1: The GridViewPager sample.

Not all rows need to have the same number of pages. Notice that in this example the number of colums is different for each row. You can also use a GridViewPager component to implement a 1D picker with only one row or only one column.

The GridViewPager class provides support for scrolling in cards whose content does not fit the device screen. This example configures each card to expand as required, so users can scroll through the card's content. When users reach the end of a scrollable card, a swipe in the same direction shows the next page on the grid, if one is available.

You can specify a custom background for each page with thegetBackgroundForPage() method. When users swipe to navigate across pages, the GridViewPager class applies parallax and crossfade effects between different backgrounds automatically.

<翻译>

adapter实现了袭击依赖你的page的特殊设置。adapter 提供的每一页都是以一个Fragment 的类型。在这个例子中,每一页都是CardFragment的实例,这个实例使用了默认的card布局。然而,你可以将不同的页面类型合并到同样的2D Picker中,例如卡片,action的icon和自定义的布局这些都依赖与你使用的案例。

注意了,2D Picker就是二维选择器,这里的二维就是左右上下,例如可以左右的翻页,上下的查看,1D Picker就是一维选择器,例如listview

并不是所有的行都需要有同同样数量的页面的。注意了在这个实例中列的数量在每一行都是不同的。你也可以使用GridViewPager 组件去实现一个1D picker 只有一行或者只有一列。

这个GridViewPager 类提供了支持在card上面滑动,这个卡片的内容无法适应设备的屏幕。这个例子配置了每一个个卡片去按要求展开,所以用户可以在卡片的内容山脉南滑动。如果用户达到了可滑动的卡片的末尾,一个手柄在相同的方向显示了grid的下一页,如果有下一页的话。(这个swipe是不是就是下面的几个小点的)

你可以使用getBackgroundForPage()方法给每一个页面指定一个自定义的背景,当用户swipe到导航十字页面的时候,GridViewPager类应用了视觉差和淡入淡入的小托在不同的背景之间自动的切换。

Assign an adapter instance to the page grid

In your activity, assign an instance of your adapter implementation to the GridViewPager component:

<翻译> 将adapter的实例复制给page grid。

在你的activity 中,分配一个你的adapter 的实例实现到GridViewPager的组件中。

public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        ...        final GridViewPager pager = (GridViewPager) findViewById(R.id.pager);        pager.setAdapter(new SampleGridPagerAdapter(this, getFragmentManager()));    }}



+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

1: 展示确认窗口

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Showing Confirmations

Previous Next

This lesson teaches you to

  1. Use Automatic Confirmation Timers
  2. Show Confirmation Animations

You should also read

  • Android Wear Design Principles

Confirmations in Android Wear apps use the whole screen or a larger portion of it than those in handheld apps. This ensures that users can see these confirmations by just glancing at the screen and that they have large enough touch targets to cancel an action.

<翻译>在android 手表应用的确认页使用整个屏幕或者一个比手机端应用大的份额( portion)。这个保证了用户可以看到确认也通过看手机屏幕,并且用户有足够大的目标去取消一个action。(就像我们说出了语音以后,他会有一个取消的按钮)

The Wearable UI Library helps you show confirmation animations and timers in your Android Wear apps:<翻译>手表UI库帮助你显示确认的动画和倒计时在你的android 手表应用中。

Confirmation timers 确认倒计时
Automatic confirmation timers show users an animated timer that lets them cancel an action they just performed.
<翻译>自动的确认倒计时给用户显示了一个动画的倒计时,它可以让用户取消掉刚才的操作。
Confirmation animations 确认动画
Confirmation animations give users visual feedback when they complete an action.
<翻译> 确认东湖给用户可见的回馈当他们完成了动作。

The following sections show you how to implement these patterns.下面的内容展示了如何实现这些模式

Use Automatic Confirmation Timers使用自动的确认倒计时



Android Wear 进阶 - 3 Creating Custom UIs for Wear Devices 创建自定义的手表设备UIs_第8张图片

Figure 1: A confirmation timer.

Automatic confirmation timers let users cancel an action they just performed. When the user performs the action, your app shows a button to cancel the action with a timer animation and starts the timer. The user has the option to cancel the action until the timer finishes. Your app gets notified if the user cancels the action and when the timer expires.

<翻译>自动确认的倒计时让用户可以取消一个刚才执行的操作。单用户执行了一个操作,你的应用显示了一个有取消操作的按钮,这个按钮还有一个倒计时的动画,然后启动这个倒计时。用户可以选择取消操作的知道倒计时完成之前。你的应用会得到用户取消了操作的通知或者倒计时超时的通知。

To show a confirmation timer when users complete an action in your app:

  1. Add a  element to your layout.
  2. Implement the DelayedConfirmationListener interface in your activity.
  3. Set the duration of the timer and start it when the user completes an action.

Add the  element to your layout as follows:

<翻译>为了当用户在你的应用中完成了操作后显示一个确认的动画:

1:添加一个  项目到你的布局中

2:在你的activity 中实现 的接口

3:设置倒计时并且在用户完成了操作后开始及时。

DelayedConfirmationView    android:id="@+id/delayed_confirm"    android:layout_width="40dp"    android:layout_height="40dp"    android:src="@drawable/cancel_circle"    app:circle_border_color="@color/lightblue"    app:circle_border_width="4dp"    app:circle_radius="16dp">

You can assign a drawable resource to display inside the circle with the android:src attribute and configure the parameters of the circle directly on the layout definition.

To be notified when the timer finishes or when users tap on it, implement the corresponding listener methods in your activity:

<翻译>你可以通过android:src 属性来将一个drawable 的资源分配显示在圆圈中,并且配置圆圈的参数在布局中。

为了在倒计时完成后或者用户取消了之后收到通知,就要实现相应的监听方法。

public class WearActivity extends Activity implements                           DelayedConfirmationView.DelayedConfirmationListener {    private DelayedConfirmationView mDelayedView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_wear_activity);        mDelayedView =                (DelayedConfirmationView) findViewById(R.id.delayed_confirm);        mDelayedView.setListener(this);    }    @Override    public void onTimerFinished(View view) {        // User didn't cancel, perform the action    }    @Override    public void onTimerSelected(View view) {        // User canceled, abort the action    }}

To start the timer, add the following code to the point in your activity where users select an action:

为了启动倒计时,添加下面的代码到你的actiivty的用户选择action的点。

// Two seconds to cancel the actionmDelayedView.setTotalTimeMs(2000);// Start the timermDelayedView.start();
Android Wear 进阶 - 3 Creating Custom UIs for Wear Devices 创建自定义的手表设备UIs_第9张图片

Figure 2: A confirmation animation.

Show Confirmation Animations显示确认动画



To show a confirmation animation when users complete an action in your app, create an intent that starts ConfirmationActivity from one of your activities. You can specify one of the these animations with theEXTRA_ANIMATION_TYPE intent extra:

  • SUCCESS_ANIMATION
  • FAILURE_ANIMATION
  • OPEN_ON_PHONE_ANIMATION

You can also add a message that appears under the confirmation icon.

To use the ConfirmationActivity in your app, first declare this activity in your manifest file:

<翻译>当用户完成了应用中的一个action的时候,为了显示确认的动画,在你的额activit中创建一个intent去启动 ConfirmationActivity 。

你可以通过EXTRA_ANIMATION_TYPE intent extra指定下面的动画。

你也可以在确认的icon 下面添加信息。

为了使用ConfirmationActivity 在你的应用中,首先在清单文件中声明这个actiivty 

      ...            android:name="android.support.wearable.activity.ConfirmationActivity">      

Then determine the result of the user action and start the activity with an intent:

然后确定用户的动作结果并且通过intent来启动activity

Intent intent = new Intent(this, ConfirmationActivity.class);intent.putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE,                ConfirmationActivity.SUCCESS_ANIMATION);intent.putExtra(ConfirmationActivity.EXTRA_MESSAGE,                getString(R.string.msg_sent));startActivity(intent);

After showing the confirmation animation, ConfirmationActivity finishes and your activity resumes.

当显示确认的界面以后,   ConfirmationActivity  完成了,并且你的acitivyt 会resume。
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

1: 推出全屏的activity

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Exiting Full-Screen Activities


Previous Next

This lesson teaches you to

  1. Disable the Swipe-To-Dismiss Gesture
  2. Implement the Long Press to Dismiss Pattern

You should also read

  • Android Wear Design Principles

By default, users exit Android Wear activities by swiping from left to right. If the app contains horizontally scrollable content, users first have to navigate to the edge of the content and then swipe again from left to right to exit the app.

For more immersive experiences, like an app that can scroll a map in any direction, you can disable the swipe to exit gesture in your app. However, if you disable it, you must implement the long-press-to-dismiss UI pattern to let users exit your app using the DismissOverlayView class from the Wearable UI Library. You must also inform your users the first time they run your app that they can exit using a long press.

For design guidelines about exiting Android Wear activities, see Breaking out of the card.

<翻译> 默认的情况下,用户推出了android 的手机activity通过从左向右的滑动(swip)。如果应用包含了水平的可滑动的内容,用户首先要滑动到内容的边缘,然后在从左向右滑动。

为了真实的体验,例如一个应用可以在地图上面随便的滑动方向,你要在你的应用中禁用滑动退出的手势。然而,如果你禁用了这个,你必须要实现长按取消的UI 模式,这个模式让用户可以通过手表UI库中的 DismissOverlayView 类来退出你的应用。

关于推出android 手表actiivty的设计的向导,请查看Breaking out of the card.

Disable the Swipe-To-Dismiss Gesture禁用互动取消的手势



If the user interaction model of your app interferes with the swipe-to-dismiss gesture, you can disable it for your app. To disable the swipe-to-dismiss gesture in your app, extend the default theme and set theandroid:windowSwipeToDismiss attribute to false:

<翻译>如果你应用的用户的交互模式和滑动取消的手势有冲去,你可以在你的app中禁用这个手势。为了在你的应用中禁用滑动取消的手势,集成默认的主题并且设置属性android:windowSwipeToDismiss为false

 name="AppTheme" parent="Theme.DeviceDefault">    <item name="android:windowSwipeToDismiss">falseitem>

If you disable this gesture, you must implement the long-press-to-dismiss UI pattern to let users exit your app, as described in the next section.

<翻译>如果你禁用了这个手势,你必须实现长按取消的UI模式来用用户推出你的应用。

Implement the Long Press to Dismiss Pattern 实现长按取消的模式



To use the DismissOverlayView class in your activity, add this element to your layout definition such that it covers the whole screen and is placed above all other views.

The following example shows how to add the  element:

<翻译> 为了在你的activity 中使用 DismissOverlayView 类,添加这个类型到你的布局定义中。并且这个是覆盖整个界面同时被放在所有的view 的最上面。

下面的例子展示了怎么去添加 项目:

    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_height="match_parent"    android:layout_width="match_parent">        DismissOverlayView        android:id="@+id/dismiss_overlay"        android:layout_height="match_parent"        android:layout_width="match_parent"/>

In your activity, obtain the  element and set some introductory text. This text is shown to users the first time they run your app to inform them that they can exit the app using a long press gesture. Then use a GestureDetector to detect a long press:

<翻译>在你的activity 中,获取  项目然后设置一些介绍的文字。这个文字在用户第一次运行你的app的时候展示给用户通知他们他们可以通过长按的手势来推出。然后使用来检测手势。

public class WearActivity extends Activity {    private DismissOverlayView mDismissOverlay;    private GestureDetector mDetector;    public void onCreate(Bundle savedState) {        super.onCreate(savedState);        setContentView(R.layout.wear_activity);        // Obtain the DismissOverlayView element        mDismissOverlay = (DismissOverlayView) findViewById(R.id.dismiss_overlay);        mDismissOverlay.setIntroText(R.string.long_press_intro);        mDismissOverlay.showIntroIfNecessary();        // Configure a gesture detector        mDetector = new GestureDetector(this, new SimpleOnGestureListener() {            public void onLongPress(MotionEvent ev) {                mDismissOverlay.show();            }        });    }    // Capture long presses    @Override    public boolean onTouchEvent(MotionEvent ev) {        return mDetector.onTouchEvent(ev) || super.onTouchEvent(ev);    }}

When the system detects a long press gesture, the  element shows an Exit button, which terminates your activity if the user presses it.

<翻译>当系统检测到了一个长按的手势的时候,  会显示一个推出的按钮,如果用户按了这个按钮会将你的actiivty 结束



更多相关文章

  1. 修改Android中Layout布局文件字体的大小
  2. 【Android】常用控件及布局
  3. Android 布局讲解
  4. Android 仿抖音上下滑动布局
  5. Android UI布局经验总结
  6. Android网格布局实现--GridView
  7. Android的xml布局文件代码讲解(TextView控件)
  8. 可动态布局的Android抽屉之完整篇

随机推荐

  1. MySQL into_Mysql中replace与replace int
  2. MYSQL 的10大经典优化案例场景实战
  3. MySQL 数据库定时备份的几种方式(全面)
  4. Mysql 字符集不一致导致连表异常的解决
  5. 五分钟带你搞懂MySQL索引下推
  6. 一篇文章读懂什么是MySQL索引下推(ICP)
  7. MySQL索引下推(ICP)的简单理解与示例
  8. 五分钟让你快速弄懂MySQL索引下推
  9. MySQL的索引系统采用B+树的原因解析
  10. Mysql prepare预处理的具体使用