5.0特性,新增两个控件RecyclerView和CardView,新增阴影属性android:elevation,可以定制启动动画,还提供了一个主题 android:Theme.Material等不胜枚举,下面先从主题说起吧。
@android:style/Theme.Material.Light.DarkActionBar
该主题包资源位于android21下面res>values里面的themes_material.xml。在主题包里面追根溯源发现name=”Platform.AppCompat” parent=”android:Theme.Material”,所以我们在使用该主题时,只需要Activity继承AppCompatActivity,自定义AppCompat的系列的主题即可,实例如下:
values: styles
也可以在>=21的values-v21++中自定义statusBar颜色:
<style name="AppTheme" parent="AppBaseTheme">
<item name="android:statusBarColor">@color/statusBarColor
style>
提醒一句这个是没问题的,但是在有些低配定制手机上(联想手机)会发现statusBarColor设置无效果,具体兼容虽然做出来但是不给各位推荐,低配中得低配就不要管了(联想负责这块的攻城狮rg了)下面先来看看效果图:
首先添加RecyclerView的项目引用(as开发对应的recyclerView的版本号也许不同)
compile 'com.android.support:recyclerview-v7:23.2.1'
xml布局实例:
<LinearLayout 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"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.idea.recyclerview.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/RecyclerView_Test"
android:layout_width="match_parent"
android:background="#fff"
tools:listitem="@layout/item_recyclerview"
android:layout_height="match_parent" />
LinearLayout>
司空见惯的布局不细说了,这里值得一提的tools,使用android studio开发的伙伴应该知道它布局是可以预览的,但是有些效果比如recyclerView、ListView等布局需要运行后才能预览效果,那么此时tools的作用就显现出来了,效果如下:
tools工具的具体使用api如下:
tools:ignore //忽略警告
tools:targetApi //忽略api兼容警告
tools:locale // 忽略字符串会执行拼写检查警告
tools:context //ide在预览布局根据Activity(Activityq本质也是一个Context)该采用什么样的主题
tools:menu //IDE 在预览窗口中使用哪个菜单
tools:actionBarNavMode //actionBar的显示模式,
tools:listitem/listheader/listfooter //预览效果中添加头部 尾部 以及子item的预览布局
tools:showIn //该属性设置于一个被其他布局的布局的根元素上。
tools:layout //Fragment预览的时候该显示成什么样
话题扯远了,现在回到正题,RecyclerView需要的数据对象,通过GsonFormat插件构成如下:
接着准备业务数据DataHelper
import java.util.ArrayList;
/**
* Created by idea on 2016/3/24.
*/
public class DataHelper {
private static DataHelper instance;
public DataHelper() {
}
public static DataHelper getInstance() {
if (instance == null) {
synchronized (DataHelper.class) {
if (instance == null) {
instance = new DataHelper();
}
}
}
return instance;
}
public ArrayList getRecyclerViewBeans() {
ArrayList list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
RecyclerViewBean recyclerViewBean = new RecyclerViewBean();
recyclerViewBean.setName("胡晓菲 " + i );
recyclerViewBean.setImageUrl("");
recyclerViewBean.setMotto("我的" + i + "杀!" + "还有谁能挡我!!");
list.add(recyclerViewBean);
}
return list;
}
}
目前有了数据还差Adapter类,RecyclerView的adapter不再是和我们以前使用BaseAdapter那样,在RecyclerView类内部有一个adapter的抽象类含有ViewHolder的泛型,我们使用时继承它即可。
/**
* Created by idea on 2016/3/24.
*/
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolder> {
private ArrayList list;
public ArrayList getList() {
return list;
}
public void setList(ArrayList list) {
if (list == null) {
list = new ArrayList<>();
}
this.list = list;
}
public RecyclerViewAdapter(ArrayList list) {
setList(list);
}
@Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//这里等同于BaseAdapter里面的getView拆分成了这么两个方法onCreateViewHolder、onBindViewHolder
View converView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recyclerview,parent,false);
return new RecyclerViewHolder(converView);
}
@Override
public void onBindViewHolder(RecyclerViewHolder holder, int position) {
//绑定数据
RecyclerViewBean recyclerViewBean = getList().get(position);
holder.name.setText(recyclerViewBean.getName());
holder.itemView.setTag(recyclerViewBean);
}
@Override
public int getItemCount() {
return getList().size();
}
public void removeItem(int position){
//移除某一项,通知刷新不再是notifyChangeData..
getList().remove(position);
notifyItemRemoved(position);
}
public void addItem(int position,RecyclerViewBean recyclerViewBean){
getList().add(position,recyclerViewBean);
//更多notify相关使用查询api既可。
notifyItemInserted(position);
}
class RecyclerViewHolder extends RecyclerView.ViewHolder {
TextView name;
public RecyclerViewHolder(View itemView) {
super(itemView);
//初始化控件,当然如果你不喜欢findViewById的方式也可以使用注解
name = (TextView)itemView.findViewById(R.id.name);
}
}
}
RecyclerView的适配器有了,还差一个分割线,自定义一个类继承自RecyclerView内部的ItemDecoration,实现原理:获取分割线的属性值得到Drawable ,onDrawOver方法里面根据item位置得到变化获取到对应的位置设置边界范围,通过canvas绘图
/**
* Created by idea on 2016/3/24.
*/
public class RecycleViewDivider extends RecyclerView.ItemDecoration {
private static final int [] ATTRS ={android.R.attr.listDivider};
Drawable mDivider;
public RecycleViewDivider(Context mContext){
TypedArray a = mContext.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
a.recycle();
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent) {
super.onDrawOver(c, parent);
int left = parent.getPaddingLeft();
int right = parent.getWidth()-parent.getPaddingRight();
int count = parent.getChildCount();
for (int i = 0; i < count; i++) {
View childView = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) childView.getLayoutParams();
int top = childView.getBottom()+params.bottomMargin;
int bottom = top+ mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
}
接着我们来完成最后一步,为RecyclerView绑定适配器,目前SDK中提供了三种自带的LayoutManager:
//布局管理
LinearLayoutManager manager = new LinearLayoutManager(this);
recycleView.setLayoutManager(manager);
//添加分割线
RecycleViewDivider mDivider = new RecycleViewDivider(this);
recycleView.addItemDecoration(mDivider);
adapter = new RecyclerViewAdapter(DataHelper.getInstance().getRecyclerViewBeans());
recycleView.setAdapter(adapter);
通过以上代码实现ListView的效果,但也只是列表效果,如果我想要刷新呢,如何添加Header又成了一个问题,这里现提供一个比较简单的方案:swiperefreshlayout,更为详尽的关于刷新加载更多在下次具体详解。通过这个简单的demo对比之前的ListView 万能适配器Adapter,于是乎对于RecyclerView的想代码重构整合工作开始了…
以上整理后的RecyclerView相关代码下载地址:亚麻跌,亚麻跌,下篇吧
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0309/2567.html