1. 程式人生 > >安卓開發:RecyclerView的使用(二)

安卓開發:RecyclerView的使用(二)

如果你越來越冷漠,你以為你成長了,但其實沒有。長大應該是變得溫柔,對全世界都溫柔。


檢視文章:

  1. 安卓開發:RecyclerView的使用(一)
  2. 安卓開發:RecyclerView的使用(二)
  3. 安卓開發: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()這個方法來生成,這樣就能保證各水果名字的長短差距都比較大,子項的高度也就各不相同了。

轉載宣告:此篇文章轉載自郭霖作者寫的《第一行程式碼》書中的章節,因為此章節對我幫助很大,並且寫的非常詳細,以便之後方便查閱。特在此做轉載宣告。