Android 5.0学习<二>

RecyclerView

    简单的了解RecyclerView的使用,对于更深层次的用法,可以查阅文档,或者在网上查询相关资料,以后再有机会,可以进行探讨和分享。

RecyclerView控件简介
  • ListView控件的升级版
  • LinearLayoutManager
  • GridLayoutManager
  • StaggeredGridLayoutManager
  • 订制Item,指定Item之间的分隔条
RecyclerView的使用
  • 更新Android Support Library到最新版本,拷贝\extras\android\support\v7\recyclerview\libs\文件夹下的android-support-v7-recyclerview.jar到项目中。
  • 继承ItemDecoration,实现自定义的分割线。由于RecyclerView的布局不固定,因此没有像ListView那样直接设定divider的方式。
  • 继承RecyclerView.Adapter,实现适配器。这个只要写过ListView的应该都很明白。
  • 创建出RecyclerView控件,对RecyclerView进行设置。
代码实例
  1. 继承ItemDecoration
package com.example.materialdesign.recyclerview;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.ItemDecoration;
import android.support.v7.widget.RecyclerView.LayoutParams;
import android.support.v7.widget.RecyclerView.State;
import android.view.View;

//由于RecyclerView的布局不固定,因此没有像ListView那样直接设定divider的方式,这些可能需要自己实现
public class SampleDriver extends ItemDecoration {

    // 系统自带的分隔条的资源
    private static final int[] ATTRS = { android.R.attr.listDivider };

    // 分隔条对象
    private final Drawable mDrawable;

    public SampleDriver(Context context) {
        TypedArray array = context.obtainStyledAttributes(ATTRS);

        mDrawable = array.getDrawable(0);

        // 回收TypedArray所占用的空间
        array.recycle();
    }

    // 绘制所有列表项之间的分隔条
    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, State state) {
        // 获取列表项距离左边缘的间距
        int left = parent.getLeft();

        // 获取列表项距离右边缘的间距
        int right = parent.getWidth() - parent.getPaddingRight();

        // 获取列表项总数
        int childCount = parent.getChildCount();

        // 开始绘制所有列表项之间的分割线
        for (int i = 0; i < childCount; i++) {
            // 获得当前的列表项
            View child = parent.getChildAt(i);

            // 获取当前列表项的布局参数信息
            RecyclerView.LayoutParams parentpParams = (LayoutParams) child.getLayoutParams();

            // 计算分隔条左上角的纵坐标
            int top = child.getBottom() + parentpParams.bottomMargin;

            // 计算分隔条右下角的纵坐标
            int bottom = top + mDrawable.getIntrinsicHeight();

            // 设置分隔条绘制的位置
            mDrawable.setBounds(left, top, right, bottom);

            // 开始绘制当前的列表项下方的分隔条
            mDrawable.draw(c);
        }
    }

}
  1. 继承RecyclerView.Adapter
package com.example.materialdesign.recyclerview;

import java.util.List;
import java.util.Random;

import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.example.materialdesign.R;
import com.example.materialdesign.recyclerview.SampleRecyclerAdapter.MyViewHolder;
import com.example.materialdesign.util.DataCreateFactory;

public class SampleRecyclerAdapter extends RecyclerView.Adapter<MyViewHolder> {
    private final List<String> dataList = DataCreateFactory.getData(20);

    @Override
    // 用于创建控件
    public MyViewHolder onCreateViewHolder(ViewGroup arg0, int arg1) {

        // 这里 主要创建一个TextView用于显示数据
        View item = LayoutInflater.from(arg0.getContext()).inflate(R.layout.recyclerview_item, arg0, false);

        return new MyViewHolder(item);
    }

    @Override
    public int getItemCount() {
        return dataList.size();
    }

    @Override
    public void onBindViewHolder(MyViewHolder arg0, int arg1) {
        // 获取当前Item中显示的数据
        String dataStr = dataList.get(arg1);

        // 设置要显示的数据
        arg0.textView.setText(dataStr.toString());
        arg0.textView.setTag(dataStr);
    }

