RecyclerView

先加入依赖:

compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'

 在布局中:

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycleview_message"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </android.support.v7.widget.RecyclerView>

接着写一个Bean,即列表中的单位项:

public class MyMessage {
    private byte[] image_friend;
    private String name_friend;
    private String content;

    MyMessage(String name, String content, byte[] image){
        this.name_friend = name;
        this.content = content;
        this.image_friend = image;
    }

    public String getFriendName(){
        return name_friend;
    }

    public String getContent(){
        return content;
    }

    public byte[] getFriendImage(){
        return image_friend;
    }
}

接着编写其适配器:

public class RVAdapterMessage extends RecyclerView.Adapter<RVAdapterMessage.ViewHolder> {

    private List<MyMessage> myMessageList;

    static class ViewHolder extends RecyclerView.ViewHolder {
        View itemview_message;
        ImageView imageview_image;
        TextView textview_name;
        TextView textview_content;

        public ViewHolder(View view) {
            super(view);
            itemview_message = view;
            imageview_image = (ImageView)view.findViewById(R.id.message_friendimage);
            textview_name = (TextView)view.findViewById(R.id.message_friendname);
            textview_content = (TextView)view.findViewById(R.id.message_content);
        }
    }

    public RVAdapterMessage(List<MyMessage> myMessageList) {
        this.myMessageList = myMessageList;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_item, parent, false);
        final ViewHolder holder = new ViewHolder(view);
        holder.itemview_message.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int position = holder.getAdapterPosition();
                MyMessage temp_mymessage = myMessageList.get(position);
                Toast.makeText(v.getContext(), "you clicked view " + temp_mymessage.getFriendName(), Toast.LENGTH_SHORT).show();
            }
        });
        holder.itemview_message.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                int position = holder.getAdapterPosition();
                MyMessage temp_mymessage = myMessageList.get(position);
                Toast.makeText(v.getContext(), "you clicked view " + temp_mymessage.getFriendName(), Toast.LENGTH_SHORT).show();
                return true;
            }
        });
        return holder;
    }
    //这个方法主要用于适配渲染数据到View中  
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        MyMessage tempmessage = myMessageList.get(position);
        byte[] bitmapdata = tempmessage.getFriendImage();
        Bitmap bitmap = BitmapFactory.decodeByteArray(bitmapdata, 0, bitmapdata.length);
        holder.imageview_image.setImageBitmap(bitmap);
        holder.textview_name.setText(tempmessage.getFriendName());
        holder.textview_content.setText(tempmessage.getContent());
    }
    //BaseAdapter的getCount方法了,即总共有多少个条目  
    @Override public int getItemCount() { return myMessageList.size(); } 
    public void setNewData(List<MyMessage> myMessageList){
        this.myMessageList = myMessageList;
    }
}

最后,就可以在主界面的java中:

List<MyMessage> myMessageList = new ArrayList<MyMessage>();
//myMessageList.add(...)
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        // 设置布局管理器
        //瀑布流,设置为3列
        StaggeredGridLayoutManager layoutManager = new
                StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);

        /*// 设置布局管理器
        //垂直分布和横向分布  LinearLayoutManager.HORIZONTAL  VERTICAL
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);*/
        recyclerView.setLayoutManager(layoutManager);


        RVAdapterMessage adapter = new RVAdapterMessage(myMessageList);
        recyclerView.setAdapter(adapter);

下面是RecyclerView的其他用法: 

从底部开始加载数据:

linearLayoutManager.setStackFromEnd(true);

指定view的类型:

@Override
public int getItemViewType(int position) {
    return position;
}

 调到指定位置:

private void smoothMoveToPosition(RecyclerView mRecyclerView, final int position) {
        // 第一个可见位置
        int firstItem = mRecyclerView.getChildLayoutPosition(mRecyclerView.getChildAt(0));
        // 最后一个可见位置
        int lastItem = mRecyclerView.getChildLayoutPosition(mRecyclerView.getChildAt(mRecyclerView.getChildCount() - 1));

        if (position < firstItem) {
            // 如果跳转位置在第一个可见位置之前,就smoothScrollToPosition可以直接跳转
            mRecyclerView.smoothScrollToPosition(position);
        } else if (position <= lastItem) {
            // 跳转位置在第一个可见项之后,最后一个可见项之前
            // smoothScrollToPosition根本不会动,此时调用smoothScrollBy来滑动到指定位置
            int movePosition = position - firstItem;
            if (movePosition >= 0 && movePosition < mRecyclerView.getChildCount()) {
                int top = mRecyclerView.getChildAt(movePosition).getTop();
                mRecyclerView.smoothScrollBy(0, top);
            }
        } else {
            // 如果要跳转的位置在最后可见项之后,则先调用smoothScrollToPosition将要跳转的位置滚动到可见位置
            // 再通过onScrollStateChanged控制再次调用smoothMoveToPosition,执行上一个判断中的方法
            mRecyclerView.smoothScrollToPosition(position);
        }
    }

 通常是对List进行添加或者删除,即在原数据上进行更新,则列表的更新方法为:

adapter.notifyDataSetChanged();

如果是要直接对List进行赋值,例如:myMessageList =  myMessageList2;

adapter.setNewData(myFriendsList);
adapter.notifyDataSetChanged();

 获取列表中某个单项View,这种方法只适用于列表长度不超出屏幕的情况:

private void getState(int position){
RVAdapterMessage.ViewHolder viewHolder = (RVAdapterMessage.ViewHolder)mRecyclerView.getChildViewHolder(mRecyclerView.getChildAt(position)); }

 注意,Recycleview的getChildAt函数中的参数是以第一个可见的view为基准,比如列表总共有6个view,只有中间的4个显示在屏幕中,那么getChildAt(0)取得的是屏幕中显示的第一个,即6个中的第2个。

所以,要获得相应的view,可以先减去第一个可见的项的位置,或者像下面这样获取view:

View view = recyclerView.getLayoutManager().findViewByPosition(position);

另外,只能取到那些出现在屏幕中的view,比如上述例子中,如果想通过getChildAt(-1)或getChildAt(4)来取两边的view,是取不到的,会返回null。目前还没找到方法在列表中获取屏幕外的view。

 

检测Recycleview是否滑到了最下面:

recyclerView_square.setOnScrollListener(new RecyclerView.OnScrollListener() {

            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                LinearLayoutManager manager = (LinearLayoutManager) recyclerView.getLayoutManager();
                // 当不滚动时
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    //获取最后一个完全显示的ItemPosition
                    int lastVisibleItem = manager.findLastCompletelyVisibleItemPosition();
                    int totalItemCount = manager.getItemCount();

                    // 判断是否滚动到底部
                    if (lastVisibleItem == (totalItemCount - 1)) {
                        //加载更多功能的代码
                        Log.d(TAG, "onScrollStateChanged: 加载更多");
                    }
                }
            }
            
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                //dx用来判断横向滑动方向,dy用来判断纵向滑动方向  
            }
        });

 

做聊天列表时需要倒置排序:

layoutManager.setReverseLayout(true);

 

顶部/底部是否可以再滑动?

canScrollVertically(1)

1表示底部;-1表示顶部

canScrollVertically(1)返回true,表示该控件还没滑到最底部

posted on 2019-02-22 18:15  赵子隆  阅读(219)  评论(0编辑  收藏  举报

导航