如何在 Kotlin 中将 listView 转换为 RecyclerView

Posted

技术标签:

【中文标题】如何在 Kotlin 中将 listView 转换为 RecyclerView【英文标题】:How to Convert listView to RecyclerView in Kotlin 【发布时间】:2020-04-26 18:57:40 【问题描述】:

我在使用 listView 时遇到问题,因为我在 listview 中显示了很多图像(关于内存)

我需要将 listview 转换为 recyclerview

问题:

当我在手机上显示图像时,使用最后一个视图,你做了很多内存阻塞, 它导致应用程序停止,所以我想将 List View 转换为 RecycleView。

主活动:

    package com.masreta87.hussain

import android.app.Activity
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.drawable.BitmapDrawable
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Environment
import android.view.View
import android.widget.AdapterView
import android.widget.ImageView
import android.widget.ListView
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.view.get
import java.io.File
import java.io.FileOutputStream
import java.io.OutputStream
import java.lang.Exception
import java.util.jar.Manifest
import androidx.core.content.ContextCompat.getSystemService
import android.icu.lang.UCharacter.GraphemeClusterBreak.T
import androidx.core.app.ComponentActivity.ExtraData
import androidx.core.content.ContextCompat.getSystemService
import android.icu.lang.UCharacter.GraphemeClusterBreak.T
import android.util.Log
import kotlinx.android.synthetic.*


class MainActivity : AppCompatActivity() 
    lateinit var Img:ListView
    lateinit var ImgArr:ArrayList<DataImg>

    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

         Img=findViewById(R.id.listviewB)
         ImgArr=ArrayList()

        ImgArr.add(DataImg(R.drawable.h))
        ImgArr.add(DataImg(R.drawable.hh))
        ImgArr.add(DataImg(R.drawable.hhh))
        ImgArr.add(DataImg(R.drawable.v2))
        ImgArr.add(DataImg(R.drawable.v3))
        ImgArr.add(DataImg(R.drawable.v4))
        ImgArr.add(DataImg(R.drawable.v5))
        ImgArr.add(DataImg(R.drawable.v6))
        //ImgArr.add(DataImg(R.drawable.v7))
        ImgArr.add(DataImg(R.drawable.v8))
        ImgArr.add(DataImg(R.drawable.v9))

        Img.adapter=customAdapter(applicationContext,ImgArr)
        Img.setOnItemClickListenerparent:AdapterView<*>, view:View, position:Int, id:Long ->
         var ImgNa=ImgArr.get(position).image.toString()

            Log.d("this",ImgNa)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
                if (ContextCompat.checkSelfPermission(this,android.Manifest.permission.WRITE_EXTERNAL_STORAGE )
                    !=PackageManager.PERMISSION_GRANTED)

                    ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                        ,100)

                else
                    saveImageToStorage(ImgNa)
                
            else
                saveImageToStorage(ImgNa)
            

        


    

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) 
        if (requestCode==100)
            if (grantResults.isNotEmpty() && grantResults[0]==PackageManager.PERMISSION_GRANTED)

               // saveImageToStorage(ImgNa)
            else
                Toast.makeText(this,"No Permission for save",Toast.LENGTH_SHORT).show()

            
        
    
    public fun saveImageToStorage(ImgNa:String)

        val externalStorageState=Environment.getExternalStorageState()
        if (externalStorageState.equals(Environment.MEDIA_MOUNTED))
            val storeDirectory=Environment.getExternalStorageDirectory().toString()
            val rnds = (1000..100000000000).random().toString()
            val file=File(storeDirectory,"$rnds.png")//Namephoto
            try 

                Log.d("output",ImgNa)
                val stream:OutputStream =FileOutputStream(file)
                var drawable=ContextCompat.getDrawable(applicationContext,ImgNa.toInt()) //edit
                var bitmap=(drawable as BitmapDrawable).bitmap
                bitmap.compress(Bitmap.CompressFormat.PNG,100,stream)
                stream.flush()
                stream.close()
                Toast.makeText(this,"Image Saved",Toast.LENGTH_LONG).show()
            catch (e:Exception)
                e.printStackTrace()
            

        else
            Toast.makeText(this,"unable to access the storage",Toast.LENGTH_SHORT).show()
        
    

