Android开发之5.0特性深入理解(一)

5.0特性,新增两个控件RecyclerView和CardView,新增阴影属性android:elevation,可以定制启动动画,还提供了一个主题 android:Theme.Material等不胜枚举,下面先从主题说起吧。


  • @android:style/Theme.Material
  • @android:style/Theme.Material.Light
  • @android:style/Theme.Material.Light.DarkActionBar

    该主题包资源位于android21下面res>values里面的themes_material.xml。在主题包里面追根溯源发现name=”Platform.AppCompat” parent=”android:Theme.Material”,所以我们在使用该主题时,只需要Activity继承AppCompatActivity,自定义AppCompat的系列的主题即可,实例如下:

values: styles

<resources>
    <style name="AppTheme" parent="AppBaseTheme">  
    </style>
    <style name="AppBaseTheme" parent="Theme.AppCompat.Light">
        <!-- customize the color palette -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:textColorPrimary">@color/textColorPrimary</item>
    </style>
</resources>

也可以在>=21的values-v21++中自定义statusBar颜色:

  <style name="AppTheme" parent="AppBaseTheme">
        <item name="android:statusBarColor">@color/statusBarColor</item>
    </style>

提醒一句这个是没问题的,但是在有些低配定制手机上(联想手机)会发现statusBarColor设置无效果,具体兼容虽然做出来但是不给各位推荐,低配中得低配就不要管了(联想负责这块的攻城狮rg了)下面先来看看效果图:

接着我们来用RecycleView控件实现ListView列表效果如下图

首先添加RecyclerView的项目引用(as开发对应的recyclerView的版本号也许不同)

  compile 'com.android.support:recyclerview-v7:23.2.1'

xml布局实例:

<?xml version="1.0" encoding="utf-8"?>
<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 //该属性设置于一个被其他布局<include>的布局的根元素上。
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<RecyclerViewBean> getRecyclerViewBeans() {

        ArrayList<RecyclerViewBean> 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<RecyclerViewBean> list;

    public ArrayList<RecyclerViewBean> getList() {
        return list;
    }

    public void setList(ArrayList<RecyclerViewBean> list) {
        if (list == null) {
            list = new ArrayList<>();
        }
        this.list = list;
    }

    public RecyclerViewAdapter(ArrayList<RecyclerViewBean> 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
  • GridLayoutManager
  • StaggeredGridLayoutManager(可以实现瀑布流)
        //布局管理
        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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值