    /**
     * 删除数据
     * 
     * @param pos
     */
    public void removeItem(int pos) {
        dataList.remove(pos);
        // 通知RecyclerView控件某个Item已经被删除,主要是为了动画效果
        notifyItemRemoved(pos);
    }

    /**
     * 在指定位置添加一项
     * 
     * @param posToAdd
     */
    public void addItem(int posToAdd) {
        dataList.add(posToAdd, "新的列表项<" + new Random().nextInt(10000) + ">");
        // 通知RecyclerView控件插入某个Item,会引起上述两个重写方法调用各自调用一次
        notifyItemInserted(posToAdd);
    }

    class MyViewHolder extends RecyclerView.ViewHolder {

        public TextView textView;

        public MyViewHolder(View arg0) {
            super(arg0);

            textView = (TextView) arg0.findViewById(R.id.recycleItemText);
        }
    }

}
  1. 创建控件,实现布局
package com.example.materialdesign;

import android.app.Activity;
import android.graphics.Outline;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.ItemDecoration;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewOutlineProvider;

import com.example.materialdesign.recyclerview.SampleDriver;
import com.example.materialdesign.recyclerview.SampleRecyclerAdapter;

//动态的添加,删除ReclerView里显示的数据
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.recyclerview_main);

        // 创建右下角圆形按钮,动态的裁剪图形
        ViewOutlineProvider viewOutlineProvider = new ViewOutlineProvider() {
            @Override
            public void getOutline(View view, Outline outline) {
                // 获取按钮的尺寸
                int fabSize = getResources().getDimensionPixelSize(R.dimen.fab_size);
                // 设置轮廓的尺寸
                outline.setOval(-4, -4, fabSize + 4, fabSize + 4);
            }
        };

        View addView = findViewById(R.id.recyclerViewAdd);
        addView.setOutlineProvider(viewOutlineProvider);

        // 获取RecyclerView对象
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerViewList);

        // 使用线性布局管理器,默认是垂直方向
        final LinearLayoutManager layoutManager = new LinearLayoutManager(this);

        // 为RecyclerView指定布局管理器对象
        recyclerView.setLayoutManager(layoutManager);

        // 为RecyclerView指定分割线
        ItemDecoration itemDecoration = new SampleDriver(this);
        recyclerView.addItemDecoration(itemDecoration);

        // 为RecyclerView指定适配器
        final SampleRecyclerAdapter recyclerAdapter = new SampleRecyclerAdapter();
        recyclerView.setAdapter(recyclerAdapter);

        // 处理点击事件
        addView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // 获取第一个可视的Item的位置
                int posToAdd = layoutManager.findFirstCompletelyVisibleItemPosition();
                recyclerAdapter.addItem(posToAdd);
            }
        });

        findViewById(R.id.recyclerViewDelete).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // 获取第一个可视的Item的位置
                int posToRemove = layoutManager.findFirstCompletelyVisibleItemPosition();
                recyclerAdapter.removeItem(posToRemove);
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.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);
    }
}
最终运行效果

运行起来的效果

这里写图片描述

点击右下角Button的效果

这里写图片描述

点击顶部删除按钮的效果

这里写图片描述

总结

    不涉及的复杂的用法,以及上述RecyclerView是一个很标准的ListView,所以使用起来比较简单。目的主要是在能够入门该控件,以后学习到复杂的用法时候,会再来分享用法。

    在启动程序时候,还遇到一个问题,大致的错误就是Error inflating class android.support.v7.widget.RecyclerViewCaused by: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/util/Pools$SimplePool;解决方法是,用\extras\android\support\v4\目录下的android-support-v4.jar替换项目中的v4包。

    这里有篇博客关于RecyclerView详细的阐述,有兴趣的可以学习关注一下:
http://blog.csdn.net/lmj623565791/article/details/45059587

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值