安卓開發:RecyclerView的使用(二)
如果你越來越冷漠,你以為你成長了,但其實沒有。長大應該是變得溫柔,對全世界都溫柔。
檢視文章:
RecyclerView實現橫向滾動和瀑布流佈局
首先要對 fruit_item 佈局進行修改,因為目前這個佈局裡面的元素是水平排列的,適用於 縱向滾動的場景,而如果我們要實現橫向滾動的話,應該把 fruit_item 裡的元素改成垂直排列 才比較合理。修改 fruit_item.xml 中的程式碼,如下所示:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="100dp" android:layout_height="wrap_content" > <ImageView android:id="@+id/fruit_image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" /> <TextView android:id="@+id/fruit_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="10dp" /> </LinearLayout>
可以看到,我們將 LinearLayout 改成垂直方向排列,並把寬度設為 100dp。這裡將寬度指定 為固定值是因為每種水果的文字長度不一致,如果用 wrap_content 的話,RecyclerView 的子項 就會有長有短,非常不美觀;而如果用 match_parent 的話,就會導致寬度過長,一個子項佔滿 整個螢幕。
然後我們將 ImageView 和 TextView 都設定成了在佈局中水平居中,並且使用 layout_ marginTop 屬性讓文字和圖片之間保持一些距離。
接下來修改 MainActivity 中的程式碼,如下所示:
public class MainActivity extends AppCompatActivity { private List<Fruit> fruitList = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initFruits(); RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view); LinearLayoutManager layoutManager = new LinearLayoutManager(this); layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); recyclerView.setLayoutManager(layoutManager); FruitAdapter adapter = new FruitAdapter(fruitList); recyclerView.setAdapter(adapter); } ... }
MainActivity 中只加入了一行程式碼,呼叫 LinearLayoutManager 的 setOrientation()方法來 設定佈局的排列方向,預設是縱向排列的,我們傳入 LinearLayoutManager.HORIZONTAL 表示 讓佈局橫行排列,這樣 RecyclerView 就可以橫向滾動了。
炫酷的瀑布流佈局
首先還是來修改一下 fruit_item.xml 中的程式碼,如下所示:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height=" wrap_content"
android:layout_margin="5dp" >
<ImageView
android:id="@+id/fruit_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<TextView
android:id="@+id/fruit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_marginTop="10dp" />
</LinearLayout>
這裡做了幾處小的調整,首先將 LinearLayout 的寬度由 100dp 改成了 match_parent,因為 瀑布流佈局的寬度應該是根據佈局的列數來自動適配的,而不是一個固定值。另外我們使用了 layout_margin 屬性來讓子項之間互留一點間距,這樣就不至於所有子項都緊貼在一些。還有 就是將 TextView 的對齊屬性改成了居左對齊,因為待會我們會將文字的長度變長,如果還是居 中顯示就會感覺怪怪的。
接著修改 MainActivity 中的程式碼,如下所示:
public class MainActivity extends AppCompatActivity {
private List<Fruit> fruitList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits();
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
StaggeredGridLayoutManager layoutManager = new
StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
FruitAdapter adapter = new FruitAdapter(fruitList);
recyclerView.setAdapter(adapter);
}
private void initFruits() {
for (int i = 0; i < 2; i++) {
Fruit apple = new Fruit(
getRandomLengthName("Apple"), R.drawable.apple_pic);
fruitList.add(apple);
Fruit banana = new Fruit(
getRandomLengthName("Banana"), R.drawable.banana_pic);
fruitList.add(banana);
Fruit orange = new Fruit(
getRandomLengthName("Orange"), R.drawable.orange_pic);
fruitList.add(orange);
Fruit watermelon = new Fruit(
getRandomLengthName("Watermelon"), R.drawable.watermelon_pic);
fruitList.add(watermelon);
Fruit pear = new Fruit(
getRandomLengthName("Pear"), R.drawable.pear_pic);
fruitList.add(pear);
Fruit grape = new Fruit(
getRandomLengthName("Grape"), R.drawable.grape_pic);
fruitList.add(grape);
Fruit pineapple = new Fruit(
getRandomLengthName("Pineapple"), R.drawable.pineapple_pic);
fruitList.add(pineapple);
Fruit strawberry = new Fruit(
getRandomLengthName("Strawberry"), R.drawable.strawberry_pic);
fruitList.add(strawberry);
Fruit cherry = new Fruit(
getRandomLengthName("Cherry"), R.drawable.cherry_pic);
fruitList.add(cherry);
Fruit mango = new Fruit(
getRandomLengthName("Mango"), R.drawable.mango_pic);
fruitList.add(mango);
}
}
private String getRandomLengthName(String name) {
Random random = new Random();
int length = random.nextInt(20) + 1;
StringBuilder builder = new StringBuilder();
for (int i = 0; i < length; i++) {
builder.append(name);
}
return builder.toString();
}
}
首先,在 onCreate()方法中,我們建立了一個 StaggeredGridLayoutManager 的例項。 StaggeredGridLayoutManager 的建構函式接收兩個引數,第一個引數用於指定佈局的列數, 傳入 3 表示會把佈局分為 3 列;第二個引數用於指定佈局的排列方向,傳入 StaggeredGridLayoutManager.VERTICAL 表示會讓佈局縱向排列,最後再把建立好的例項設定到 RecyclerView 當中就可以了,就是這麼簡單!
沒錯,僅僅修改了一行程式碼,我們就已經成功實現瀑布流佈局的效果了。不過由於瀑布流佈 局需要各個子項的高度不一致才能看出明顯的效果,為此我又使用了一個小技巧。這裡我們把眼 光聚焦在 getRandomLengthName()這個方法上,這個方法使用了 Random 物件來創造一個 1 到 20 之間的隨機數,然後將引數中傳入的字串隨機重複幾遍。在 initFruits()方法中,每個水果 的名字都改成呼叫 getRandomLengthName()這個方法來生成,這樣就能保證各水果名字的長短差距都比較大,子項的高度也就各不相同了。
轉載宣告:此篇文章轉載自郭霖作者寫的《第一行程式碼》書中的章節,因為此章節對我幫助很大,並且寫的非常詳細,以便之後方便查閱。特在此做轉載宣告。