介绍 RecyclerView 是android-support-v7-21版本中新增的一个Widgets,官方介绍 RecyclerView 是 ListView 的升级版本,更加先进和灵活。
CardView 则是Google提供的一个卡片式视图组件
这个例子将展示一个使用RecyclerView展示多个显示联系人资料的CardView的例子。
布局 为了使用RecyclerView和CardView,需要导入support-v7中的两个包。在Android Studio上面很容易。
1 2 3 4 5 dependencies { ... compile 'com.android.support:recyclerview-v7:21.0.3' compile 'com.android.support:cardview-v7:21.0.3' }
RecyclerView和ListView非常类似,我们可以用同样的方式放入布局里面。
1 2 3 4 5 6 7 8 9 10 11 12 13 <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/cardList" android:layout_width ="match_parent" android:layout_height ="match_parent" /> </RelativeLayout >
这是一个卡片布局,包含了几个TextView用来展示用户资料
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 <?xml version="1.0" encoding="utf-8" ?> <android.support.v7.widget.CardView android:layout_width ="match_parent" android:layout_height ="match_parent" android:id ="@+id/card_view" card_view:cardCornerRadius ="4dp" android:layout_margin ="5dp" xmlns:android ="http://schemas.android.com/apk/res/android" xmlns:card_view ="http://schemas.android.com/apk/res-auto" > <RelativeLayout android:layout_width ="match_parent" android:layout_height ="match_parent" > <TextView android:id ="@+id/title" android:layout_width ="match_parent" android:layout_height ="20dp" android:background ="@color/bkg_card" android:text ="contact det" android:gravity ="center_vertical" android:textColor ="@android:color/white" android:textSize ="14dp" /> <TextView android:id ="@+id/txtName" android:layout_width ="wrap_content" android:layout_height ="wrap_content" android:text ="Name" android:gravity ="center_vertical" android:textSize ="10dp" android:layout_below ="@id/title" android:layout_marginTop ="10dp" android:layout_marginLeft ="5dp" /> <TextView android:id ="@+id/txtSurname" android:layout_width ="wrap_content" android:layout_height ="wrap_content" android:text ="Surname" android:gravity ="center_vertical" android:textSize ="10dp" android:layout_below ="@id/txtName" android:layout_marginTop ="10dp" android:layout_marginLeft ="5dp" /> <TextView android:id ="@+id/txtEmail" android:layout_width ="wrap_content" android:layout_height ="wrap_content" android:text ="Email" android:textSize ="10dp" android:layout_marginTop ="10dp" android:layout_alignParentRight ="true" android:layout_marginRight ="150dp" android:layout_alignBaseline ="@id/txtName" /> <TextView android:id ="@+id/txtAdd" android:layout_width ="wrap_content" android:layout_height ="wrap_content" android:text ="Address" android:textSize ="10dp" android:layout_alignStart ="@id/txtEmail" android:layout_alignBaseline ="@id/txtSurname" /> </RelativeLayout > </android.support.v7.widget.CardView >
代码 我们先来建个联系人类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 package cn.treize.recyclerviewandcardview;public class ContactInfo { protected String name; protected String surname; protected String email; protected static final String NAME_PREFIX = "Name_" ; protected static final String SURNAME_PREFIX = "Surname_" ; protected static final String EMAIL_PREFIX = "Email_" ; }
自定义的RecyclerView.Adapter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 package cn.treize.recyclerviewandcardview;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import java.util.List;public class ContactAdapter extends RecyclerView .Adapter<ContactAdapter.ContactViewHolder> { private List<ContactInfo> contactList; public ContactAdapter (List<ContactInfo> contactList) { this .contactList = contactList; } @Override public ContactViewHolder onCreateViewHolder (ViewGroup parent, int viewType) { View itemView = LayoutInflater.from(parent.getContext()) .inflate(R.layout.card_item, parent ,false ); return new ContactViewHolder (itemView); } @Override public void onBindViewHolder (ContactViewHolder holder, int position) { ContactInfo ci = contactList.get(position); holder.vName.setText(ci.name); holder.vEmail.setText(ci.email); holder.vSurname.setText(ci.surname); holder.vTitle.setText(ci.name + " " + ci.surname); } @Override public int getItemCount () { return contactList.size(); } public static class ContactViewHolder extends RecyclerView .ViewHolder { protected TextView vName; protected TextView vSurname; protected TextView vEmail; protected TextView vTitle; public ContactViewHolder (View v) { super (v); vName = (TextView) v.findViewById(R.id.txtName); vSurname = (TextView) v.findViewById(R.id.txtSurname); vEmail = (TextView) v.findViewById(R.id.txtEmail); vTitle = (TextView) v.findViewById(R.id.title); } } }
MainAcitvity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 package cn.treize.recyclerviewandcardview;import android.os.Bundle;import android.support.v7.app.ActionBarActivity;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.view.Menu;import android.view.MenuItem;import java.util.ArrayList;import java.util.List;public class MainActivity extends ActionBarActivity { @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); RecyclerView recyclerView = (RecyclerView) findViewById(R.id.cardList); recyclerView.setHasFixedSize(true ); LinearLayoutManager layoutManager = new LinearLayoutManager (this ); layoutManager.setOrientation(LinearLayoutManager.VERTICAL); recyclerView.setLayoutManager(layoutManager); ContactAdapter adapter = new ContactAdapter (createList(30 )); recyclerView.setAdapter(adapter); } @Override public boolean onCreateOptionsMenu (Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); return true ; } @Override public boolean onOptionsItemSelected (MenuItem item) { int id = item.getItemId(); if (id == R.id.action_settings) { return true ; } return super .onOptionsItemSelected(item); } public List<ContactInfo> createList (int size) { List<ContactInfo> contactList = new ArrayList <ContactInfo>(); for (int i=1 ; i<= size; i++){ ContactInfo ci = new ContactInfo (); ci.name = ContactInfo.NAME_PREFIX + i; ci.surname = ContactInfo.SURNAME_PREFIX +i; ci.email = ContactInfo.EMAIL_PREFIX +i; contactList.add(ci); } return contactList; } }
效果如下
OnItemClick方法 我们发现RecyclerView没有OnItemClick之类的方法。那怎么实现呢,有很多种方法。这里用的是来说StackOverFlow 的一个方法,看别人的回复说有延迟,但是我在模拟器中使用没发现。
他的使用方法很简单:
1 2 3 4 5 6 7 8 9 RecyclerView recyclerView = findViewById(R.id.recycler);recyclerView.addOnItemTouchListener(new RecyclerItemClickListener (getApplicationContext(),new RecyclerItemClickListener .OnItemClickListener(){ @Override public void onItemClick (View view, int position) { ((TextView)view.findViewById(R.id.title)).setText("onClick~~~~~~~~~~~~~~~" ); Toast.makeText(getApplicationContext(),"this is " + (position+1 ) +" item" , Toast.LENGTH_LONG).show(); } }));
RecyclerItemClickListener的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 package cn.treize.recyclerviewandcardview;import android.content.Context;import android.support.v7.widget.RecyclerView;import android.view.GestureDetector;import android.view.MotionEvent;import android.view.View;public class RecyclerItemClickListener implements RecyclerView .OnItemTouchListener { private OnItemClickListener mListener; public interface OnItemClickListener { public void onItemClick (View view, int position) ; } GestureDetector mGestureDetector; public RecyclerItemClickListener (Context context, OnItemClickListener mListener) { this .mListener = mListener; mGestureDetector = new GestureDetector (context, new GestureDetector .SimpleOnGestureListener(){ @Override public boolean onSingleTapUp (MotionEvent e) { return true ; } }); } @Override public boolean onInterceptTouchEvent (RecyclerView rv, MotionEvent e) { View childView = rv.findChildViewUnder(e.getX(), e.getY()); if (childView != null && mListener !=null && mGestureDetector.onTouchEvent(e)) { mListener.onItemClick(childView,rv.getChildPosition(childView)); return true ; } return false ; } @Override public void onTouchEvent (RecyclerView rv, MotionEvent e) { } }
效果如下:
本文中的代码可以在GitHub 中找到。