随着Android版本的更新,出现了越来越多的新控件,作为一名Android程序员很有必要去关心这些东西,毕竟面试的时候很多面试官喜欢问。大家肯定都知道ListView这个控件,因为很多地方都需要用到它。自Android 5.0之后,谷歌公司推出了RecycleVIew控件,这个滑动控件的功能非常强大,既能实现ListView的功能,也能实现GridView的效果,下面就让我们一起去看看这个控件如何使用吧。
首先我们先来看看他是怎么实现ListView的功能吧,不多说,直接上代码:
public class RecyclerViewActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private LinearLayoutManager mLayoutManager;
private RecyclerViewAdapter mRecyclerViewAdapter;
private List<JavaBean> mList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycler_view);
mRecyclerView = (RecyclerView) findViewById(R.id.activity_recycler_view);
initData();
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerViewAdapter = new RecyclerViewAdapter(this, mList, mRecyclerView);
mRecyclerView.setAdapter(mRecyclerViewAdapter);
}
private void initData() {
mList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
mList.add(new JavaBean("sorelion" + i));
mList.add(new JavaBean("sorelion" + i));
}
}
}
适配器代码
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int TYPE_HEADER = 0;
private static final int TYPE_NORMAL = 1;
private final RecyclerView mRecyclerView;
private List<JavaBean> mlist;
private Context mContext;
private View mHeaderView;
public RecyclerViewAdapter(Context context, List<JavaBean> list, RecyclerView mRecyclerView) {
this.mlist = list;
this.mContext = context;
this.mRecyclerView = mRecyclerView;
mHeaderView = LayoutInflater.from(mContext).inflate(R.layout.item1, mRecyclerView, false);
}
@Override
public RecyclerHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_HEADER) {
return new RecyclerHolder(mHeaderView);
} else {
View view = LayoutInflater.from(mContext).inflate(R.layout.item, parent, false);
RecyclerHolder holder = new RecyclerHolder(view);
return holder;
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (position == 0) {
return;
} else {
((RecyclerHolder) holder).text.setText(mlist.get(position).getName());
}
}
@Override
public int getItemCount() {
return mlist == null ? 0 : mlist.size();
}
@Override
public int getItemViewType(int position) {
if (position == 0) {
return TYPE_HEADER;
}
return TYPE_NORMAL;
}
class RecyclerHolder extends RecyclerView.ViewHolder {
TextView text;
public RecyclerHolder(View itemView) {
super(itemView);
if (itemView == mHeaderView) return;
text = (TextView) itemView.findViewById(R.id.text);
}
}
我们跑起来看看效果
是不是和ListView一样呢,那么下面我们来看看双列会有什么效果呢?
我们换一个LayoutManage就可以达到效果.
mLayoutManager = new GridLayoutManager(this, 2);
问题出来了,怎么成这样了?仔细分析一下就会知道,因为在我们上面的代码中,当position为0的时候,我们会填充一个头布局,其他情况填充正常的布局,所以这种情况的出现是可以理解的,但是这明显不是我们想要的效果,怎么办呢?
这时候我们需要重写一个方法:
gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return getItemViewType(position) == TYPE_HEADER
? gridManager.getSpanCount() : 1;
}
});
怎么理解呢?我的理解就是判断当前的条目是不是头布局,是头布局,那么就占据相应的单元格(根据GridManager初始化时的参数),正常就只占据一个单元格,借鉴大神的建议,我决定把这个方法这样放:
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
if (manager instanceof GridLayoutManager) {
final GridLayoutManager gridManager = ((GridLayoutManager) manager);
gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return getItemViewType(position) == TYPE_HEADER
? gridManager.getSpanCount() : 1;
}
});
}
}
跑起来在看看效果
哈哈,终于完美解决问题了,可能有些人对下面的一段代码就不理解了,为什么我position等于1的时候不需要判断呢,明明一个header布局相当于占据了两个position的位置啊。
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (position == 0) {
return;
} else {
((RecyclerHolder) holder).text.setText(mlist.get(position).getName());
}
}
对于这块,我也只是稍微翻了翻源码(毕竟全英文,上班没那么多时间去研究),稍微理解了一下,有兴趣的可以自己去看看源码,去揭开它的神秘面纱吧。有了这些思路,显示多类型的条目是不是有了思路呢?当然你也可以像ListView那样,封装自己的addheader和addfoot方法,究竟怎么玩,那就看你了。