RecyclerView是ViewGroup的子类,每一个列表项都是作为一个View子对象展示的,而View子对象是可以自定义的。
先来个简易版的列表项显示,每个列表项只显示一个标题,并且View对象是一个简单的TextView,我们通过一个例子来理解和知道如何使用RecyclerView类。
- RecyclerView意思为可回收视图,所做的就是回收再利用,反复循环。
贴图参考自:《Android编程权威指南第二版第九章》。
数据层Crime类:
package com.example.lu.criminalintent.Model;
import java.util.Date;
import java.util.UUID;
public class Crime {
private UUID mId;
private String mTitle;
private Date mDate;
private Boolean mSolved;
public Date getmDate() {
return mDate;
}
public void setmDate(Date mDate) {
this.mDate = mDate;
}
public Boolean getmSolved() {
return mSolved;
}
public void setmSolved(Boolean mSolved) {
this.mSolved = mSolved;
}
public Crime() {
mId = UUID.randomUUID();
mDate = new Date();
}
public UUID getmId() {
return mId;
}
public String getmTitle() {
return mTitle;
}
public void setmTitle(String mTitle) {
this.mTitle = mTitle;
}
}
数据层CrimeLab类:
package com.example.lu.criminalintent.Model;
import android.content.Context;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class CrimeLab {
private static CrimeLab sCrimeLab;
private List<Crime> mCrimes;//存储crime对象
private CrimeLab(Context context) {
mCrimes = new ArrayList<>();
for (int i = 0;i < 100; i++) {
Crime crime = new Crime();
crime.setmTitle("Crime #" + i);
crime.setmSolved(i % 2 == 0);
mCrimes.add(crime);
}
}
public static CrimeLab get(Context context) {
if (sCrimeLab == null) {
sCrimeLab = new CrimeLab(context);
}
return sCrimeLab;
}
//返回整个所有crime对象
public List<Crime> getmCrimes() {
return mCrimes;
}
//返回相对应位置id的crime对象
public Crime getCrime(UUID id) {
for (Crime crime : mCrimes) {
if (crime.getmId().equals(id)) {
return crime;
}
}
return null;
}
}
Activity类:
package com.example.lu.criminalintent.Controller;
import android.support.v4.app.Fragment;
import com.example.lu.criminalintent.Father.SingleFragmentActivity;
import com.example.lu.criminalintent.UI.CrimeListFragment;
public class CrimeListActivity extends SingleFragmentActivity {
@Override
protected Fragment createFragment() {
return new CrimeListFragment();
}
}
这里为了代码复用,把复用的代码做成了一个抽象类。
SingleFragmentActivity类:
package com.example.lu.criminalintent.Father;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import com.example.lu.criminalintent.R;
public abstract class SingleFragmentActivity extends FragmentActivity {
protected abstract Fragment createFragment();
/*
*以下代码复用。
*/
private Fragment fragment;
private FragmentManager fm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initLayout();
if (fragment == null) {
fragment = createFragment();
fm.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit();
}
}
private void initLayout() {
fm = getSupportFragmentManager();
fragment = fm.findFragmentById(R.id.fragment_container);
}
}
绿色代码可以解读为:
创建一个新的fragment事务,加入一个添加操作,然后提交该事务。
add()方法是整个事务的核心,包含两个参数,分别为:容器视图资源id和新创建的fragment。
容器视图资源id的作用是
1.告诉FragmentManager,fragment视图应该出现在activity视图的什么位置
2.用作FragmentManager队列中fragment唯一的标识符
我们来看下标红的代码的方法,FragmentManager是如何实现的,
红色的代码:先获取到一个FragmentManager管理器,然后再找到一个Fragment,存进fragment队列中。
布局CrimeListFragment类:
package com.example.lu.criminalintent.UI;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.example.lu.criminalintent.Model.Crime;
import com.example.lu.criminalintent.Model.CrimeLab;
import com.example.lu.criminalintent.R;
import java.util.List;
public class CrimeListFragment extends Fragment{
private RecyclerView mCrimeRecyclerView;
private CrimeAdapter mAdapter;//适配器,这里用内部类的形式实现适配器
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_crime_list, container, false);
initLayout(view);
initController();
updateUI();
return view;
}
private void initLayout(View view) {
mCrimeRecyclerView = view.findViewById(R.id.crime_recycler_view);
}
private void initController() {
//LinearLayoutManager负责定位屏幕上的列表项和屏幕滚动行为
mCrimeRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
}
//实现ViewHolder
private class CrimeHolder extends RecyclerView.ViewHolder{
public TextView mTitleTextView;
public CrimeHolder(View itemView) {
super(itemView);
mTitleTextView = (TextView) itemView;
}
}
//实现Adapter
private class CrimeAdapter extends RecyclerView.Adapter<CrimeHolder> {
private List<Crime> mCrimes;
public CrimeAdapter(List<Crime> crimes) {
mCrimes = crimes;
}
@NonNull
@Override
public CrimeHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
View view = layoutInflater.inflate(android.R.layout.simple_list_item_1, parent, false);
return new CrimeHolder(view);
}
@Override
public void onBindViewHolder(@NonNull CrimeHolder holder, int position) {
Crime crime = mCrimes.get(position);
holder.mTitleTextView.setText(crime.getmTitle());
}
@Override
public int getItemCount() {
return mCrimes.size();
}
}
private void updateUI() {
CrimeLab crimeLab = CrimeLab.get(getActivity());
List<Crime> crimes = crimeLab.getmCrimes();
mAdapter = new CrimeAdapter(crimes);
mCrimeRecyclerView.setAdapter(mAdapter);
}
}
接下来解读下标红代码:
布局文件:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
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:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
<!--
通用布局文件
-->
fragment_crime_list.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/crime_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
效果图:
如果你能理解上述代码是如何实现的,那么相信你已经基本掌握了如何使用RecyclerView类了。