RecyclerView的使用

花了一晚上的时间来研究RecyclerView的使用,现在将代码贴出,个人感觉RecyclerView相当强大,一定是以后布局的趋势,RecyclerView是5.0的新的库,其与ListView,GradView的设计思想不一样,自身也是有很多的优越性


1.RecyclerView关注点(不是关注点就是这个的效果要自己去设置)
仅关注回收与复用view,
不关注
Item的显示位置显示风格----LayoutManager
Item间的分隔------ItemDecoration
Item增加与删除的动画效果-----ItemAnimator
Adapter
ViewHolder


2.RecyclerView能干什么
实现ListView
实现GridView
横向ListView
横向GridView
瀑布流
定制Item增加与删除动画 (ItemAnimator)


3.使用前导包
android studio
导入jar包file->project structure->选中所用的medule->dependencis->"+"->选到v7的recyclerview包
eclipse
在sdk中extras下找到v7包导入项目即可



话不多说上代码

MainActivity.java

package cn.bigniu.recyclerviewdemo;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;


import java.util.ArrayList;
import java.util.List;



public class MainActivity extends AppCompatActivity {

    private RecyclerView mRecyclerView;
    private List<String> mDatas;
    private SimpleAdapter mAdapter;

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

        //初始化datas
        initDatas();

        //初始化View
        initViews();

        mAdapter=new SimpleAdapter(this,mDatas);
        mRecyclerView.setAdapter(mAdapter);


        /**
         * 设置RecyclerView的布局管理
         *
         *
         * ListView的显示方式
         * LinearLayoutManager(Context context, int orientation, boolean reverseLayout)
         */
        LinearLayoutManager linearLayoutManager=
                new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
        mRecyclerView.setLayoutManager(linearLayoutManager);

        /**
         * 为删除添加设置动画效果
         *
         * DefaultItemAnimator()为系统默认的动画效果
         *
         * Github上还有很多动画效果,可以自己下载下来使用,当然也可以自己定义
         * github:https://github.com/gabrielemariotti/RecyclerViewItemAnimators
         */
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());


        //点击事件回调
        mAdapter.setmOnItemClickListener(new SimpleAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                Toast.makeText(MainActivity.this,
                        "Click:"+position,Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onItemLongClick(View view, int position) {
                Toast.makeText(MainActivity.this,
                        "Long Click"+position,Toast.LENGTH_SHORT).show();
            }
        });



        /**
         * 设置RecyclerView的Item分割线
         *
         *void addItemDecoration(ItemDecoration)
         * ItemDecoration是一个抽象类,系统也没有给我们提供一个实现类
         * 所以这里我们使用网上的一个现成类
         * 类的地址为:https://gist.github.com/alexfu/0f464fc3742f134ccdle
         *
         * 程序中的Divider其实就是从Theme中提取的listDivider方法
         * 可通过DividerItemDecoration源码查看
         */
        /*mRecyclerView.addItemDecoration(
                new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST));*/
    }

    private void initViews() {

        mRecyclerView= (RecyclerView) findViewById(R.id.id_recyclerView);
    }

    private void initDatas() {
        mDatas=new ArrayList<String>();

        for (int i='A';i<='z';i++){
            mDatas.add(""+(char)i);
        }
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.menu_main,menu);
        return true;
    }

    /**
     * 在这里面就行点击menu后实现页面的改变操作
     * @param item
     * @return
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        int id=item.getItemId();
        switch (id){
            case R.id.action_add:
                mAdapter.addData(1);
                break;
            case R.id.action_delete:
                mAdapter.deleteData(1);
                break;

            case R.id.action_gridview:
                mRecyclerView.setLayoutManager(new GridLayoutManager(this,3));
                break;

            case R.id.action_staggered:
                Intent intent=new Intent(this,StaggeredActivity.class);
                startActivity(intent);
                break;
            case R.id.action_hor_gridview:
                mRecyclerView.setLayoutManager(
                        new StaggeredGridLayoutManager(5,StaggeredGridLayoutManager.HORIZONTAL));
                break;
            case R.id.action_listview:
                mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
                break;
            default:
                break;
        }
        return super.onOptionsItemSelected(item);
    }
}


SimpleAdapter.java(ListView,GridView)
package cn.bigniu.recyclerviewdemo;

import android.content.Context;
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;

/**
 * RecyclerView给开发者提供了一个Adapter,目的是为了让开发者强制使用ViewHolder
 */
public class SimpleAdapter extends RecyclerView.Adapter<SimpleAdapter.MyViewHolder>{

