Anroid Wear OS 手表應(yīng)用開發(fā) - UI

Wear UI

智能手表相對手機(jī)來說,由于使用場景不同,且屏幕較小,所以應(yīng)用的設(shè)計、交互和手機(jī)是有些區(qū)別的。相對來說,布局會更簡潔,更多地使用滑動手勢進(jìn)行操作。

為此,在 Wear OS 上,官方提供了一系列新的控件和交互,通過它們,我們可以很方便地打造出一個適合手表交互的應(yīng)用。

添加依賴

下面用到的控件都來自 Wear 控件庫,需要在 build.gradle 文件中添加以下依賴:

implementation 'com.android.support:wear:28.0.0'

布局

常見的表盤有方形和圓形兩種,使用普通布局的情況下,可能會出現(xiàn)這種情況:

image

為了使圓形表盤上的內(nèi)容不超出邊界,同時兼容方形表盤,我們可以使用 BoxInsetLayout 這個布局:

<android.support.wear.widget.BoxInsetLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_height="match_parent"
    android:layout_width="match_parent">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:boxedEdges="all">
        
        <...>
        
    </FrameLayout>
    
</android.support.wear.widget.BoxInsetLayout>

這樣可以在保證方形表盤不受影響的情況下,圓形布局的內(nèi)容,不會超過顯示邊界:

image

導(dǎo)航抽屜欄

為了節(jié)省寶貴的顯示空間,通常手表應(yīng)用是沒有標(biāo)題欄的,在使用 ViewPager 的時候,也沒有 TabLayout 的顯示,但因此我們無法很好的確認(rèn)當(dāng)前頁面。

導(dǎo)航欄 WearableNavigationDrawerView 就是用來解決這個問題的,我們先看看它的效果:

image

從手表頂部向下滑,會出現(xiàn)一個導(dǎo)航欄,顯示當(dāng)前頁面的圖標(biāo)和標(biāo)題。當(dāng)存在多個頁面時,通過左右滑動它來切換頁面。

下面來看看它的用法,我們修改布局文件,使用 WearableDrawerLayout 作為根布局,添加導(dǎo)航欄控件:

<android.support.wear.widget.drawer.WearableNavigationDrawerView
        android:id="@+id/navigation_drawer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:navigationStyle="multiPage"/>

當(dāng)存在多個頁面時,需要添加 app:navigationStyle="multiPage" 這個屬性。

和 ViewPager 類似,我們需要給它設(shè)置一個適配器,設(shè)置每個頁面的圖標(biāo)和標(biāo)題,像這樣:

class MainDrawerAdapter(context: Context) :
    WearableNavigationDrawerView.WearableNavigationDrawerAdapter() {

    private val mContext = context

    override fun getItemText(pos: Int): CharSequence {
        return when (pos) {
            0 -> "第一頁"
            else -> "第二頁"
        }
    }

    override fun getItemDrawable(pos: Int): Drawable {
        return when (pos) {
            0 -> ContextCompat.getDrawable(mContext, R.drawable.icon_one)!!
            else -> ContextCompat.getDrawable(mContext, R.drawable.icon_two)!!
        }
    }

    override fun getCount(): Int {
        return 2
    }

}

然后在 Activity 中設(shè)置:

navigation_drawer.setAdapter(MainDrawerAdapter(this))
navigation_drawer.controller.peekDrawer()
navigation_drawer.addOnItemSelectedListener { pos ->
    // TODO 切換頁面
}

這里面的 controller.peekDrawer() 是讓導(dǎo)航欄在頂部露出一小部分,提示用戶這里是有東西可以下滑的,也可以調(diào)用 controller.closeDrawer() 完全隱藏導(dǎo)航欄。

操作抽屜欄

當(dāng)需要對當(dāng)前頁面進(jìn)行一些操作的時候,但頁面里又沒有空間再放按鈕了怎么辦?既然可以從頂部下拉出導(dǎo)航欄,要不在底部上拉出一個操作欄?操作欄 WearableActionDrawerView 就是用來做這個的。

通過給操作欄設(shè)置 menu 文件,它會以列表的形式展示可操作項,布局中這么寫:

<android.support.wear.widget.drawer.WearableActionDrawerView
    android:id="@+id/action_drawer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:actionMenu="@menu/action_drawer_menu"/>

代碼中使用:

action_drawer.controller.peekDrawer()
action_drawer.setOnMenuItemClickListener { item -> 
    // TODO 點擊菜單
    true
}

和頂部導(dǎo)航欄類似,controller.peekDrawer() 會在底部露出一小部分操作欄,如果當(dāng)前頁面是一個列表,這一部分會在列表滑動時隱藏,在列表到頂部和底部時顯示:

image

露出部分默認(rèn)會顯示操作欄第一項的圖標(biāo),可以在布局中添加 app:showOverflowInPeek="true",讓它顯示豎直三個點的省略圖標(biāo)。

自定義抽屜欄

導(dǎo)航欄 WearableNavigationDrawerView 和 操作欄 WearableActionDrawerView
用起來很簡單,但是它們的樣式是固定的,一個只能顯示圖標(biāo)加標(biāo)題,一個只能顯示 menu 格式的列表。

這兩個控件都繼承自 WearableDrawerView,所以兩者都可以通過 WearableDrawerView 來實現(xiàn)自定義樣式。下面是一個簡單的自定義底部抽屜欄布局:

