kotlin,LoaderManager CursorLoader load all photo to GridLayoutManager RecyclerView
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
import android.database.Cursor
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.loader.app.LoaderManager
import androidx.loader.content.CursorLoader
import androidx.loader.content.Loader
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import java.text.SimpleDateFormat
import java.util.Date
import kotlin.system.measureTimeMillis
class MainActivity : AppCompatActivity() {
private val TAG = "fly"
private var loaderManager: LoaderManager? = null
private var photoAdapter: PhotoAdapter? = null
private val LOADER_ID = 2023
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.d(TAG, "${getFormatTime()} onCreate ${Thread.currentThread().id}")
val recyclerView: RecyclerView = findViewById(R.id.recyclerview)
val layoutManager = GridLayoutManager(this, 5)
recyclerView.setLayoutManager(layoutManager)
photoAdapter = PhotoAdapter(this)
recyclerView.setAdapter(photoAdapter)
setupLoader()
}
override fun onRestart() {
super.onRestart()
//loaderManager?.getLoader<CursorLoader>(LOADER_ID)?.forceLoad()
}
override fun onDestroy() {
super.onDestroy()
loaderManager?.destroyLoader(LOADER_ID)
}
fun getFormatTime(): String {
val sdf = SimpleDateFormat("MM-dd hh:mm:ss")
val date: String = sdf.format(Date(System.currentTimeMillis()))
return date
}
private fun getImages(cursor: Cursor?): List<Photo?>? {
Log.d(TAG, "总量:${cursor?.count}")
val photos: ArrayList<Photo> = ArrayList()
Log.d(TAG, "Cursor start ${Thread.currentThread().id}")
//读取手机图片
//Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, null);
while (cursor?.moveToNext() == true) {
//图片的路径
val path: String =
cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA))
//图片名称
val name: String =
cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME))
//图片最后修改日期
val date_modified =
cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATE_MODIFIED))
val date: String =
SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(Date(date_modified.toLong()))
//图片大小
val size: Long =
cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE))
val photo = Photo(name, date, size, path, 0)
photos.add(photo)
}
Log.d(TAG, "Cursor end ${Thread.currentThread().id}")
cursor?.close()
return photos
}
private fun setupLoader() {
loaderManager = LoaderManager.getInstance(this)
loaderManager?.initLoader(LOADER_ID, Bundle(), loaderCallbacks)
}
private val loaderCallbacks: LoaderManager.LoaderCallbacks<Cursor> =
object : LoaderManager.LoaderCallbacks<Cursor> {
override fun onCreateLoader(id: Int, args: Bundle?): Loader<Cursor> {
Log.d(TAG, "${getFormatTime()} onCreateLoader ${Thread.currentThread().id}")
val loader = CursorLoader(applicationContext)
loader.uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
return loader
}
override fun onLoaderReset(loader: Loader<Cursor?>) {
}
override fun onLoadFinished(loader: Loader<Cursor?>, cursor: Cursor?) {
Log.d(TAG, "onLoadFinished in ${Thread.currentThread().id}")
var lists: ArrayList<Photo>
val time = measureTimeMillis {
lists = getImages(cursor) as ArrayList<Photo>
}
Log.d(TAG, "Cursor遍历耗时:$time")
photoAdapter?.dataChanged(lists)
Log.d(TAG, "onLoadFinished out ${Thread.currentThread().id}")
}
}
}
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import java.io.File
class PhotoAdapter(private val context: Context) :
RecyclerView.Adapter<PhotoHolder>() {
private var items: ArrayList<Photo> = ArrayList()
fun dataChanged(photos: ArrayList<Photo>) {
this.items = photos
notifyDataSetChanged()
}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): PhotoHolder {
val view: View =
LayoutInflater.from(parent.context).inflate(R.layout.item, parent, false)
return PhotoHolder(view)
}
override fun onBindViewHolder(holder: PhotoHolder, pos: Int) {
Glide.with(context).load(File(items[pos].path)).into(holder.image)
holder.text.setText(items[pos].date)
holder.pos.setText(pos.toString())
}
override fun getItemCount(): Int {
return items.size
}
}
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class PhotoHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var image: ImageView
var text: TextView
var pos: TextView
init {
image = itemView.findViewById(R.id.image)
text = itemView.findViewById(R.id.text)
pos = itemView.findViewById(R.id.pos)
}
}
class Photo(
//名称
var name: String,
//日期
var date: String,
//大小
var size: Long,
//路径
var path: String,
var time: Long
)
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"/>
<?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"
android:padding="10dp">
<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/pos"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>