相关引用:
1. 《第一行代码 第二版》
2. https://www.jianshu.com/p/f86f59dccaef
3. https://www.jianshu.com/p/991062d964cf
拓展性更好、添加动画效果更加方便(自带ItemAnimation)、性能更好( ListView继承自:AbsListView。(GirdView也是), RecyclerView直接继承了ViewGroup,从封装的层次上得出了为什么RecyclerView性能比ListView更好的原因, 因为封装的层次越高,查询执行的速度相对较慢),更加灵活
moudle下的build.gradle添加依赖
dependencies{
compile fileTree(dir: 'libs',include: ['*.jar'])
compile 'com.android.support:appcompat-v7:24.2.1'
compile 'com.android.support:recyclerview-v7:24.2.1'
testCompile 'junit:junit:4.12'
}
在布局文件中添加该组件
由于RecyclerView不是内置在SDK中,所以要把完整的包路径写出来。
创建适配器
public class MyRecyclerViewAdapter extends RecyclerView.Adapter {
private final LayoutInflater mLayoutInflater;
private final Context mContext;
private String[] mTitles;
// 传递数据源
public MyRecyclerViewAdapter(Context context,String[] strs) {
mTitles = strs;
mContext = context;
mLayoutInflater = LayoutInflater.from(context);
}
// 用于创建ViewHolder实例,在这个方法中将item的布局加载出来
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {// 第二个参数就是View的类型,实现多布局关键
return new ViewHolder(mLayoutInflater.inflate(R.layout.item_text, parent, false));
}
// 对每个item进行赋值,会在每个子项被滚动到屏幕内的时候执行
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
String str = mTitles[position];
holder.mTextView.setText(str);
}
// 告诉RecyclerView有多少子项
@Override
public int getItemCount() {
return mTitles == null ? 0 : mTitles.length;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView mTextView;
ViewHolder(View view) {
super(view);
mTextView = (TextView)view.findViewById(R.id.tv_title);
}
}
}
在Acvitiy中设置
public class MainActivity extends ActionBarActivity {
private RecyclerView mRecyclerView;
private String[] mTitles;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
mRecyclerView = (RecyclerView)findViewById(R.id.recyclerView);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));//这里用线性显示 类似于listview
// mRecyclerView.setLayoutManager(new GridLayoutManager(this, 2));//这里用线性宫格显示 类似于grid view
// mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, OrientationHelper.VERTICAL));//这里用线性宫格显示 类似于瀑布流
mRecyclerView.setAdapter(new NormalRecyclerViewAdapter(this,mTitles));
}
private void initData() {
//to do sth here
}
}
设置点击事件
其实ListView的setOnItemClickListener()注册的是子项的点击事件,如果想点击的是子项里面具体控件的事件,那就比较麻烦了。居以此,RecyclerView的点击事件是由具体的View去注册
public class MyRecyclerViewAdapter extends RecyclerView.Adapter {
private final LayoutInflater mLayoutInflater;
private final Context mContext;
private String[] mTitles;
// 传递数据源
public MyRecyclerViewAdapter(Context context,String[] strs) {
mTitles = strs;
mContext = context;
mLayoutInflater = LayoutInflater.from(context);
}
// 用于创建ViewHolder实例,在这个方法中将item的布局加载出来
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mLayoutInflater.inflate(R.layout.item_text, parent, false);
final ViewHolder holder = new ViewHolder(view);
holder.mRootView.setOnClickListener(new OnClickListener(){
@override
public void onClick(View v){
//to do sth here
}
});
holder.mTextView.setOnClickListener(new OnClickListener(){
@override
public void onClick(View v){
//to do sth here
}
});
return holder;
}
// 对每个item进行赋值,会在每个子项被滚动到屏幕内的时候执行
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
String str = mTitles[position];
holder.mTextView.setText(str);
}
// 告诉RecyclerView有多少子项
@Override
public int getItemCount() {
return mTitles == null ? 0 : mTitles.length;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
View mRootView;
TextView mTextView;
ViewHolder(View view) {
super(view);
mRootView = view;
mTextView = (TextView)view.findViewById(R.id.tv_title);
}
}
}
我们知道,在ListView中设置多种布局的关键就是getItemViewType()
与getViewTypeCount()
,在RecyclerView中,只有getItemViewType()
,其用法也与ListView一致。并且onCreateViewHolder()
的第二个参数int viewType
就是getItemViewType()
的返回值。思路如下:
定义不同的viewType常量(非必须) 。
在getItemViewType方法中根据position来返回不同的viewType 。
根据getItemViewType方法返回的不同的viewType在onCreateViewHolder创建不同的ViewHolder。
onBindViewHolder方法里面用instanceof判断不同的ViewHolder来做不通的赋值处理。
注意getItemCount的返回值
public class ViewTypeActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private List mDatas;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initData();
setContentView(R.layout.activity_water_full);
mRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerview);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.addItemDecoration(new SpacesItemDecoration(12));
mRecyclerView.setAdapter(new ViewTypeAdapter());
}
private void initData() {
mDatas = new ArrayList();
for (int i = 0; i < 24; i++) {
mDatas.add("位置是" + i);
}
}
class ViewTypeAdapter extends RecyclerView.Adapter{
public static final int ONE_ITEM = 1;
public static final int TWO_ITEM = 2;
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater mInflater = LayoutInflater.from(ViewTypeActivity.this);
RecyclerView.ViewHolder holder = null;
if(ONE_ITEM == viewType){
View v = mInflater.inflate(R.layout.item_linear,parent,false);
holder = new OneViewHolder(v);
}else{
View v = mInflater.inflate(R.layout.item_two,parent,false);
holder = new TwoViewHolder(v);
}
return holder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if(holder instanceof OneViewHolder){
((OneViewHolder) holder).tv.setText(mDatas.get(position));
}else {
((TwoViewHolder) holder).tv1.setText(mDatas.get(position));
((TwoViewHolder) holder).tv2.setText(mDatas.get(position));
}
}
@Override
public int getItemViewType(int position) {
if(position % 3 == 0){
return TWO_ITEM;
}else{
return ONE_ITEM;
}
}
@Override
public int getItemCount() {
return mDatas.size();
}
class OneViewHolder extends RecyclerView.ViewHolder{
TextView tv;
public OneViewHolder(View itemView) {
super(itemView);
tv = (TextView) itemView.findViewById(R.id.adapter_linear_text);
}
}
class TwoViewHolder extends RecyclerView.ViewHolder{
TextView tv1,tv2;
public TwoViewHolder(View itemView) {
super(itemView);
tv1 = (TextView) itemView.findViewById(R.id.adapter_two_1);
tv2 = (TextView) itemView.findViewById(R.id.adapter_two_2);
}
}
}
}
作者:丿歌吟有梦
链接:https://www.jianshu.com/p/f86f59dccaef
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
当RecyclerView为LinearLayoutManager,我们可以通过viewType给RecyclerView来设置Header和Footer,但是当布局管理器为GridLayoutManager和StaggeredGridLayoutManager时就要不能这样去做了。
如何去加我会放在后面去写:
public static final int HEADER = 1;
public static final int FOOTER = 2;
public static final int ITEM = 3;
@Override
public int getItemViewType(int position) {
if(position == 0){
return HEADER;
}else if(position == getItemCount() -1){
return FOOTER;
}else{
return ITEM;
}
}
@Override
public int getItemCount() {
return mDatas.size() + 2;//Header和Footer
}
作者:丿歌吟有梦
链接:https://www.jianshu.com/p/f86f59dccaef
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。