學會使用 RecyclerView 後大致上可以不使用 ListView 了。
畢竟 RecyclerView 的功能比 ListView 強大許多。
效果圖如下。
Android 版本的演變與更版本更新的資料。
有興趣可以到 Wiki:Android 歷史版本 查看相關資訊。
使用 RecyclerView 必須 import v7 support library。
Android Studio 現在也很貼心,可以在 layout Design 直接幫你 import 。
import library後在 layout.xml 中放入 RecyclerView 。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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="com.demo.recyclerviewdemo.activity.RecyclerViewDemo">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_RecyclerDemo"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
接下來與使用 BaseAdapter 一樣需要建立 item layout.xml 與自定義 Adapter 。<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="120dp">
<ImageView
android:id="@+id/iv_AndroidLogo"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerVertical="true"
tools:src="@drawable/eclair"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/iv_AndroidLogo">
<TextView
android:id="@+id/tv_AndroidTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="4dp"
android:text="Android Version"
android:textColor="@android:color/black"
android:textSize="20sp"
android:textStyle="bold"/>
<TextView
android:id="@+id/tv_AndroidVersion"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tv_AndroidTitle"
android:layout_centerHorizontal="true"
android:textColor="@android:color/holo_red_dark"
android:textSize="16sp"
tools:text="2.0/2.1 eclair"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/tv_AndroidVersion"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginTop="4dp">
<EditText
android:id="@+id/et_AndroidMemo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@null"
android:enabled="false"
android:focusable="false"
android:textSize="12sp"
tools:text="最佳化硬體速度「Car Home」程式支援更多的螢幕解像度
改良的使用者介面新的瀏覽器的用户介面和支援HTML5新的聯繫人名單更好的白色/黑色背景比率改進Google Maps 3.1.2支援Microsoft Exchange
支援內建相機閃光燈支援數位變焦改進的虛擬鍵盤支援藍牙2.1支援動態桌面的設計"/>
</ScrollView>
</RelativeLayout>
</RelativeLayout>
item 畫面如下。
製作 Adapter 。RecyclerView 所使用的 Adapter 也與 ListView 不一樣。
必須要繼承 RecyclerView.Adapter 來實作。
而且支援使用 ViewHolder 不必像 BaseAdapter 需要自己判斷 ViewHolder 。
繼承 RecyclerView.Adapter 需要 Override 以下三種方法。
- onCreateViewHolder:處理 ViewHolder View。
- onBindViewHolder :處理 ViewHolder 中 UI 與資料綁定。
- getItemCount :決定 RecyclerView 有幾個 Item 項目。
public class RecyclerViewDemoAdapter extends RecyclerView.Adapter<RecyclerViewDemoAdapter.ViewHolder> {
int[] image = new int[]{R.drawable.beta, R.drawable.one, R.drawable.cupcake, R.drawable.donut,
R.drawable.donut, R.drawable.eclair, R.drawable.froyo, R.drawable.gingerbread, R.drawable.honeycomb,
R.drawable.ice_cream_sandwich, R.drawable.jelly_bean, R.drawable.kitkat, R.drawable.lollipop,
R.drawable.marshmallow, R.drawable.nougat, R.drawable.o};
private List<AndroidVO> mAndroidVOList;
public RecyclerViewDemoAdapter(List<AndroidVO> androidVOList) {
mAndroidVOList = androidVOList;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycler_view_demo, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.tvVersion.setText(mAndroidVOList.get(position).getVersion());
holder.ivLogo.setImageResource(image[position]);
holder.etMemo.setText(mAndroidVOList.get(position).getMemo());
}
@Override
public int getItemCount() {
return mAndroidVOList.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
ImageView ivLogo;
TextView tvVersion;
EditText etMemo;
public ViewHolder(View itemView) {
super(itemView);
ivLogo = (ImageView) itemView.findViewById(R.id.iv_AndroidLogo);
tvVersion = (TextView) itemView.findViewById(R.id.tv_AndroidVersion);
etMemo = (EditText) itemView.findViewById(R.id.et_AndroidMemo);
}
}
}
ViewHolder 不像 BaseAdapter 只是一個 inner class 。
而是要繼承 RecyclerView.ViewHolder 。
事先把網路上抓好的圖片位置寫成 int[] 方便之後抓取位置。
可以看到我是傳入一個 List<AndroidVO> 的物件進去。
AndroidVO:幫我把從 Wiki 上抓的資料組成一個物件傳入 Adapter 。
而是要繼承 RecyclerView.ViewHolder 。
事先把網路上抓好的圖片位置寫成 int[] 方便之後抓取位置。
可以看到我是傳入一個 List<AndroidVO> 的物件進去。
AndroidVO:幫我把從 Wiki 上抓的資料組成一個物件傳入 Adapter 。
public class AndroidVO {
private String version;
private String memo;
public AndroidVO(String version, String memo) {
this.version = version;
this.memo = memo;
}
public String getVersion() {
return version;
}
public String getMemo() {
return memo;
}
}
Java Code public class RecyclerViewDemo extends AppCompatActivity {
private List<String> version = new ArrayList<>();
private List<String> memo = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycler_view_demo);
RecyclerViewDemoAdapter adapter = new RecyclerViewDemoAdapter(initData());
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rv_RecyclerDemo);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
}
private List<AndroidVO> initData() {
version = Arrays.asList(getResources().getStringArray(R.array.android_version));
memo = Arrays.asList(getResources().getStringArray(R.array.android_memo));
List<AndroidVO> list = new ArrayList<>();
for (int i = 0; i < version.size(); i++) {
AndroidVO vo = new AndroidVO(version.get(i), memo.get(i));
list.add(vo);
}
return list;
}
}
initData() 只是幫我把資料組成 List 方便我傳入 Adapter 。RecyclerView 使用方法與 ListView 雷同。
差別在於 RecyclerView 需要使用 setLayoutManager() 設定 LayoutManager Type。
這樣系統才知道要讓 RecyclerView 進行怎樣的排列。
這次我們以 LinearLayoutManager 作為示範。
最後在 RecyclerView.setAdapter() 就完成 RecyclerView 初步的使用了。
可以看到跟 ListView 效果差不多,但是效能上比 Listview 好很多。
接下來要寫上 onClick 事件。
與 ListView 不同的是 RecyclerView 沒有 setOnClickListener 接口可以使用。
所以要自己去實現它。
首先我們在 ViewHolder class 中 implement View.OnItemClickListener 。
並且 override onClick()。
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
@Override
public void onClick(View v) {
if (mClick != null)
mClick.onItemClick(v, (int) v.getTag());
}
可以看到 override onClick 中 我判斷了 mClick 並且做了某些事情。mClick 是自己定義的 interface 如下。
private OnRecyclerViewClick mClick;
public interface OnRecyclerViewClick {
void onItemClick(View v, int position);
}
public void setOnClickListener(OnRecyclerViewClick clickListener) {
this.mClick = clickListener;
}
寫了一個 OnRecyclerViewClick interface 。裡面宣告一個 void onItemClick(View v,int position) 。
View 的目的是要把點擊到的 item 傳出去就像 ListView 的 itemClick 事件。
int 不用多解釋就是點擊當前 itemView 的 adapter 位置。
然後再 onBindViewHolder 中把我們需要的 position 數值放進去 itemView中。
holder.itemView.setTag(position);
並且在 adapter 中宣告 setOnClickListener 好讓我們可以在 class 中接收 click 事件。Activity 中只要這樣使用。
adapter.setOnClickListener(new RecyclerViewDemoAdapter.OnRecyclerViewClick() {
@Override
public void onItemClick(View v, int position) {
Toast.makeText(RecyclerViewDemo.this, "version=" + version.get(position) + "\n" + memo.get(position),
Toast
.LENGTH_SHORT)
.show();
}
});
設置完 click 事件後效果如下圖。程式碼下載:GitHub
相關連結
0 意見:
張貼留言