    //用于加载item布局
    protected LayoutInflater mInflater;
    private Context mContext;
    protected List<String> mDatas;



    /**
     * 因为RecyclerView没有提供Item的点击事件,所以这里我们自己定义一个接口
     * 来实现点击事件
     */
    public interface OnItemClickListener{

        void onItemClick(View view,int position);
        void onItemLongClick(View view,int position);
    }

    private OnItemClickListener mOnItemClickListener;

    public void setmOnItemClickListener(OnItemClickListener onItemClickListener){
        this.mOnItemClickListener=onItemClickListener;
    }

 /** -------------------------------------------------------------------------- **/
    public SimpleAdapter(Context context,List<String> datas) {
        this.mContext=context;
        this.mDatas=datas;
        mInflater=LayoutInflater.from(context);
    }
    /**
     * 在以往的BaseAdapter中会在getView()中去进行创建ViewHolder和对应的View进行
     * 赋值,而在此adapter中将这个过程分为了两步,由这两个方法完成
     * (可以看出Google开始强制开发者使用ViewHolder模式了)
     */

    /**
     * 创建ViewHolder
     * @param viewGroup
     * @param i
     * @return
     */
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {

        View view=mInflater.inflate(R.layout.item_single_textview,viewGroup,false);
        MyViewHolder viewHolder=new MyViewHolder(view);
        return viewHolder;
    }

    /**
     * 绑定ViewHolder
     * @param holder
     * @param pos
     */
    @Override
    public void onBindViewHolder(final MyViewHolder holder, final int pos) {
        holder.tv.setText(mDatas.get(pos));
        setUpItemEvent(holder);


    }


    /**
     * android studio 快速提取方法 Ctrl + Alt + M
     * @param holder
     */
    protected void setUpItemEvent(final MyViewHolder holder) {
        //为每个Item设置点击事件,实现点击方法的回调
        if (mOnItemClickListener!=null){
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int layoutPosition = holder.getLayoutPosition();
                    mOnItemClickListener.onItemClick(holder.itemView,layoutPosition);
                }
            });

            //longclick
            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    int layoutPosition = holder.getLayoutPosition();
                    mOnItemClickListener.onItemLongClick(holder.itemView, layoutPosition);
                    /**return false; false后面长按过后会有onItemClick效果出现,所以这里设置true
                    可以解决这个bug**/
                    return true;
                }
            });
        }
    }

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


    public void addData(int pos){
        mDatas.add(pos,"Insert One");

//        notifyDataSetChanged();不是调用这个这里要注意
//        notifyItemChanged(pos);这里有很多方法,比如这个就是改变值得更新方法
        /**
         * notifyItemInserted(pos)不会刷新View,所以会存在添加过后的pos都是一样的问题
         *
         * 为了得到正确的pos,我们调用holder.getLayoutPosition();来获取Item
         * 在布局中的pos就可以得到正确的pos了
         *
         * 在点击事件中调用了该方法
         */
          notifyItemInserted(pos);
    }

    public void deleteData(int pos){
        mDatas.remove(pos);
        notifyItemRemoved(pos);
    }


    class MyViewHolder extends RecyclerView.ViewHolder {
        //将item中的控件在这里面进行初始化
        TextView tv;
        public MyViewHolder(View itemView) {
            super(itemView);

            tv= (TextView) itemView.findViewById(R.id.id_tv);
        }
    }

}


接下来是瀑布流布局的实现

StaggeredActivity.java

package cn.bigniu.recyclerviewdemo;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

public class StaggeredActivity extends AppCompatActivity {

    private RecyclerView mRecyclerView;
    private List<String> mDatas;
    private StaggeredAdapter mAdapter;

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

        //初始化datas
        initDatas();

        //初始化View
        initViews();

        mAdapter = new StaggeredAdapter(this, mDatas);
        mRecyclerView.setAdapter(mAdapter);

        //瀑布流的布局显示
        mRecyclerView.setLayoutManager(
                new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL));


        mAdapter.setmOnItemClickListener(new SimpleAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {

            }

            @Override
            public void onItemLongClick(View view, int position) {
                mAdapter.deleteData(position);
            }
        });

        /*mRecyclerView.addItemDecoration(
                new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST));*/
    }

    private void initViews() {

        mRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerView);
    }

    private void initDatas() {
        mDatas = new ArrayList<String>();

        for (int i = 'A'; i <= 'z'; i++) {
            mDatas.add("" + (char) i);
        }
    }


    @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();

        return super.onOptionsItemSelected(item);
    }
}




瀑布流的Adapter

StaggeredAdapter.java