还有customAdapter

package com.masreta87.hussain

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.ImageView

class customAdapter(var context: Context,var data:ArrayList<DataImg>) :BaseAdapter()
private class ViewHolder(row:View?)
     var ivImage:ImageView
    init 
        this.ivImage=row?.findViewById(R.id.imageViewN) as ImageView


    

    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View 
        var view:View?
        var viewHolder:ViewHolder
        if(convertView==null)
            var layout=LayoutInflater.from(context)
            view=layout.inflate(R.layout.listview_item,parent,false)
            viewHolder=ViewHolder(view)
            view.tag=viewHolder

        else
            view=convertView
            viewHolder=view.tag as ViewHolder
        
        var data:DataImg=getItem(position) as DataImg

        viewHolder.ivImage.setImageResource(data.image)
        return view as View
    

    override fun getItem(position: Int): Any 
        return data.get(position)
    

    override fun getItemId(position: Int): Long 
        return position.toLong()
    

    override fun getCount(): Int 
        return data.count()
    


和DataImg:

package com.masreta87.hussain

class DataImg(var image:Int) 


activity_Main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    android:layout_
    android:layout_
    tools:context=".MainActivity">


    <ListView
        android:id="@+id/listviewB"
        android:layout_
        android:layout_
        />
</RelativeLayout>

listview_item.xml

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

    <ImageView
        android:id="@+id/imageViewN"
        android:background="@drawable/image_border"
        android:layout_
        android:scaleType="fitXY"
        android:layout_

        />
</LinearLayout>

【问题讨论】:

您只需要创建recyclerview 适配器而不是listview 适配器,并使用与本示例相同的视图并在活动中进行设置 替代方法....我建议您使用滑翔图像库,它将您的可绘制对象缓存在内存中。你不会得到任何内存错误 【参考方案1】:

第一次改变你的activity_Main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    android:layout_
    android:layout_
    tools:context=".MainActivity">


    <RecyclerView
        android:id="@+id/recycler_view"
        android:layout_
        android:layout_
        />
</RelativeLayout>

然后你必须像这样为 RecyclerView 创建一个适配器:

class CustomAdapter(private val activity: Context?, private val arrData: List<DataImg>) : RecyclerView.Adapter<CustomAdapter.ViewHolder>() 
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder 
        var itemView: View? = null
        itemView = LayoutInflater.from(activity)
                .inflate(R.layout.listview_item, parent, false)
        return ViewHolder(itemView)
    

    override fun onBindViewHolder(holder: ViewHolder, i: Int) 
        val model = arrData[i]
    


    override fun getItemCount(): Int 
        return arrData.size
    

    class ViewHolder(view: View?) : RecyclerView.ViewHolder(view!!) 

    


现在在您的主要活动中,您必须为您的 RecyclerView 设置布局管理器,并且必须将 Adapter 与它绑定

recyclerViewSearchList = findViewById(R.id.recycler_view)
recyclerView.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
recyclerViewSearchList.adapter = CustomAdapter(MainActivity.this, ImgArr)

【讨论】:

recyclerView.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) recyclerViewSearchList.adapter = CustomAdapter(MainActivity.this, ImgArr) 错误 确保您使用小 C 编写 CustomAdapter 而不是 customAdapter 你有没有使用 recyclerViewSearchList = findViewById(R.id.recycler_view) 初始化recyclerview recyclerView.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) //这里报错什么recyclerView元素??

以上是关于如何在 Kotlin 中将 listView 转换为 RecyclerView的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Kotlin 中将 String 转换为 Int?

如何在 Kotlin 中将 Firestore 日期/时间戳转换为日期?

如何在 Kotlin 中将数据类转换为 ByteBuffer?

如何在 Kotlin 中将 ArrayList 转换为 JSONArray()

如何在 Kotlin 中将 View 转换为 Imageview [重复]

如何在 Kotlin 中将字符串数组 JSON 转换为 ArrayList?