自从Google的Material Design风格的出现,一直都Android开发程序员的追捧,我也比例外,没事也喜欢研究研究Google的这种设计,没事喜欢写点Demo测试一下效果,今天给大家带来的是RecycleView和CardView结合使用实现的卡片式列表布局,其中回调封装了RecycleView的Item的点击事件。
大家都知道,RecyclerView注重的不是布局,而是回收与复用View,所以Google并没有给我们提供出Item的监听事件供我们来调用,所以我们得自己实现这个功能。
先上效果图:
效果图:
首先我们先引入支持库:
compile 'com.android.support:recyclerview-v7:23.1.1'
compile 'com.android.support:cardview-v7:21.0.2'
Demo的目录结构:
下面我们一个一个的来看:
扫描二维码关注公众号,回复:
11434931 查看本文章
public class MainActivity extends AppCompatActivity {
@Bind(R.id.my_recycler_view)
RecyclerView myRecyclerView;
@Bind(R.id.progressBar)
ProgressBar progressBar;
@Bind(R.id.tv)
TextView tv;
private MyAdapter mAdapter;
private List<JsonBean> mData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
ButterKnife.bind(this);
//初始化数据
initData();
//初始化布局
initView();
}
/**
* 初始化Bean对象
*/
private void initData() {
mData = new ArrayList<>();
for (int i = 1; i < 31; i++) {
JsonBean jsonBean = new JsonBean("第"+i +"张订单");
mData.add(jsonBean);
}
}
@TargetApi(Build.VERSION_CODES.M)
private void initView() {
myRecyclerView.setHasFixedSize(true);
//设置RecyclerView适配器
mAdapter = new MyAdapter(MainActivity.this, mData);
myRecyclerView.setAdapter(mAdapter);
//为RecyclerView设置内容的布局(这里是一个线性布局)
LinearLayoutManager manager = new LinearLayoutManager(MainActivity.this);
myRecyclerView.setLayoutManager(manager);
//为RecyclerView设置Item的监听(先不用关心怎么用)
mAdapter.setOnItemClickListener(new MyItemClickListener() {
@Override
public void onItemClick(View view, int postion) {
Toast.makeText(MainActivity.this, postion+"", Toast.LENGTH_SHORT).show();
}
});
}
}
MainActivity.java中主要是一些RecyclerView的简单设置
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
private Context context;
private List<JsonBean> mList;
private LayoutInflater mInflater;
private View view;
private MyItemClickListener listener;
public MyAdapter(Context context, List<JsonBean> mList) {
this.context = context;
this.mList = mList;
mInflater = LayoutInflater.from(context);
}
@Override
public int getItemCount() {
return mList.size();
}
@Override
public MyViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
view = mInflater.inflate(R.layout.item, parent, false);
MyViewHolder viewHolder = new MyViewHolder(view, listener);
return viewHolder;
}
@Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
holder.tv.setText(mList.get(position).getText());
//如果对于Item中控件的监听,可以在此处实现
holder.iv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, position +"abc", Toast.LENGTH_SHORT).show();
}
});
}
/**
* 为Adapter暴露一个Item点击监听的公开方法
*
* @param listener
*/
public void setOnItemClickListener(MyItemClickListener listener) {
this.listener = listener;
}
}
class MyViewHolder extends RecyclerView.ViewHolder {
ImageView iv;
View itemView;
TextView tv;
MyItemClickListener mListener;
public MyViewHolder(View itemView, final MyItemClickListener mListener) {
super(itemView);
this.itemView = itemView;
iv = (ImageView) itemView.findViewById(R.id.imageview);
tv = (TextView) itemView.findViewById(R.id.textview);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mListener.onItemClick(v, getAdapterPosition());
}
});
}
}
/**
* 回调接口
*/
interface MyItemClickListener {
void onItemClick(View view, int postion);
}
上面是RecyclerView.Adapter的实现方式,相信写过ListView的同学都应该明白,只不过里面自己实现一个Item监听时间的接口回调方法,整个回调方法很简单,我在之前的Okttp3.0简单的二次回调封装中也是用的这种方法,大家可以去看一看。注意:这里的setOnItemClickListener方法在adapter中实现也就意味着这个方法是被adapter来调用的,并不是让RecyclerView来使用的,这就是为什么在MainActivity中用Adapter去调用这个方法的原因了:
mAdapter.setOnItemClickListener(new MyItemClickListener() {
@Override
public void onItemClick(View view, int postion) {
Toast.makeText(MainActivity.this, postion+"", Toast.LENGTH_SHORT).show();
}
});
对于上面都是最基本的RecyclerView的使用,那么RecyclerView在那个地方对CardView进行结合使用的呢?再上面的adapter中我们加载了一个item.xml布局,我们先来看一下。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
android:padding="15dp">
<View
android:layout_width="wrap_content"
android:layout_height="7dp"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
android:background="#2b55ee" />
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="#bebecb">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/imageview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是一张非常漂亮的图片"
android:textColor="#181818"
android:textSize="20sp" />
<TextView
android:id="@+id/textview1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是一张饿了吗订单"
android:textColor="#181818"
android:textSize="20sp" />
<TextView
android:id="@+id/textview2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="订餐者:Anonymous"
android:textColor="#181818"
android:textSize="20sp" />
<TextView
android:id="@+id/textview4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="请及时处理订单"
android:textColor="#181818"
android:textSize="20sp" />
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
因为CardView继承的是FrameLayout,所以我们要在CardView中嵌套一个LinearLayout线性布局,每个item上的蓝色的线可以用View来代替,这种效果像不像是饿了么Android客户端的效果呢?这个界面写的略显丑陋,如果你有好的设计不妨自己去修改。