使用 Recycler 和Card Views
为了在屏幕上显示美丽的风景,你需要一个view。你可以使用 RecyclerView作为ListView的替代者,但它比ListView更加强大,Google把它描述成一个‘非常灵活的view,可以在有限的空间里提供很大的数据来显示’。在这一张你将会证明这一点。
用xml去定义RecyclerView
在 activity_main.xml加上这一句
<android.support.v7.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/light_gray"/>
现在你在页面上就有了一个RecyclerView,需要注意的是它的大小应该是match_parent的
初始化RecyclerView,指派LayoutManager
在MainActivity.java,
private RecyclerView mRecyclerView;
private StaggeredGridLayoutManager mStaggeredLayoutManager;
只是定义了两个变量,一个是RecyclerView的引用,另外一个是LayouyManager的引用
在onCreate最后加上下面的代码
mRecyclerView = (RecyclerView) findViewById(R.id.list);
mStaggeredLayoutManager = new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(mStaggeredLayoutManager);
在上面的代码里,你初始化的RecyclerView,并且指派了StaggeredGridLayout ,StaggeredGridLayout 你用它创建了竖直的挫列网格。第一个参数是列的数量,第二个是方向。1个列让它成为了一个list而不是grid,等会你将看到如何让它变成两列。
创建行,使用Card View
CardView 提供了一系列的背景,包括圆角和阴影,你将实现RecyclerView的悲歌条目,默认的CardView 继承自FrameLayout ,所以有存储其他子view 的能力
新建布局文件row_places.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/placeCard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
card_view:cardCornerRadius="@dimen/card_corner_radius"
card_view:cardElevation="@dimen/card_elevation">
<ImageView
android:id="@+id/placeImage"
android:layout_width="match_parent"
android:layout_height="200dp"
android:scaleType="centerCrop" />
<!-- 响应点击事件用的-->
<LinearLayout
android:id="@+id/mainHolder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:selectableItemBackground"
android:orientation="horizontal" />
<LinearLayout
android:id="@+id/placeNameHolder"
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_gravity="bottom"
android:orientation="horizontal">
<TextView
android:id="@+id/placeName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="left"
android:paddingLeft="10dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="@android:color/white" />
</LinearLayout>
</android.support.v7.widget.CardView>
通过引入xmlns:card_view=”http://schemas.android.com/apk/res-auto”,你就可以使用类似card_view:cardCornerRadius and card_view:cardElevation 的属性,这些属性让 Material Design 使你的card-view真的像一个card
注意mainHolder,你需要?android:selectableItemBackground作为背景。这个会产生ripple 效果在用户点击的时候,很多app都这样,你等一会就会看到效果
实现Recycler VIew 的Adapter
创建新的java类,名字是TravelListAdapter
// 1
public class TravelListAdapter extends RecyclerView.Adapter<TravelListAdapter.ViewHolder> {
Context mContext;
// 2
public TravelListAdapter(Context context) {
this.mContext = context;
}
// 3
public class ViewHolder extends RecyclerView.ViewHolder {
public LinearLayout placeHolder;
public LinearLayout placeNameHolder;
public TextView placeName;
public ImageView placeImage;
public ViewHolder(View itemView) {
super(itemView);
placeHolder = (LinearLayout) itemView.findViewById(R.id.mainHolder);
placeName = (TextView) itemView.findViewById(R.id.placeName);
placeNameHolder = (LinearLayout) itemView.findViewById(R.id.placeNameHolder);
placeImage = (ImageView) itemView.findViewById(R.id.placeImage);
}
}
}
注意发生了什么
- TravelListAdapter extend Recycler.Adapter 这样你就能重写很多方法
- 在构造方法里传递上下文,等会就知道用处
- 创建ViewHolder 类,虽然在ListView里是可选的,但是RecyclerView 强制使用,这个在滚动的时候表现更好,避免多次调用findViewById()
因为你的adapter是RecyclerView.Adapter的子类,所以需要重写下面的方法
// 1
@Override
public int getItemCount() {
return new PlaceData().placeList().size();
}
// 2
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_places, parent, false);
return new ViewHolder(view);
}
// 3
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final Place place = new PlaceData().placeList().get(position);
holder.placeName.setText(place.name);
Picasso.with(mContext).load(place.getImageResourceId(mContext)).into(holder.placeImage);
}
发生了什么?
- getItemCount()返回数量
- onCreateViewHolder(…) 返回ViewHolder ,你要先用你的xml填充
- onBindViewHolder(…) 把Place 对象和ViewHolder进行了绑定,你将使用Picasso 来缓存图片
在
MainActivity 加上
private TravelListAdapter mAdapter;
mAdapter = new TravelListAdapter(this);
mRecyclerView.setAdapter(mAdapter);
你喜欢哪个地方?我喜欢加拿大。不管你想去哪,你都要记下来你要去那里干啥,首先,你要响应用户的点击
下一章我们将会讨论点击事件的实现