美文网首页
RecyclerView滚动事件、多布局复用的使用

RecyclerView滚动事件、多布局复用的使用

作者: RoboyCore | 来源:发表于2016-12-21 15:00 被阅读168次

    RecyclerView的好处

    ‘1.可以当ListView、GridView等布局使用、并且可以滚动设置方向、使用灵活
    2.可以添加自定义动画、多布局使用ViewHolder拓展性好

    注意事项’

    1.支持listview、gridview、瀑布流(布局管理器不添加会导致数据不显示)
    2.使用需要自定义滚动、点击、长按、下拉刷新、上拉加载事件的监听
    3.滚动事件一定要用设置空闲状态刷新

    newState == RecyclerView.SCROLL_STATE_IDLE
    ####并且一定是布局管理器对才能得到滚动当前可见第一个和最后一个Item
    

    4.内部传递监听事件,可以定义接口,从Adapter传递出更多数据到Activity或者Fragment中
    5.Adapter使用需要设置泛型<RecyclerView.ViewHolder> 并且内部ViewHolder要继承RecyclerView.ViewHolder,加载布局根据getItemType返回的值传递相应ViewHolder对象
    6.设置数据源时要要判断ViewHolder的类型来决定加载什么数据

    !!!如果使用要设置布局管理器对象,确定要使用哪种类型,不然不能看到数据

    private void init() {
        mRecyclerView = (RecyclerView)findViewById(R.id.recycler_view);
        mList = new ArrayList<>();
        mAdapter = new RecyclerAdapter(this,mList);
    
        LinearLayoutManager lm = new LinearLayoutManager(this);
        lm.setOrientation(LinearLayoutManager.VERTICAL);//线性
    
        GridLayoutManager gm = new GridLayoutManager(this, 3, LinearLayoutManager.VERTICAL, false);//网格
    
        StaggeredGridLayoutManager sgm = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);//瀑布流
    //        mRecyclerView.setLayoutManager(lm);
    //        mRecyclerView.setLayoutManager(gm);
            mRecyclerView.setLayoutManager(sgm);
        mRecyclerView.setAdapter(mAdapter);
    }
    

    =======================================================

    Adapter

    package mobi.xiaowu.recyclerview.adapter;
    
    import android.content.Context;
    import android.graphics.Color;
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ImageView;
    import android.widget.TextView;
    
    import java.util.List;
    import java.util.Random;
    
    import mobi.xiaowu.recyclerview.R;
    import mobi.xiaowu.recyclerview.model.Focus;
    import mobi.xiaowu.recyclerview.utils.ImgAsync;
    
    /**
     * Created by xiaowu on 2016/12/21.
     */
    
    public class Ex01Adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements     View.OnLongClickListener, View.OnClickListener {
    private List<Focus.Item> mItems;
    private Context mContext;
    private LayoutInflater mInflater;
    
    private OnItemClickListener mListener;
    private OnItemLongClickListener mLongListener;
    private RecyclerView mRecyclerView;
    
    private static final int POSITION_SINGLE = 1;//设置单双行标记
    private static final int POSITION_MULTIPLE = 2;
    
    private Random rm;
    
    public Ex01Adapter(Context context, List<Focus.Item> items) {
        mContext = context;
        mItems = items;
        mInflater = LayoutInflater.from(mContext);
        rm = new Random();
    }
    //初始化监听事件
    public void setOnClickListener(OnItemClickListener listener) {
        mListener = listener;
    }
    public void setOnLongClickListener(OnItemLongClickListener listener) {
        mLongListener = listener;
    }
    
    /**
     * 根据类型创建不同的布局
     * @param parent
     * @param viewType
     * @return
     */
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = null;
        RecyclerView.ViewHolder holder = null;
        switch (viewType) {
            case POSITION_SINGLE:
                 view =  mInflater.inflate(R.layout.item_ex01, parent, false);
                holder = new ViewHolder(view);
                break;
            case POSITION_MULTIPLE:
                view =  mInflater.inflate(R.layout.item_ex02, parent, false);
                holder = new ViewHolder2(view);
                break;
        }
        if (view != null) {
            view.setOnClickListener(this);
            view.setOnLongClickListener(this);
        }
        return holder;
    }
    
    /**
     * 根据返回的ViewHolder类型加载不同数据
     * @param holder
     * @param position
     */
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof ViewHolder) {
            ViewHolder vh = (ViewHolder) holder;
            if (position >0) {
                vh.mTextView.setText(mItems.get(position).getTitle());
            }
            else {
                vh.mTextView.setText("");
            }
            vh.mImageView.setImageResource(R.mipmap.ic_launcher);
            vh.mImageView.setTag(mItems.get(position).getCoverPath());
            new ImgAsync(vh.mImageView).execute(mItems.get(position).getCoverPath());
        }else if (holder instanceof ViewHolder2){
            ViewHolder2 vh = (ViewHolder2) holder;
            if (position >0) {
                vh.mTextView.setText(mItems.get(position).getTitle());
            }
            else {
                vh.mTextView.setText("");
            }
            vh.mTextView.setTextColor(Color.rgb(rm.nextInt(256),rm.nextInt(256),rm.nextInt(256)));//第二种布局使用的颜色随机
            vh.mImageView.setImageResource(R.mipmap.ic_launcher);
            vh.mImageView.setTag(mItems.get(position).getCoverPath());
            new ImgAsync(vh.mImageView).execute(mItems.get(position).getCoverPath());
        }
    }
    
    @Override
    public int getItemCount() {
        return mItems.size();
    }
    
    /**
     * 返回布局的类型标识
     * @param position
     * @return
     */
    @Override
    public int getItemViewType(int position) {
        return position%2==0 ?POSITION_SINGLE:POSITION_MULTIPLE;
    }
    
    //挂载RecyclerView
    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        mRecyclerView = recyclerView;
    
    }
    
    @Override
    public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
        super.onDetachedFromRecyclerView(recyclerView);
        mRecyclerView = null;
    }
    
    @Override
    public boolean onLongClick(View v) {
        int position = mRecyclerView.getChildAdapterPosition(v);
        mLongListener.MyItemLongClick(mRecyclerView,v,position,mItems.get(position));
        return true;
    }
    
    @Override
    public void onClick(View v) {
        int position = mRecyclerView.getChildAdapterPosition(v);
        mListener.MyItemClick(mRecyclerView,v,position,mItems.get(position));
    }
    
    
    //接口
    public interface OnItemClickListener{
        void MyItemClick(RecyclerView recyclerView, View v, int position, Focus.Item data);
    }
    
    public interface OnItemLongClickListener {
        void MyItemLongClick(RecyclerView recyclerView, View v, int position, Focus.Item data);
    }
    
    
    
    public static class ViewHolder extends RecyclerView.ViewHolder{
        private TextView mTextView;
        private ImageView mImageView;
    
        public ViewHolder(View itemView) {
            super(itemView);
            mTextView = (TextView)itemView.findViewById(R.id.item_tv);
            mImageView = (ImageView)itemView.findViewById(R.id.item_iv);
        }
    }
    public static class ViewHolder2 extends RecyclerView.ViewHolder{
        private TextView mTextView;
        private ImageView mImageView;
    
        public ViewHolder2(View itemView) {
            super(itemView);
            mTextView = (TextView)itemView.findViewById(R.id.item_tv);
            mImageView = (ImageView)itemView.findViewById(R.id.item_iv);
        }
    }
    

    }

    Activity

    package mobi.xiaowu.recyclerview;
    
    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.RecyclerView.OnScrollListener;
    import android.support.v7.widget.StaggeredGridLayoutManager;
    import android.view.View;
    import android.widget.RadioGroup;
    import android.widget.Toast;
    
    import com.google.gson.Gson;
    
    import java.io.UnsupportedEncodingException;
    import java.util.ArrayList;
    import java.util.List;
    
    import mobi.xiaowu.recyclerview.adapter.Ex01Adapter;
    import mobi.xiaowu.recyclerview.model.Focus;
     import mobi.xiaowu.recyclerview.utils.JsonAsyncTask;
    
    public class Ex01Activity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener, Ex01Adapter.OnItemClickListener, Ex01Adapter.OnItemLongClickListener {
    private RecyclerView mRecyclerView;
    private List<Focus.Item> mList;
    private Ex01Adapter mAdapter;
    private RadioGroup mRadioGroup;
    private RecyclerView.OnScrollListener mOnScrollListener;//滚动事件
    private LinearLayoutManager mLm;
    private StaggeredGridLayoutManager mSgm;
    private GridLayoutManager mGm;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ex01);
        init();
        loadData();//数据下载
    }
    
    private void loadData() {
        new JsonAsyncTask(new JsonAsyncTask.Callback() {
            @Override
            public void sendData(byte[] json) {
                try {
                    Focus focus = new Gson().fromJson(new String(json, "utf-8"), Focus.class);
                    mList.addAll(focus.getList());
                    mAdapter.notifyDataSetChanged();
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
        },this).execute(Ex01Url.URL);
    }
    
    private void init() {
        mList = new ArrayList<>();
        mAdapter = new Ex01Adapter(this,mList);
        mRecyclerView = (RecyclerView)findViewById(R.id.recycler_view);
        mRadioGroup = (RadioGroup)findViewById(R.id.rg);
        mRadioGroup.setOnCheckedChangeListener(this);
    
        //初始化布局管理器
        mLm = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        mGm = new GridLayoutManager(this, 2, LinearLayoutManager.VERTICAL, false);
        mGm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                return position==0? 2:1;
            }
        });
        mSgm = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
    
    
        mRecyclerView.setLayoutManager(mLm);
        mRecyclerView.setAdapter(mAdapter);
        mAdapter.setOnClickListener(this);//adapter传过来的点击事件
        mAdapter.setOnLongClickListener(this);//adapter传过来的长按事件
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());//设置默认动画
    
        //!!!滚动事件是内部类,java不支持多继承,所以要自己创建类对象再添加相应方法
        mOnScrollListener = new RecyclerView.OnScrollListener(){
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            }
    
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {//!!!必须监听状态停止不然会刷新多次
                    int position = mLm.findLastVisibleItemPosition();//!!!布局管理器才能得到Item的当前位置关系,RecyclerView没有监听Item变化的
                    if (position == mList.size() - 1) {
                        Toast.makeText(Ex01Activity.this, "刷新成功", Toast.LENGTH_SHORT).show();
                        loadData();
                    }
                }
            }
        };
    
        mRecyclerView.addOnScrollListener(mOnScrollListener);//初始化后再添加滚动方法
    }
    
    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {
        switch (checkedId) {
            case R.id.rb_01://线性布局管理
                mRecyclerView.setLayoutManager(mLm);//改变成线性布局
                break;
            case R.id.rb_02://网格布局管理
    
                mRecyclerView.setLayoutManager(mGm);//改变成网格布局
                break;
            case R.id.rb_03://稀疏布局管理(瀑布流)
                mRecyclerView.setLayoutManager(mSgm);//改变成稀疏布局
                break;
        }
    }
    
    
    @Override
    public void MyItemClick(RecyclerView recyclerView, View v, int position, Focus.Item data) {
        Toast.makeText(this, "当前"+position +data.getTitle(), Toast.LENGTH_SHORT).show();
    }
    
    @Override
    public void MyItemLongClick(RecyclerView recyclerView, View v, int position, Focus.Item data) {
        Toast.makeText(this, "当前长按"+position +data.getTitle(), Toast.LENGTH_SHORT).show();
        mList.remove(position);
        mAdapter.notifyItemChanged(position);
        if (position != mList.size()-1) {
            mAdapter.notifyItemRangeChanged(position,mList.size()-position);
        }
    
    }
    

    }

    项目上传至GitHub

    相关文章

      网友评论

          本文标题:RecyclerView滚动事件、多布局复用的使用

          本文链接:https://www.haomeiwen.com/subject/adyqvttx.html