與ListView對比優勢:
1.運行效率更高。
2.能實現橫向滾動與瀑布流佈局。
官方更加推薦Recycler控件,但因爲後期加入又要使所有版本的Android都能使用,所以把它放入了support庫當中,所以使用的第一步,是在項目的build.gradle中添加相應的依賴庫。
打開app/build.gradle文件,在dependencies中添加
implementation 'com.android.support:recyclerview-v7:28.0.0'
不同項目不同版本的依賴庫版本號不同,截圖給大家參考下我現在的,不必模仿:
點擊Sync Now同步。
那麼如何使用這個控件呢?點擊activity_main.xml,修改代碼:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
中間的這段代碼,就是調用RecyclerView控件。因爲它並不是內置在SDK中的控件,所以使用時要寫出完整的路徑名。
接下來我們以水果列表顯示爲例分別實現四個功能,每個功能講解結束都會附上Demo,請自行下載:
1:實現縱向滾動
2:實現橫向滾動
3:實現瀑布流佈局
4:實現recyclerView點擊事件
功能一:實現縱向滾動
先創建一個Fruit類Fruit.java,代碼如下:
package com.example.recyclerviewtest;
public class Fruit {
private String name;
private int imageId;
public Fruit(String name, int imageId) {
this.name = name;
this.imageId = imageId;
}
public String getName() {
return name;
}
public int getImageId() {
return imageId;
}
}
再創建對於一個水果,它的單個佈局文件fruit_item.xml。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/fruit_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/fruit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"/>
</LinearLayout>
接下來爲RecyclerView準備一個適配器,新建FruitAdapter類文件FruitAdapter.java,讓這個個適配器繼承自RecyclerView.Adapter,並將泛型指定爲FruitAdapter.ViewHolder。其中ViewHolder是我們在FruitAdapter中定義的一個內部類,代碼如下:
package com.example.recyclerviewtest;
import android.media.Image;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.w3c.dom.Text;
import java.util.List;
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
private List<Fruit> mFruitList;
//傳入view參數,這個參數就是RecyclerView的子項佈局,這樣就能找到裏面各個控件的id
static class ViewHolder extends RecyclerView.ViewHolder {
ImageView fruitImage;
TextView fruitName;
public ViewHolder(@NonNull View itemView) {
super(itemView);
fruitImage = (ImageView)itemView.findViewById(R.id.fruit_image);
fruitName = (TextView)itemView.findViewById(R.id.fruit_name);
}
}
//將要展示的數據源傳入
public FruitAdapter(List<Fruit> fruitList) {
mFruitList = fruitList;
}
//下面三個函數必須要重寫
//載入fruit_item佈局,創建ViewHolder實例
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
//爲每個RecylerView對象賦值
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Fruit fruit = mFruitList.get(position);
holder.fruitName.setText(fruit.getName());
holder.fruitImage.setImageResource(fruit.getImageId());
}
//計算一共多少個子項
@Override
public int getItemCount() {
return mFruitList.size();
}
}
適配器已經準備好了,我們現在可以使用RecyclerView了,修改MainActivity.java:
package com.example.recyclerviewtest;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.widget.LinearLayout;
import java.util.ArrayList;
import java.util.List;
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 = (RecyclerView)findViewById(R.id.recycler_view);
//創建LinerLayoutManager對象,其中LayoutManager用於指定RecyclerView的佈局方式
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
//設置佈局
recyclerView.setLayoutManager(layoutManager);
FruitAdapter adapter = new FruitAdapter(fruitList);
//關聯RecyclerView與數據
recyclerView.setAdapter(adapter);
}
private void initFruits() {
for(int i = 0; i < 2; i++) {
Fruit apple = new Fruit("Apple", R.drawable.apple_pic);
fruitList.add(apple);
Fruit banana = new Fruit("Banana", R.drawable.banana_pic);
fruitList.add(banana);
Fruit orange = new Fruit("Orange", R.drawable.orange_pic);
fruitList.add(orange);
Fruit watermelon = new Fruit("Watermelon", R.drawable.watermelon_pic);
fruitList.add(watermelon);
Fruit pear = new Fruit("Pear", R.drawable.pear_pic);
fruitList.add(pear);
Fruit grape = new Fruit("Grape", R.drawable.grape_pic);
fruitList.add(grape);
Fruit pineapple = new Fruit("Pineapple", R.drawable.pineapple_pic);
fruitList.add(pineapple);
Fruit strawberry = new Fruit("Strawberry", R.drawable.strawberry_pic);
fruitList.add(strawberry);
Fruit cherry = new Fruit("Cherry", R.drawable.cherry_pic);
fruitList.add(cherry);
Fruit mango = new Fruit("Mango", R.drawable.mango_pic);
fruitList.add(mango);
}
}
}
接下來就可以運行了,以後如果需要不同的內容,結構,更改部分代碼即可,代碼結構不會改變。下面是運行效果:
功能一Demo文件下載:https://download.csdn.net/download/qq_38367681/12167275
功能二:實現橫向滾動
要實現橫向拉動其實很簡單,因爲ListView的佈局是由自身去管理的,而RecyclerView把這個工作交給了LayoutManager,LayoutManager中制定了一套可擴展的佈局排列接口,子類只要按照接口的規範來實現,就能定製出各種不同排列的佈局了。
第一步,肯定要先改寫子項的佈局,使它橫向排列看起來更舒服,所以修改fruit_item.xml.
<?xml version="1.0" encoding="utf-8"?>
<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>
第二部,只需要調整layoutManager的排列方向。默認是垂直方向,所以縱向排列的代碼並沒有加入方向調整,實現功能二,我們只需要加入一行代碼,設置排列方向爲水平:
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
所以MainActivity.java代碼變成如下:
package com.example.recyclerviewtest;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.widget.LinearLayout;
import java.util.ArrayList;
import java.util.List;
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 = (RecyclerView)findViewById(R.id.recycler_view);
//創建LinerLayoutManager對象,其中LayoutManager用於指定RecyclerView的佈局方式
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
//設置線性佈局爲水平線性佈局,默認爲垂直,所以不設置效果會跟listview一樣
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
//設置佈局
recyclerView.setLayoutManager(layoutManager);
FruitAdapter adapter = new FruitAdapter(fruitList);
//關聯RecyclerView與數據
recyclerView.setAdapter(adapter);
}
private void initFruits() {
for(int i = 0; i < 2; i++) {
Fruit apple = new Fruit("Apple", R.drawable.apple_pic);
fruitList.add(apple);
Fruit banana = new Fruit("Banana", R.drawable.banana_pic);
fruitList.add(banana);
Fruit orange = new Fruit("Orange", R.drawable.orange_pic);
fruitList.add(orange);
Fruit watermelon = new Fruit("Watermelon", R.drawable.watermelon_pic);
fruitList.add(watermelon);
Fruit pear = new Fruit("Pear", R.drawable.pear_pic);
fruitList.add(pear);
Fruit grape = new Fruit("Grape", R.drawable.grape_pic);
fruitList.add(grape);
Fruit pineapple = new Fruit("Pineapple", R.drawable.pineapple_pic);
fruitList.add(pineapple);
Fruit strawberry = new Fruit("Strawberry", R.drawable.strawberry_pic);
fruitList.add(strawberry);
Fruit cherry = new Fruit("Cherry", R.drawable.cherry_pic);
fruitList.add(cherry);
Fruit mango = new Fruit("Mango", R.drawable.mango_pic);
fruitList.add(mango);
}
}
}
運行結果如下:
功能二Demo文件下載:https://download.csdn.net/download/qq_38367681/12168921
功能三:實現瀑布流佈局
同功能二,爲了瀑布流佈局更美觀,肯定是先修改fruit_item.xml文件,然後再修改MainActivity.java中的LayoutManager,使其變成瀑布流佈局。當然也只是一行代碼:
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
共接收兩個參數,第一個參數是列數,第二個參數是佈局的排列方向。
fruit_item.xml代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<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>
MainActivity.java代碼如下:
package com.example.recyclerviewtest;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import android.os.Bundle;
import android.widget.LinearLayout;
import java.util.ArrayList;
import java.util.List;
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 = (RecyclerView)findViewById(R.id.recycler_view);
//創建一個StaggeredGridLayoutManager實例,共接收兩個參數,第一個參數是列數,第二個參數是佈局的排列方向
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
//設置佈局
recyclerView.setLayoutManager(layoutManager);
FruitAdapter adapter = new FruitAdapter(fruitList);
//關聯RecyclerView與數據
recyclerView.setAdapter(adapter);
}
private void initFruits() {
for(int i = 0; i < 2; i++) {
Fruit apple = new Fruit("Apple", R.drawable.apple_pic);
fruitList.add(apple);
Fruit banana = new Fruit("BananaBananaBananaBananaBananaBananaBananaBananaBananaBananaBananaBananaBananaBananaBananaBananaBananaBananaBanana", R.drawable.banana_pic);
fruitList.add(banana);
Fruit orange = new Fruit("Orange", R.drawable.orange_pic);
fruitList.add(orange);
Fruit watermelon = new Fruit("Watermelon", R.drawable.watermelon_pic);
fruitList.add(watermelon);
Fruit pear = new Fruit("Pear", R.drawable.pear_pic);
fruitList.add(pear);
Fruit grape = new Fruit("GrapeGrapeGrapeGrapeGrapeGrapeGrapeGrapeGrapeGrapeGrapeGrapeGrapeGrapeGrapeGrapeGrapeGrapeGrape", R.drawable.grape_pic);
fruitList.add(grape);
Fruit pineapple = new Fruit("Pineapple", R.drawable.pineapple_pic);
fruitList.add(pineapple);
Fruit strawberry = new Fruit("Strawberry", R.drawable.strawberry_pic);
fruitList.add(strawberry);
Fruit cherry = new Fruit("Cherry", R.drawable.cherry_pic);
fruitList.add(cherry);
Fruit mango = new Fruit("Mango", R.drawable.mango_pic);
fruitList.add(mango);
}
}
}
運行結果如下:
功能三Demo文件下載:https://download.csdn.net/download/qq_38367681/12169036
功能四:RecyclerView的點擊事件。
RecyclerView所有的點擊事件都需要具體的View控件去註冊,其實這樣反而會更舒服,我們可以爲任何我們想要觸發點擊事件的控件,佈局,甚至是RecyclerView列表子項添加點擊事件。爲RecyclerView子項添加點擊監聽時,我們在ViewHolder中添加fruitView變量用來保存子項最外層的佈局實例,然後在onCreateViewHolder()方法中註冊點擊事件即可。爲子項的控件添加點擊監聽時,直接用viewholder裏的佈局控件註冊點擊即可。代碼如下:
FruitAdapter.java
package com.example.recyclerviewtest;
import android.media.Image;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.w3c.dom.Text;
import java.util.List;
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
private List<Fruit> mFruitList;
//傳入view參數,這個參數就是RecyclerView的子項佈局,這樣就能找到裏面各個控件的id
static class ViewHolder extends RecyclerView.ViewHolder {
//整個子項佈局
View fruitView;
ImageView fruitImage;
TextView fruitName;
public ViewHolder(@NonNull View itemView) {
super(itemView);
fruitView = itemView;
fruitImage = (ImageView)itemView.findViewById(R.id.fruit_image);
fruitName = (TextView)itemView.findViewById(R.id.fruit_name);
}
}
//將要展示的數據源傳入
public FruitAdapter(List<Fruit> fruitList) {
mFruitList = fruitList;
}
//下面三個函數必須要重寫
//載入fruit_item佈局,創建ViewHolder實例
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item, parent, false);
final ViewHolder holder = new ViewHolder(view);
//爲子項的實例佈局添加點擊監聽
holder.fruitView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = holder.getAdapterPosition();
Fruit fruit = mFruitList.get(position);
Toast.makeText(v.getContext(), "you clicked view" + fruit.getName(), Toast.LENGTH_SHORT).show();
}
});
//爲每個子項的圖片添加點擊監聽
holder.fruitImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = holder.getAdapterPosition();
Fruit fruit = mFruitList.get(position);
Toast.makeText(v.getContext(), "you clicked image" + fruit.getName(), Toast.LENGTH_SHORT).show();
}
});
return holder;
}
//爲每個RecylerView對象賦值
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Fruit fruit = mFruitList.get(position);
holder.fruitName.setText(fruit.getName());
holder.fruitImage.setImageResource(fruit.getImageId());
}
//計算一共多少個子項
@Override
public int getItemCount() {
return mFruitList.size();
}
}
運行結果如下:
點擊圖片時
當點擊文字(其實代表的是圖片文字整個子項被點擊,因爲給圖片註冊了點擊監聽,所以只能點文字表明點擊了整個子項)
功能四Demo文件下載:https://download.csdn.net/download/qq_38367681/12169120
直接複製使用吧,祝愉快