package cn.bigniu.recyclerviewdemo;

import android.content.Context;
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.ArrayList;
import java.util.List;

/**
 * 为了减少重新写一次接口,我们直接继承SimpleAdapter
 */
public class StaggeredAdapter extends SimpleAdapter {

    //用于加载item布局
    /*private LayoutInflater mInflater;
    private Context mContext;
    private List<String> mDatas;*/

    //设置一个随机变量来改变瀑布流布局的高度
    private List<Integer> mHeights;

    public StaggeredAdapter(Context context, List<String> datas) {
        super(context,datas);
        /*this.mContext = context;
        this.mDatas = datas;
        mInflater = LayoutInflater.from(context);*/

        mHeights = new ArrayList<Integer>();
        for (int i = 0; i < mDatas.size(); i++) {
            mHeights.add((int) (100 + Math.random() * 300));
        }
    }

    /*@Override
    public StaggeredAdapter.MyViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {

        View view = mInflater.inflate(R.layout.item_single_textview, viewGroup, false);
        MyViewHolder viewHolder = new MyViewHolder(view);
        return viewHolder;
    }*/

    @Override
    public void onBindViewHolder(MyViewHolder holder, int pos) {
        //itemView就是StaggeredAdapter.MyViewHolder中的view
        //设置item的高度
        ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
        lp.height=mHeights.get(pos);
        holder.itemView.setLayoutParams(lp);
        holder.tv.setText(mDatas.get(pos));

        setUpItemEvent(holder);
    }

    /*@Override
    public int getItemCount() {
        return mDatas.size();
    }*/

    /*class MyViewHolder extends RecyclerView.ViewHolder {
        //将item中的控件在这里面进行初始化
        TextView tv;

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

            tv = (TextView) itemView.findViewById(R.id.id_tv);
        }
    }*/

}



主布局界面

activity_main.xml

<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/id_recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </android.support.v7.widget.RecyclerView>
</RelativeLayout>




Item子布局

为了方便和减少布局中出现其他的布局不美观等问题,我们在子布局中设置layout_margin属性来进行分隔

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_margin="3dp"
    android:background="@drawable/item_bg"
    android:layout_height="72dp">
    <TextView
        android:id="@+id/id_tv"
        android:layout_width="72dp"
        android:layout_height="match_parent"
        android:gravity="center"/>


</FrameLayout>




Menu布局

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">

    <!-- ifRoom表示如果Actionbar上有空间,就显示这个menu;
    withText表示显示的时候如果空间足够,会显示menu的title。 -->

    <item android:id="@+id/action_add"
        android:title="Add"
        android:orderInCategory="100"
        android:icon="@mipmap/ic_menu_add"
        app:showAsAction="ifRoom" />
    <item android:id="@+id/action_delete"
        android:title="Delete"
        android:orderInCategory="100"
        android:icon="@mipmap/ic_menu_delete"
        app:showAsAction="ifRoom" />



    <item android:id="@+id/action_listview"
        android:title="ListView"
        android:orderInCategory="100"
        app:showAsAction="never" />
    <item android:id="@+id/action_gridview"
        android:title="GridView"
        android:orderInCategory="100"
        app:showAsAction="never" />
    <item android:id="@+id/action_hor_gridview"
        android:title="HorizontalGridView"
        android:orderInCategory="100"
        app:showAsAction="never" />
    <item android:id="@+id/action_staggered"
        android:title="StaggeredGridView"
        android:orderInCategory="100"
        app:showAsAction="never" />
    <item android:id="@+id/action_settings"
        android:title="@string/action_settings"
        android:orderInCategory="100"
        app:showAsAction="never" />

</menu>




其他相关文件

style.xml

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->

       <!-- <item name="android:listDivider">@drawable/divider_02</item>-->
    </style>

</resources>

divider_02.xml(自定义分隔线)

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <size android:height="4dp"></size>

    <!-- 设置渐变的效果 -->
    <!-- linear 线性   -->
    <!-- 不同的模拟器会加载不同的values,所以要在自己模拟器版本加载的values下添加这个
      属性,不然不会有读取的效果-->
    <gradient android:startColor="#ffff0000"
        android:centerColor="#ff00ff00"
        android:endColor="#ff0000ff"
        android:type="linear"/>
</shape>




selector

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_pressed="true" android:drawable="@color/state_pressed"></item>
     <item android:drawable="@color/state_normal"></item>
</selector>

colors

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="state_pressed">#ffff0000</color>
    <color name="state_normal">#44ff00ff</color>
</resources>




DividerItemDecoration.java下载地址



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值