去年很早之前,我就讲解过RecyclerView的使用,今天我们就在讲解CardView的时候,顺便再把RecyclerView同时讲解一下。RecyclerView、CardView为用于显示复杂视图的新增Widget。接下来看看如何使用吧。
RecyclerView作为替代ListView使用,它更先进,更灵活,RecyclerView标准化了ViewHolder,ListView中convertView是复用的,在RecyclerView中,是把ViewHolder作为缓存的单位了,然后convertView作为ViewHolder的成员变量保持在ViewHolder中,也就是说,假设手机屏幕可显示10个条目,则会创建10个ViewHolder缓存起来,每次复用的是ViewHolder,所以他把getView这个方法变为了onCreateViewHolder。 ViewHolder更适合多种子布局的列表,尤其IM聊天对话框列表。
注意的是:RecyclerView不提供ListView中的setOnItemClickListener方法,我们可以在ViewHolder中添加类似的点击事件。
虽然RecyclerView充分考虑了它的扩展性,更好用,更灵活,但是用起来也有些麻烦。所以要使用RecyclerView,要好好考虑以下几点:
如何用呢?这里我就不过多介绍了,因为关于RecyclerView的使用,去年我很早时间就写过一篇文章。建议大家参考: Android新组件RecyclerView介绍,其效率更好(可点击)
更多推荐:
偷懒新姿势,打造属于RecyclerView的万能适配器Adapter和ViewHolder
一种新的 HeaderView + RecyclerView 实现方式
RecyclerView具体使用不讲了,今天我们顺便讲一下如何在RecyclerView加上拉更多的效果吧,下拉刷新我们使用SwipeRefreshLayout的效果就行。因为我看市面上目前大部分的app都是这样做的,下拉刷新用SwipeRefreshLayout的效果,自己在RecyclerView上添加上拉更多。
很可惜的是,RecyclerView并没有像ListView那样提供给我们addFooterView()那样的方法,那该如何实现呢?前面我们介绍RecyclerView时,说过RecyclerView适合多种嵌套的布局效果, ViewHolder更适合多种子布局的列表。所以我们看 RecyclerView的Adapter中的一个方法如下:
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType)
看到viewType了吧,就是在这里处理多种布局效果,上拉更多的布局和其他item其实没有什么区别。所以处理方式大家都知道了吧。
第一步:添加布局状态标识,并增加一项FooterView 在adapter中声明布局状态标识,是普通布局还是foot布局
private static final int TYPE_NORMAL_ITEM = 0; //普通Item
private static final int TYPE_FOOTER_ITEM = 1; //底部FooterView
在getItemCount()中加1
@Override
public int getItemCount() {
//+1是加入底部的加载布局项
return list.size() + 1;
}
第二步:重写getItemViewType判断不同布局
public int getItemViewType(int position) {
// 如果position+1等于整个布局所有数总和就是底部布局
if (position + 1 == getItemCount()) {
return TYPE_FOOTER_ITEM;
} else {
return TYPE_NORMAL_ITEM;
}
}
第三步:在onCreateViewHolder根据viewType返回不同的布局
//创建新View,被LayoutManager所调用
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
//如果viewType是普通item返回普通的布局,否则是底部布局并返回
if (viewType == TYPE_NORMAL_ITEM) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout
.cardview_recyclerview_item, viewGroup, false);
final NormalItmeViewHolder vh = new NormalItmeViewHolder(view);
if (mClickListener != null) {
vh.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mClickListener.onItemClick(vh.itemView, vh.getLayoutPosition());
}
});
}
return vh;
} else {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout
.recyclerview_footer_view, viewGroup, false);
FooterViewHolder vh = new FooterViewHolder(view);
return vh;
}
}
第四步:根据holder类型判断数据
//将数据与界面进行绑定的操作
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
if (viewHolder instanceof NormalItmeViewHolder) {
((NormalItmeViewHolder) viewHolder).titleTv.setText(list.get(position).getTitle());
((NormalItmeViewHolder) viewHolder).contentTv.setText(list.get(position).getContent());
} else if (viewHolder instanceof FooterViewHolder) {
FooterViewHolder footViewHolder = (FooterViewHolder) viewHolder;
switch (load_more_status) {
case PULLUP_LOAD_MORE:
footViewHolder.foot_view_item_tv.setVisibility(View.VISIBLE);
footViewHolder.foot_view_item_tv.setText("上拉加载更多");
footViewHolder.pb.setVisibility(View.GONE);
break;
case LOADING_MORE:
footViewHolder.foot_view_item_tv.setVisibility(View.GONE);
footViewHolder.pb.setVisibility(View.VISIBLE);
break;
}
}
}
到这里,关于上拉更多基本就配置完了。先看效果图,如下:
Adapter和Activity中的全部代码太多,而且微信对代码支持不是很好,我就不贴出来了,想看代码的去下载demo就可以了。
CardView
CardView是Android5.0之后为新增的控件,CardView是一个卡片布局,布局可以包含圆角和阴影,本质上CardView是一个FrameLayout,因此它作为一个布局容器,可以布局其他的View。
CardView中常用的属性有:
效果图如下:
代码如下:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:layout_marginTop="12dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
app:cardBackgroundColor="@color/white"
app:contentPadding="8dp"
app:cardCornerRadius="10dp"
app:cardElevation="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/item_iv"
android:layout_width="120dp"
android:layout_height="90dp"
android:layout_gravity="center_vertical"
android:layout_margin="6dp"
android:background="@drawable/item_one"
android:scaleType="centerCrop"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_marginRight="10dp"
android:layout_gravity="center_vertical"
android:orientation="vertical">
<TextView
android:id="@+id/item_title_tv"
android:layout_width="wrap_content"
android:textColor="#383838"
android:textSize="20sp"
android:textStyle="bold"
android:layout_height="wrap_content"
android:text="非著名程序员"/>
<TextView
android:id="@+id/item_content_tv"
android:textColor="#545454"
android:textSize="16sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="美女说:非著名程序员公众号是东半球最好的技术分享公众号"/>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
最后友情提醒一下,使用CardView别忘了添加依赖:
compile 'com.android.support:cardview-v7:23.4.0'
这个系列的讲解和实例都会整理在一个demo里,demo的github地址:https://github.com/loonggg/MaterialDesignDemo 去star吧,我会慢慢完善的。