當我們使用RecyclerView和ListView進行布局的時候瞄摊,為了能夠看到布局的實際情況我們需要不停的運行和構建app然后在手機或模擬器上查看布局效果,為了能夠看到實際的布局效果我們還需要自己生成模擬數(shù)據(jù)剩燥,或者從網(wǎng)絡獲取數(shù)據(jù)筋讨,有時候我們只是輕微的修改了一下布局知押,為了看到具體的布局效果,我們也需要重新運行和構建app,這大大降低了我們的開發(fā)效率暂氯。更多的時候我們可能遇到的是UI設計師已經(jīng)給出了UI,但是接口并沒有寫好,這個時候我們就只能在運行時自己用代碼生成一些數(shù)據(jù)亮蛔。那么有沒有什么方式能夠讓我們不依賴接口提供數(shù)據(jù)而快速的搭建和預覽RecyclerView和ListView的布局效果的方法呢痴施。接下來我將分享一些我最近剛學習到的快速開發(fā)和預覽ListView和RecyclerView布局的方法,希望能夠幫助你在實際的開發(fā)中節(jié)省一些時間究流。
當我們使用RecyclerView或ListView進行布局的時候辣吃,讓人心煩的問題是我們不能在Studio的布局預覽中看到他的真實布局樣式。比如說我們現(xiàn)在有一個顯示用戶個人信息的列表芬探,在這個列表的每一個item中包含了該用戶的頭像神得,居住的城市,和加入服務的時間偷仿,以及一些用戶的描述數(shù)據(jù)哩簿。它的布局像下面這樣:
res/layout/item_part1.xml
-------------------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/avatar"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:contentDescription="@null"
app:layout_constraintDimensionRatio="h,1:1"
app:layout_constraintEnd_toStartOf="@id/name"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/name" />
<TextView
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:layout_constraintBottom_toTopOf="@+id/city"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="5"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="@+id/city"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:layout_constraintBottom_toTopOf="@id/description"
app:layout_constraintEnd_toStartOf="@id/date"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintTop_toBottomOf="@+id/name" />
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:gravity="end"
app:layout_constraintBaseline_toBaselineOf="@id/city"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/city" />
<TextView
android:id="@+id/description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:ellipsize="end"
android:maxLines="3"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintTop_toBottomOf="@+id/city" />
</android.support.constraint.ConstraintLayout>
現(xiàn)在我們打開android studio的布局設計器和預覽器將看到如下的效果:
僅管在設計器和預覽器中我們能夠看到item 中的view的大體輪廓,假如我們將布局切換到我們的RecyclerView中我們將看到如下的情行:
我們看到在RecyclerView顯示的地方提供了一列簡單的item進行占位炎疆,RecyclerView和他的Item視圖布局并沒有建立什么聯(lián)系卡骂,所以
我們無法預覽item視圖在RecyclerView中的真實效果,下邊我們使用一個小技巧來實現(xiàn)在設計器和布局器中顯示RecyclerView的真實item布局效果形入。布局文件如下:
res/layout/fragment_part.xml
-------------------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/item_part1" />
tools:listitem="@layout/item_part1"告訴RecyclerView使用布局item_part1作為它自己的item布局全跨。添加這行代碼后我們在android studio的預覽器中看到的效果如下:
現(xiàn)在我們能夠預覽RecyclerView在預覽器中的布局情況。但這依舊沒有達到我們的實際期望亿遂∨ㄈ簦可能很多人都使用過tools:text="..."這個屬性,他主要是協(xié)助我們在布局的時候快速預覽TextView設置text屬性的值的時候的顯示效果蛇数。但是在這兒設置的text屬性的值并不會被打包到真實的apk中挪钓。僅僅用于在android studio的布局預覽器顯示預覽效果。下邊我們給res/layout/item_part1.xml布局中的TextView都加上tools:text="..."屬性代碼如下:
res/layout/item_part1.xml
-----------------------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/avatar"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:contentDescription="@null"
app:layout_constraintDimensionRatio="h,1:1"
app:layout_constraintEnd_toStartOf="@id/name"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/name" />
<TextView
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:layout_constraintBottom_toTopOf="@+id/city"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="5"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="Mark Allison"/>
給RecyclerView的Item布局中的TextView添加tools:text="..."后的布局效果如下:
現(xiàn)在看上去是不是更加好看了一點耳舅,同樣的我們可以使用tools:src給ImageView設置一張預覽圖碌上,但是這樣做會有一個問題倚评,就是我們需要在我們的app中添加一些真實的圖片,而這些圖片我們僅僅是在布局的時候作為預覽用的馏予,apk在運行時并不會使用他們天梧,但是這些圖片會被打包進apk中,這增加了apk的大小霞丧。顯然我們是難以接受的呢岗。那么有沒有解決這個問題的方法呢,答案是有的蛹尝。這就是我今天所要講的主角后豫,在android studio 3.0及之后的版本中新增了一個Sample Data目錄。這個目錄主要用于存放我們在布局階段在android studio中的預覽器中預覽布局效果所用到的資源突那,比如我們可以存放TextView的tools:text="..."用到文本資源挫酿,ImageView的tools:src="..."用到的圖片資源。這些資源并不會被打包打實際的apk中陨收,他們并不會增加apk的大小饭豹。像我們之前在TextView的tools:text="..."設置文本后確實能夠預覽RecyclerView的布局情況,但是你有沒有發(fā)現(xiàn)他所有的item相應位置顯示的文本都是相同的务漩,他并沒有提供差異性拄衰。我們想看到的效果是他最終的一個效果。各個item中對應位置的TextView的值應該是不同的饵骨,對應位置的ImageView顯示的圖片也是不同的翘悉。甚至我想測試TextView中不同長度的文字對于布局的影響,比如文字短的時候是個什么樣子居触,文字特別長的時候布局會不會亂妖混,會不會擠到別的View或者遮蓋別的View。這些需求使用Sample Data都能做到轮洋。
下邊的布局文件使用了sample data目錄中的數(shù)據(jù)制市,你可能會有疑惑的地方不要著急稍候我會作詳細的講解:
res/layout/item_part1.xml
-------------------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/avatar"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:contentDescription="@null"
app:layout_constraintDimensionRatio="h,1:1"
app:layout_constraintEnd_toStartOf="@id/name"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/name"
tools:src="@tools:sample/avatars" />
<TextView
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:layout_constraintBottom_toTopOf="@+id/city"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="5"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="@tools:sample/full_names" />
<TextView
android:id="@+id/city"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:layout_constraintBottom_toTopOf="@id/description"
app:layout_constraintEnd_toStartOf="@id/date"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintTop_toBottomOf="@+id/name"
tools:text="@tools:sample/cities" />
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:gravity="end"
app:layout_constraintBaseline_toBaselineOf="@id/city"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/city"
tools:text="@tools:sample/date/ddmmyy" />
<TextView
android:id="@+id/description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:ellipsize="end"
android:maxLines="3"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintTop_toBottomOf="@+id/city"
tools:text="@tools:sample/lorem/random" />
</android.support.constraint.ConstraintLayout>
下邊我們來看看在android studio的設計預覽器中的最終效果怎么樣是不是很酷,在沒有接口的情況下弊予,我們不需要自己生成模擬數(shù)據(jù)祥楣,編寫adapter就能在不運行app的情況下,實時的在android studio的設計預覽器中對RecyclerView和ListView的實際效果進行預覽汉柒。下邊我將詳細介紹sample data的使用方法误褪。
首先我們需要在項目中創(chuàng)建一個sample data目錄:
我們看到新創(chuàng)建的sampledata 目錄位于app目錄下
然后我們在sampledata目錄下創(chuàng)建一個名稱叫"names"的文件用以存放用戶的名字(這里文件名稱你可以任意取一個,并不一定非得叫"names")然后我們在這個文件里邊輸入一些人的名字碾褂,像下邊這樣:
sampledata/names
-------------------------------------------------------------------------
Mark Allison
Sir Reginald Fortescue Crumplington-Smythe
Pablo Diego José Francisco de Paula Juan Nepomuceno María de los Remedios Cipriano de la Santísima Trinidad Ruiz y Picasso
Millicent Marbles
然后我們將item布局中用于顯示用戶名的TextView的tools:text的值設為tools:text="@tools:sample/names"具體的代碼如下:
<TextView
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:layout_constraintBottom_toTopOf="@+id/city"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="5"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="@sample/names"/>
同理我們在sampledata目錄下在新建一個目錄取名叫"avatars"(這個名字是任意的)然后我們在avatars目錄下存放幾個VectorDrawables資源文件兽间。如下:
然后我們將顯示用戶頭像的ImageView的tools:src設置為tools:src="@sample/avatars"。具體代碼如下:
<ImageView
android:id="@+id/avatar"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:contentDescription="@null"
app:layout_constraintDimensionRatio="h,1:1"
app:layout_constraintEnd_toStartOf="@id/name"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/name"
tools:src="@sample/avatars" />
然后我們此時在android studio 的預覽器中預覽一下RecyclerView的效果如下:
RecyclerView的實際顯示效果就出來了正塌,但是呢大家可能有注意到了嘀略,在上邊我們?yōu)橛脩舻挠脩裘峁┝艘粋€names文件來提供用戶的姓名數(shù)據(jù)恤溶,那我要給用戶的地址提供數(shù)據(jù)不是得在新建一個為提供地址的文件,如果我有很多TextView那我不是要新建很多文件屎鳍,這個一點都不高雅宏娄。別急其實呢sampledata是支持json格式的文件的问裕。我們可以像我們的實際接口數(shù)據(jù)那樣提供一些json格式的數(shù)據(jù)逮壁。
下邊我們在sampledata目錄中新建一個名為users.json文件,就像下邊這樣
然后呢我們在users.json文件中編輯一段json數(shù)據(jù),就像下邊這樣:
{
"data": [
{
"city": "Hemel Hempstead, Hertfordshire, UK",
"avatar": "@sample/avatars"
},
{
"city": "Brokenwind, Aberdeenshire, UK",
"avatar": "@sample/avatars"
},
{
"city": "Málaga, Espa?a",
"avatar": "@sample/avatars"
},
{
"city": "Batchelors Bump, Essex, UK",
"avatar": "@sample/avatars"
}
]
}
然后我們可以在RecyclerView的item布局中引用這個json文件中的數(shù)據(jù)粮宛,像下邊這樣
res/layout/item_part1.xml
-------------------------------------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/avatar"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:contentDescription="@null"
app:layout_constraintDimensionRatio="h,1:1"
app:layout_constraintEnd_toStartOf="@id/name"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/name"
tools:src="@sample/users.json/data/avatar" />
<TextView
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:layout_constraintBottom_toTopOf="@+id/city"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="5"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="@sample/names" />
<TextView
android:id="@+id/city"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:layout_constraintBottom_toTopOf="@id/description"
app:layout_constraintEnd_toStartOf="@id/date"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintTop_toBottomOf="@+id/name"
tools:text="@sample/users.json/data/city" />
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:gravity="end"
app:layout_constraintBaseline_toBaselineOf="@id/city"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/city"
tools:text="@tools:sample/date/ddmmyy" />
<TextView
android:id="@+id/description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:ellipsize="end"
android:maxLines="3"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintTop_toBottomOf="@+id/city"
tools:text="@tools:sample/lorem/random" />
</android.support.constraint.ConstraintLayout>
我們來看看在android studio的設計器中的預覽效果
通過這種方式窥淆,我們可以在程序接口還未提供的時候,就先開始按照UI設計圖進行實際的布局開發(fā)巍杈。我們在也不用每修改一點東西就運行程序查看RecyclerView和ListView的顯示效果了忧饭。并且我們可以在sampledata的文件中按照自己的需要提供各種情況的數(shù)據(jù),用以檢查布局文件中的各個控件在各種取值情況了的顯示情況筷畦,以排查在極端情況下可能出現(xiàn)的布局異常词裤。以上就是我這篇文章所有的內(nèi)容了,希望對您有所幫助鳖宾。
源碼地址:https://github.com/StylingAndroid/ToolTime/tree/Part2
參考文章:
https://blog.stylingandroid.com/tool-time-part-1-2
https://blog.stylingandroid.com/tool-time-part-2