RecyclerView、CardView实战
来源:互联网 发布:帝国时代3mac版本 编辑:程序博客网 时间:2024/05/01 20:16
本篇blog参照网上大神demo实现,效果一样http://frank-zhu.github.io/android/2015/02/26/android-recyclerview-part-3/。
关键点:
- CardView的使用,CardView继承的是FrameLayout,所以摆放内部控件的时候需要注意一下;
- RecyclerView的简单使用,关键理解RecyclerView实现的思想,对比ListView学习;
- array配置文件读取
一、首先,引入依赖包,重新编译
compile 'com.android.support:appcompat-v7:22.2.0' compile 'com.android.support:recyclerview-v7:21.0.3' compile 'com.android.support:cardview-v7:21.0.3'
CardView
先来简单介绍下CardView,其实我们可以在很多App中已经看到过这样的效果,就是把list的一个item做成卡片样式的,之前很多人通过自定义view可以实现卡片的效果,不过现在有了现成的,Google亲生。CardView继承的是FrameLayout,所以摆放内部控件的时候需要注意一下啦。
简单总结下CardView的参数:
<resources> <declare-styleable name="CardView"> <!-- Background color for CardView. --> <!-- 背景色 --> <attr name="cardBackgroundColor" format="color" /> <!-- Corner radius for CardView. --> <!-- 边缘弧度数 --> <attr name="cardCornerRadius" format="dimension" /> <!-- Elevation for CardView. --> <!-- 高度 --> <attr name="cardElevation" format="dimension" /> <!-- Maximum Elevation for CardView. --> <!-- 最大高度 --> <attr name="cardMaxElevation" format="dimension" /> <!-- Add padding in API v21+ as well to have the same measurements with previous versions. --> <!-- 设置内边距,v21+的版本和之前的版本仍旧具有一样的计算方式 --> <attr name="cardUseCompatPadding" format="boolean" /> <!-- Add padding to CardView on v20 and before to prevent intersections between the Card content and rounded corners. --> <!-- 在v20和之前的版本中添加内边距,这个属性是为了防止卡片内容和边角的重叠 --> <attr name="cardPreventCornerOverlap" format="boolean" /> <!-- 下面是卡片边界距离内部的距离--> <!-- Inner padding between the edges of the Card and children of the CardView. --> <attr name="contentPadding" format="dimension" /> <!-- Inner padding between the left edge of the Card and children of the CardView. --> <attr name="contentPaddingLeft" format="dimension" /> <!-- Inner padding between the right edge of the Card and children of the CardView. --> <attr name="contentPaddingRight" format="dimension" /> <!-- Inner padding between the top edge of the Card and children of the CardView. --> <attr name="contentPaddingTop" format="dimension" /> <!-- Inner padding between the bottom edge of the Card and children of the CardView. --> <attr name="contentPaddingBottom" format="dimension" /> </declare-styleable></resources>
RecyclerView
先来说说RecycleView的优点就是,他可以通过设置LayoutManager来快速实现listview、gridview、瀑布流的效果,而且还可以设置横向和纵向显示,添加动画效果也非常简单(自带了ItemAnimation,可以设置加载和移除时的动画,方便做出各种动态浏览的效果),也是官方推荐使用的。
关键是RecyclerView将view的操作交给了Adapter,而不在自身处理view。
OK,简单了解了CardView、RecyclerView,接下来实现我们的效果!
简单效果的实现:
很简单的List列表样式,外层RecycleView,item用CardView实现。
activity_main布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <android.support.v7.widget.RecyclerView android:id="@+id/m_rv" android:layout_width="wrap_content" android:layout_height="wrap_content" /></RelativeLayout>
关键是我们的NormalRecyclerViewAdapter
package com.wj.adapter;import android.content.Context;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import android.widget.Toast;import com.wj.R;/** * Created by ${wj} , * on 2015/7/15 0015. */public class NormalRecyclerViewAdapter extends RecyclerView.Adapter<NormalRecyclerViewAdapter.NormalTextViewHolder>{ /** * 视图加载器 */ private LayoutInflater mInflater; /** * 内容提供者 */ private Context mContext; /** * Item展示的内容,这里只是一个简单的text. */ private String[] mTitles; /** * 构造器,正常应该传入我们Item所要展示的对象List,这里只是简单实现了文字展示 * @param context */ public NormalRecyclerViewAdapter(Context context) { this.mContext = context; mInflater=LayoutInflater.from(mContext); mTitles=mContext.getResources().getStringArray(R.array.titles); } /** * 创建RecyclerView的VIewHolder * @param viewGroup * @param i * @return */ @Override public NormalTextViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { //加载布局文件 View view=mInflater.inflate(R.layout.item_text,viewGroup,false); //创建布局文件对应的ViewHolder return new NormalTextViewHolder(view); } /** * 实例化viewHolder中各控件内容 * @param normalTextViewHolder * @param i */ @Override public void onBindViewHolder(NormalTextViewHolder normalTextViewHolder, int i) { normalTextViewHolder.itemText.setText(mTitles[i]); } /** * 返回Item个数 * @return */ @Override public int getItemCount() { return mTitles==null ? 0 : mTitles.length; } /** * RecyclerView关键类,ViewHolder.这个就是RecyclerView优于ListView的关键点之一,封装了ViewHolder,可以更好的实现view的重载 * 这里需要做的操作 * 1.声明我们的Item里面的所有控件 * 2.在构造函数中初始化我们声明的控件 * 3.可以设置Item的点击事件,不再像ListView一样,交给外层来处理 */ public class NormalTextViewHolder extends RecyclerView.ViewHolder{ private TextView itemText; public NormalTextViewHolder(View itemView) { super(itemView); itemText= (TextView) itemView.findViewById(R.id.text_view); itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(mContext,mTitles[getPosition()],Toast.LENGTH_SHORT).show(); } }); } }}
为了方便理解,我加了详细的注释
MainActivity中很简单
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mRecyclerView= (RecyclerView) findViewById(R.id.m_rv); mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); //mRecyclerView.setLayoutManager(new GridLayoutManager(this,2)); mAdapter=new NormalRecyclerViewAdapter(this); mRecyclerView.setAdapter(mAdapter);// mAdapter1=new MultipleItemAdapter(this);// mRecyclerView.setAdapter(mAdapter1); }
关键注意:设置Layoutmanger方法,可以看到上面代码我们设置了linearLayoutManger和GridLayoutManger,就可以分别实现上面的两种效果。
接下来再来看一下Adapter的复杂用法,可以看到下面效果Item的展示形式不一样,对的,这里其实我们用了两个Item的布局,一个是图片+文字的,一个是单有文字的(红色背景)。感觉这样的效果蛮赞的,那么如何实现呢,其实很简单。
关键还是在Adapter中实现,MultileItemAdapter,这里我们写了两个ViewHoder
/** * 只显示文本的item */ public class TextViewHolder extends RecyclerView.ViewHolder{ private TextView itemText; public TextViewHolder(View itemView) { super(itemView); itemText= (TextView) itemView.findViewById(R.id.text_view); //Item的点击事件 itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(mContext, mTitles[getPosition()], Toast.LENGTH_SHORT).show(); } }); } }
/** * 显示图像和文本的viewhoder */ public class ImageViewHolder extends RecyclerView.ViewHolder{ private ImageView imageView; private TextView textView; public ImageViewHolder(View itemView) { super(itemView); imageView= (ImageView) itemView.findViewById(R.id.item_image_iv); textView= (TextView) itemView.findViewById(R.id.item_image_tv); //Item的点击事件 itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(mContext, mTitles[getPosition()], Toast.LENGTH_SHORT).show(); } }); } }
那么我们如何来区分加载这两个view呢,很简单
public class MultipleItemAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{ /** * 枚举类型,两种显示方式 */ public static enum ITEM_TYPE{ ITEM_TYPE_IMAGE, ITEM_TYPE_TEXT } /** * 不注释了,应该明白 */ private LayoutInflater mInflater; private Context mContext; private String[] mTitles; /** * 同上 * @param context */ public MultipleItemAdapter(Context context) { this.mContext = context; mInflater=LayoutInflater.from(mContext); //从values的array文件里读取数据 mTitles=mContext.getResources().getStringArray(R.array.titles); } /** * 关键在这里实现,onCreateViewHolder里面带了一个叫做viewType的参数,这个参数就是标识view的类型的 * @param parent * @param viewType * @return */ @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { //java.lang.Enum.ordinal()方法返回此枚举常量的序数(其枚举声明中的位置,其中初始常量分配的序数为零)。 if(viewType==ITEM_TYPE.ITEM_TYPE_IMAGE.ordinal()){ View view=mInflater.inflate(R.layout.item_image,parent,false); return new ImageViewHolder(view); }else { View view=mInflater.inflate(R.layout.item_text,parent,false); return new TextViewHolder(view); } } /** * 这里判断holder是属于哪一个,返回对应的viewhoder * @param holder * @param position */ @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if(holder instanceof ImageViewHolder){ ((ImageViewHolder)holder).imageView.setImageResource(R.drawable.test); ((ImageViewHolder)holder).textView.setText(mTitles[position]); }else if(holder instanceof TextViewHolder){ ((TextViewHolder)holder).itemText.setText(mTitles[position]); } } @Override public int getItemCount() { return mTitles==null ? 0 : mTitles.length; } /** * 关键方法,对应上面onCreateViewHoder里面的newsType * 重写Recycler.Adapter的getItemViewType方法 * 这里我们设置了单双数区别 * @param position * @return */ @Override public int getItemViewType(int position) { return position%2==0 ? ITEM_TYPE.ITEM_TYPE_IMAGE.ordinal() : ITEM_TYPE.ITEM_TYPE_TEXT.ordinal(); }
OK,基本用法介绍到这里Over!
欢迎留言指导交流!
- RecyclerView、CardView实战
- RecyclerView+CardView
- RecyclerView&CardView
- Android RecyclerView And CardView
- RecyclerView and CardView
- 学习RecyclerView和CardView
- RecyclerView CardView使用解析
- CardView,RecyclerView的使用
- RecyclerView结合CardView使用
- RecyclerView cardview点击效果
- RecyclerView+Cardview学习探索
- RecyclerView + CardView 基础练习
- Android --- Recyclerview and Cardview
- RecyclerView,CardView导入AndroidStudio
- RecyclerView CardView使用解析
- CardView、RecyclerView简单使用
- 商城项目实战 | 5.1 RecyclerView 和 CardView 更配 实现首页商品分类
- 今天新了解:RecyclerView CardView
- Android添加快捷方式(Short)到手机桌面
- Eclipse中Vi插件Vrapper的安装和使用
- 7月14日 WindowsServer 2003终止服务!
- C/C++内存管理详解
- mysql分表的3种方法
- RecyclerView、CardView实战
- 第三十五讲|问题求解方法——迭代
- 食药监移动执法指挥系统
- eclipse 注释模板设置详解
- OpenJWeb3.1 Java Web应用快速开发平台全部开源公告
- Java学习------基本数据类型转换
- iOS开发中MVC、MVVM模式详解
- 深入浅出聊Unity3D项目优化:从Draw Calls到GC
- powerbuilder日期函数