ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

RecyclerView替代ListView

2021-03-04 12:59:54  阅读:174  来源: 互联网

标签:int RecyclerView import android ListView 替代 public view


文章目录

1. 背景

    我们都知道在android 5.0后引入了RecyclerView来替代ListView,由于其强大的功能和效果以及其规范化,已经逐渐完全替代了ListViewGridView,本文将简单探究RecyclerView替代ListView的具体使用,在下一篇中将探究RecyclerView替代GridView的具体使用。参考文章:hereAndroid进阶之光。

2.使用

2.1 基本使用

  • 依赖导入
  • 布局文件定义

2.1.1 依赖

对于Android 9.0API level 28)中提出了AndroidX,它是Jetpack的一部分。对于API level 27或者更早的版本中可以使用support library,对应于com.android.support.*。但是Google官方推荐使用在项目中使用AndroidX,并停止了对com.android.support.*的支持。AndroidX是对android.support.xxx包的整理后产物。由于之前的 support 包过于混乱,所以,Google 推出了AndroidX
故而在一些博客中常见的:

implementation 'com.android.support:appcompat-v7:22.2.0'
implementation 'com.android.support:appcompat-v7:26.1.0'

将之复制到相应的位置,可以看见如下:
在这里插入图片描述
它推荐使用Refactor->Migrate来迁移到AndridX libraries库。由于我们的项目默认创建的就是AndroidX的了,这里提示的错误只是因为导入的依赖不对,这里应该是:

implementation 'androidx.recyclerview:recyclerview:1.1.0'

2.1.2 基本案例

主布局文件:recycleview.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/myrecycleview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </androidx.recyclerview.widget.RecyclerView>
</LinearLayout>

ListView类似的,我们需要定义每一个item的样式布局:recycleview_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_item"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center" />
</LinearLayout>

同样,需要定义一个适配器方法,该适配器方法需要继承自RecyclerView.Adapter,在该类中需要复写:onCreateViewHolderonBindViewHoldergetItemCount方法。

package com.example.myapplication;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.List;

public class MyAdapter extends RecyclerView.Adapter{
    private List<String> mList;
    private Context context;
    public MyAdapter(Context context, List<String> mList){
        this.context = context;
        this.mList = mList;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(context).inflate(R.layout.recycleview_item, parent, false);
        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        ((MyViewHolder) holder).tv.setText(mList.get(position));
    }

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

    class MyViewHolder extends RecyclerView.ViewHolder{
        TextView tv;
        public MyViewHolder(View view){
            super(view);
            tv = (TextView) view.findViewById(R.id.tv_item);
        }
    }
}

    和之前写ListView中的ViewHolder中的区别在于,这里的适配器,需要强制实现onBindViewHolder,也就是必须要写一个ViewHolder类,继承自RecyclerView.ViewHolder,以保存已经实例化好的变量。使用onBindViewHolder方法来得到已经实例化过的对象,进而进行一些必要的赋值操作。
然后是我们的函数入口:

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;

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

public class MainActivity extends AppCompatActivity {
    private RecyclerView recyclerView;
    private MyAdapter adapter;
    private List<String> mList;

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

        recyclerView = findViewById(R.id.myrecycleview);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        linearLayoutManager.setOrientation(RecyclerView.VERTICAL);
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        mList = getList();
        adapter = new MyAdapter(this, mList);
        recyclerView.setAdapter(adapter);
    }

    private List<String> getList(){
        List<String> list = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            list.add(i+"");
        }
        return list;
    }
}

注意到与ListView不同的一点就是,需要设置布局管理器用于设置条目的排列样式,可以是垂直排列或者水平排列。其余的都是类似的处理。
可以看见效果:
在这里插入图片描述

2.1.3 案例添加分割线

谷歌目前没有提供默认的分割线,这就需要我们继承RecyclerView.ItemDecoration来自定义分割线。然后使用recyclerView.addItemDecoration()来加入分割线。

package com.example.myapplication;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

public class VerticalDividerItemDecoration extends RecyclerView.ItemDecoration {
    private Drawable divider;
    public VerticalDividerItemDecoration(Context context){
        final TypedArray a = context.obtainStyledAttributes(new int[]{android.R.attr.listDivider});
        divider = a.getDrawable(0);
        a.recycle();
    }

    @Override
    public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
        final int left = parent.getPaddingLeft();
        final int right = parent.getWidth() - parent.getPaddingRight();
        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            RecyclerView v = new RecyclerView(parent.getContext());
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)child.getLayoutParams();
            final int top = child.getBottom() + params.bottomMargin;
            final int bottom = top + divider.getIntrinsicHeight();
            divider.setBounds(left, top, right, bottom);
            divider.draw(c);
        }
    }
}

上面的代码是我从Android进阶之光中抄的。然后使用就是:

recyclerView.addItemDecoration(new VerticalDividerItemDecoration(MainActivity.this));

可以看见效果:
在这里插入图片描述

2.1.4 案例添加点击事件

列表中条目的点击事件需要我们自己来定义。这种方式需要结合接口来进行编程处理,比较灵活。有点类似javascript中定义的回调函数处理。我们对Item的点击事件,也就是放置在Adapter中进行处理,然后设置接口函数,添加添加点击回调,然后在MainActivity中进行实例化该接口对象即可。

package com.example.myapplication;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.List;

public class MyAdapter extends RecyclerView.Adapter{
    private List<String> mList;
    private Context context;
    public MyAdapter(Context context, List<String> mList){
        this.context = context;
        this.mList = mList;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(context).inflate(R.layout.recycleview_item, parent, false);
        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
        final MyViewHolder myViewHolder = ((MyViewHolder) holder);
        myViewHolder.tv.setText(mList.get(position));
        if(onItemClickListener!=null){
            // 点击
            myViewHolder.tv.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View view) {
                    onItemClickListener.onItemClick(myViewHolder.tv, position);
                }
            });
            // 长按
            myViewHolder.tv.setOnLongClickListener(new View.OnLongClickListener(){
                @Override
                public boolean onLongClick(View view) {
                    onItemClickListener.onItemLongClick(myViewHolder.tv, position);
                    return false;
                }
            });
        }
    }

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

    class MyViewHolder extends RecyclerView.ViewHolder{
        TextView tv;
        public MyViewHolder(View view){
            super(view);
            tv = (TextView) view.findViewById(R.id.tv_item);
        }
    }
    private OnItemClickListener onItemClickListener;
    public interface OnItemClickListener{
        void onItemClick(View veiw, int position);
        void onItemLongClick(View view, int position);
    }

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

MainActivity.java中:

adapter = new MyAdapter(this, mList);

adapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() {
     @Override
     public void onItemClick(View veiw, int position) {
         Toast.makeText(MainActivity.this, "点击了第"+(position+1)+"条", Toast.LENGTH_SHORT).show();
     }

     @Override
     public void onItemLongClick(View view, int position) {
         Toast.makeText(MainActivity.this, "长按了第"+(position+1)+"条", Toast.LENGTH_SHORT).show();
     }
 });

 recyclerView.setAdapter(adapter);

在这里插入图片描述

标签:int,RecyclerView,import,android,ListView,替代,public,view
来源: https://blog.csdn.net/qq_26460841/article/details/113860801

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有