<android.support.wear.widget.drawer.WearableDrawerView
        android:id="@+id/action_drawer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="bottom"
        app:drawerContent="@+id/drawer_content"
        app:peekView="@+id/peek_view">

    <FrameLayout
            android:id="@+id/drawer_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

        <include layout="@layout/layout_bottom_drawer"/>

    </FrameLayout>

    <FrameLayout
            android:id="@+id/peek_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:paddingTop="8dp"
            android:paddingBottom="8dp"
            android:orientation="horizontal">

        <ImageView
                android:layout_width="16dp"
                android:layout_height="16dp"
                android:src="@drawable/icon_omit"
                tools:ignore="ContentDescription"/>

    </FrameLayout>

</android.support.wear.widget.drawer.WearableDrawerView>

通過 layout_gravity 來設(shè)置抽屜欄是在頂部還是底部。它包裹了抽屜欄的主視圖 drawer_content 和關(guān)閉時露出部分的視圖 peek_view。這樣我們就可以在 layout_bottom_drawer 中設(shè)置自己想要的布局了,其他用法都和上面是一樣的。

確認(rèn)動畫

當(dāng)處理完某個業(yè)務(wù)之后,我們通常需要給用戶一個處理成功或失敗的提示,在 Wear OS 上,我們可以用一個 Activity 來展示確認(rèn)動畫。

ConfirmationActivity 是官方提供的用來展示確認(rèn)動畫的 Activity。

image

用起來也很簡單,先在 manifest 文件中注冊:

<manifest>
  <application>
    ...
    <activity
        android:name="android.support.wearable.activity.ConfirmationActivity">
    </activity>
  </application>
</manifest>

需要顯示確認(rèn)的時候,通過傳參跳轉(zhuǎn)就好了:

val intent = Intent(this, ConfirmationActivity::class.java)
intent.putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE, ConfirmationActivity.SUCCESS_ANIMATION)
intent.putExtra(ConfirmationActivity.EXTRA_MESSAGE, message)
startActivity(intent)

這里面,EXTRA_ANIMATION_TYPE 是動畫類型,它有以下三個可選項:

  • SUCCESS_ANIMATION
  • FAILURE_ANIMATION
  • OPEN_ON_PHONE_ANIMATION

EXTRA_MESSAGE 則是要顯示的文字內(nèi)容。

環(huán)形進(jìn)度條

CircularProgressLayout 是一個環(huán)形的進(jìn)度條,通常用它包裹一個圓形按鈕:

image

可以用它來做防誤觸,用戶點擊按鈕后,允許在進(jìn)度條走完之前,點擊取消操作。

我們把它添加到布局中:

<android.support.wear.widget.CircularProgressLayout
    android:id="@+id/circular_progress"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="4dp"
    app:backgroundColor="@color/darkblue"
    app:colorSchemeColors="@color/lightblue"
    app:strokeWidth="4dp">
    
    <ImageView
      android:id="@+id/image_view"
      android:src="@drawable/cancel"
      android:layout_width="40dp"
      android:layout_height="40dp" />
      
</android.support.wear.widget.CircularProgressLayout>

對 CircularProgressLayout 的監(jiān)聽和操作如下:

// 監(jiān)聽進(jìn)度
circular_progress.setOnTimerFinishedListener {
    // TODO 進(jìn)度完成
}
// 設(shè)置進(jìn)度總時間
circular_progress.totalTime = 1000
// 開始計時
circular_progress.startTimer()
// 結(jié)束計時
circular_progress.stopTimer()

列表

如果對比方形表盤和圓形表盤的手表,他們的應(yīng)用列表界面是這樣的:

image
image

在圓形表盤上,列表是沿著表盤左邊,曲線排列滾動的。這就是列表控件 WearableRecyclerView 實現(xiàn)的效果。

WearableRecyclerView 繼承自 RecyclerView,所以基本用法都是一樣的。

在布局中加入:

<android.support.wear.widget.WearableRecyclerView
    android:id="@+id/wearable_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="vertical" />

代碼中設(shè)置:

// 使列表上的第一項和最后一個項在屏幕上垂直居中對齊
wearable_recycler_view.isEdgeItemsCenteringEnabled = true
// 使用 WearableLinearLayoutManager 管理布局
wearable_recycler_view.layoutManager = WearableLinearLayoutManager(this)

如果想自定義別的滾動效果,我們可以通過拓展 WearableLinearLayoutManager.LayoutCallback 來實現(xiàn),這里就不展開說了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,287評論 4 61
  • Android UI相關(guān)開源項目庫匯總OpenDigg 抽屜菜單MaterialDrawer ★7337 - 安卓...
    黃海佳閱讀 8,825評論 3 77
  • 生命的一切都來的輕松愉快并充滿榮耀~感恩今天的開啟~ 超頻的藍(lán)鷹,太陽的白橋~ 今日覺察: 1.今天一切都非常順利...
    Demi瑤瑤閱讀 326評論 0 0
  • 【今日拍攝】 渾河中的水已經(jīng)結(jié)成了冰,晶瑩剔透。 冬天來了,春天還會遠(yuǎn)嗎? 【今日好句】 大道理人人都懂,小情緒卻...
    簡單alan閱讀 218評論 0 1
  • 又看到了二十年前的經(jīng)典了,三人再一次的同臺,依舊和當(dāng)初演得時候一樣,劇中都是各種的調(diào)侃,各種的擠兌,但是里面又多了...
    鎖顏閱讀 286評論 0 0

友情鏈接更多精彩內(nèi)容