自从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的目录结构:
下面我们一个一个的来看:
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客户端的效果呢?
源码下载