RecyclerView 所做的就是回收再利用,循环往复。
ViewHolder 和 Adapter
RecyclerView 的任务仅限于回收和定位屏幕上的 TextView 。 TextView 能够显示数据还离不
开另外两个类的支持: Adapter 子类和 ViewHolder 子类。 ViewHolder 要做的事很少,我们首先
讨论它。顾名思义, ViewHolder 只做一件事:容纳 View 视图(如图9-5所示)。
adapter
图9-6进行了简化,实际上隐藏了一些信息。 RecyclerView 自己不创建 ViewHolder 。这个
任务实际是由adapter来完成的。adapter是个控制器对象,从模型层获取数据,然后提供给
RecyclerView 显示,起到了沟通的桥梁作用。
adapter负责:
创建必要的 ViewHolder ;
绑定 ViewHolder 至模型层数据。
要创建adapter,首先要定义 RecyclerView.Adapter 子类。然后由它封装从 DataLab 获取的weather。RecyclerView 需要显示视图对象时,就会去找它的adapter。图9-7展示了一个 RecyclerView可能发起的会话。
首先,通过调用adapter的 getItemCount() 方法, RecyclerView 询问数组列表中包含多少个对象。
接 着 , RecyclerView 调 用 adapter 的 createViewHolder(ViewGroup, int) 方 法 创 建ViewHolder 以及 ViewHolder 要显示的视图。
最后, RecyclerView 会传入 ViewHolder 及其位置,调用 onBindViewHolder(ViewHolder,int) 方法。adapter会找到目标位置的数据并绑定到 ViewHolder 的视图上。所谓绑定,就是使用模型数据填充视图。
整个过程执行完毕, RecyclerView 就能在屏幕上显示crime列表项了。需要注意的是,相对于 onBindViewHolder(ViewHolder, int) 方法, createViewHolder(ViewGroup, int) 方法的调用并不频繁。一旦创建了够用的 ViewHolder , RecyclerView 就会停止调用 createViewHolder(...) 方法。然后,通过回收利用旧的 ViewHolder 节约时间和内存。
应用:RecyclerView 类来自于Google支持库。要使用它,首先要添加 RecyclerView 依赖库。单击File → Project Structure....菜单项切换至项目结构窗口,选择左边的app模块,然后单击Dependencies选项页。单击+按钮弹出依赖库添加窗口。找到并选择recyclerview-v7支持库,单击OK按钮完成依赖库添加。
示例代码:
DataListFragment.java:
import android.os.Bundle; 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 java.util.List; /** * Created by Administrator on 2017/4/8. */ public class DataListFragment extends Fragment { private RecyclerView mWeatherRecyclerView; private WeatherAdapter mAdapter; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate( R.layout.fragment_data_list, container, false ); mWeatherRecyclerView = (RecyclerView)view.findViewById(R.id.weather_recycler_view); mWeatherRecyclerView.setLayoutManager( new LinearLayoutManager(getActivity()) ); updateUI(); return view; } private void updateUI( ) { DataLab dataLab = DataLab.get(getActivity()); List<Weather> weathers = dataLab.getWeathers(); mAdapter = new WeatherAdapter(weathers); mWeatherRecyclerView.setAdapter(mAdapter); } private class WeatherHolder extends RecyclerView.ViewHolder { public TextView mTitleTextView; public WeatherHolder(View itemView) { super(itemView); mTitleTextView = (TextView)itemView; } } private class WeatherAdapter extends RecyclerView.Adapter<WeatherHolder> { private List<Weather> mWeathers; public WeatherAdapter( List<Weather> weathers ) { mWeathers = weathers; } @Override public WeatherHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater layoutInflater = LayoutInflater.from(getActivity()); View view = layoutInflater.inflate( android.R.layout.simple_list_item_1, parent, false ); return new WeatherHolder( view ); } @Override public void onBindViewHolder(WeatherHolder holder, int position) { Weather weather = mWeathers.get( position ); holder.mTitleTextView.setText(weather.getTitle()); } @Override public int getItemCount() { return mWeathers.size(); } } }
fragment_data_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/weather_recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" />
Datalab.java:
import android.content.Context; import java.util.ArrayList; import java.util.List; import java.util.UUID; /** * Created by Administrator on 2017/4/8. */ public class DataLab { private static DataLab sDataLab; private List<Weather> mWeathers; public static DataLab get( Context context ) { if ( sDataLab == null ) { sDataLab = new DataLab( context ); } return sDataLab; } private DataLab( Context context ) { mWeathers = new ArrayList<>(); for ( int i=0; i<100; i++ ) { Weather weather = new Weather(); weather.setTitle("weather #"+i); weather.setSolve( i%2 == 0 ); mWeathers.add( weather ); } } public List<Weather> getWeathers() { return mWeathers; } public Weather getWeather( UUID id ) { for ( Weather weather : mWeathers ) { if( weather.getId().equals(id) ) { return weather; } } return null; } }
运行: