Android load all photos into RecyclerView,pinch to zoom by ScaleGestureDetector,kotlin(4)

Android load all photos into RecyclerView,pinch to zoom by ScaleGestureDetector,kotlin(4)

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />

import android.content.ContentValues
import android.content.Context
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import android.view.ScaleGestureDetector
import android.view.ScaleGestureDetector.SimpleOnScaleGestureListener
import android.view.View.OnTouchListener
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
import java.text.SimpleDateFormat
import java.util.Date


class MainActivity : AppCompatActivity() {
    private var mPhotos: List<Photo>? = null
    private var mRecyclerView: RecyclerView? = null
    private var mPhotoAdapter: PhotoAdapter? = null
    private var mLayoutManager: GridLayoutManager? = null
    private var mScaleGestureDetector: ScaleGestureDetector? = null
    private val TAG = "fly"
    private val ZOOM = intArrayOf(3, 5, 9)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.recycler_view)
        mRecyclerView = findViewById(R.id.recycler_view)
        mLayoutManager = GridLayoutManager(this, ZOOM[2])
        mLayoutManager?.orientation = GridLayoutManager.VERTICAL
        mRecyclerView?.setLayoutManager(mLayoutManager)
        mScaleGestureDetector = ScaleGestureDetector(this, object : SimpleOnScaleGestureListener() {
            override fun onScaleBegin(detector: ScaleGestureDetector): Boolean {
                Log.d(TAG, "--onScaleBegin--")
                return super.onScaleBegin(detector)
            }

            override fun onScale(detector: ScaleGestureDetector): Boolean {
                Log.d(TAG, "--onScale--")
                return super.onScale(detector)
            }

            override fun onScaleEnd(detector: ScaleGestureDetector) {
                super.onScaleEnd(detector)
                Log.d(TAG, "--onScaleEnd--")
                Log.d(TAG, "TimeDelta-" + detector.timeDelta)
                Log.d(TAG, "ScaleFactor-" + detector.scaleFactor)
                Log.d(TAG, "currentSpan-" + detector.currentSpan)
                scale(detector)
            }

            private fun scale(detector: ScaleGestureDetector): Boolean {
                if (detector.currentSpan > 50 && detector.timeDelta > 10) {
                    val scaleFactor = detector.scaleFactor
                    val curSpanCount = mLayoutManager!!.spanCount
                    Log.d(TAG, "LayoutManager SpanCount()-\$curSpanCount")
                    val curIndex = getSpanCountIndex(curSpanCount)
                    if (scaleFactor < 1) {
                        if (curSpanCount == ZOOM[ZOOM.size - 1]) {
                            return true
                        } else {
                            mLayoutManager!!.spanCount = ZOOM[curIndex + 1]
                        }
                    } else {
                        if (curSpanCount == ZOOM[0]) {
                            return true
                        } else {
                            mLayoutManager!!.spanCount = ZOOM[curIndex - 1]
                        }
                    }
                    mRecyclerView?.setLayoutManager(mLayoutManager)
                    mPhotoAdapter?.dataChanged(mPhotos)

                    return true
                }
                return false
            }
        })

        mRecyclerView?.setOnTouchListener(OnTouchListener { v, event ->
            mScaleGestureDetector!!.onTouchEvent(event)
            false
        })

        mPhotoAdapter = PhotoAdapter(applicationContext)
        mRecyclerView?.setAdapter(mPhotoAdapter)

        CoroutineScope(Dispatchers.IO).launch {
            mPhotos = readAllImage(applicationContext)
            launch(Dispatchers.Main) {
                mPhotoAdapter?.dataChanged(mPhotos)
            }
        }
    }

    private fun getSpanCountIndex(spanCount: Int): Int {
        var index = 0
        for (i in ZOOM.indices) {
            if (spanCount == ZOOM[i]) {
                index = i
            }
        }
        return index
    }

    companion object {
        private fun readAllImage(context: Context): List<Photo> {
            val photos: MutableList<Photo> = ArrayList<Photo>()

            //读取手机图片
            val cursor = context.contentResolver.query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                null,
                null,
                null,
                null
            )
            while (cursor!!.moveToNext()) {
                //图片的路径
                val path =
                    cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA))

                //图片名称
                val name =
                    cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME))

                //图片最后修改日期
                val file = File(path)
                val sdf = SimpleDateFormat("yyyy-MM-dd hh:mm:ss")
                val date = sdf.format(Date(file.lastModified()))

                //图片大小
                val size =
                    cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE))
                val photo = Photo(name, date, size, path, getImageUri(context, path))
                photos.add(photo)
            }
            cursor.close()
            return photos
        }

        private fun getImageUri(context: Context, filePath: String): Uri? {
            val cursor = context.contentResolver.query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                arrayOf(MediaStore.Images.Media._ID),
                MediaStore.Images.Media.DATA + "=? ",
                arrayOf(filePath),
                null
            )
            return if (cursor != null && cursor.moveToFirst()) {
                val id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID))
                val baseUri = Uri.parse("content://media/external/images/media")
                Uri.withAppendedPath(baseUri, "" + id)
            } else {
                val values = ContentValues()
                values.put(MediaStore.Images.Media.DATA, filePath)
                context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
            }
        }
    }
}

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.github.piasy.biv.BigImageViewer
import com.github.piasy.biv.loader.glide.GlideImageLoader
import com.github.piasy.biv.view.BigImageView


class PhotoAdapter(context: Context?) :
    RecyclerView.Adapter<PhotoAdapter.PhotoViewHolder>() {
    private var photos: List<Photo>? = null

    init {
        BigImageViewer.initialize(GlideImageLoader.with(context))
    }

    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): PhotoViewHolder {
        val view: View =
            LayoutInflater.from(parent.context).inflate(R.layout.photo, parent, false)
        return PhotoViewHolder(view)
    }

    override fun onBindViewHolder(holder: PhotoViewHolder, position: Int) {
        holder.textView.text = position.toString()
        holder.imageView.showImage(photos?.get(position)?.uri)
    }

    override fun getItemCount(): Int {
        return photos?.size ?: 0
    }

    inner class PhotoViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var imageView: BigImageView
        var textView: TextView

        init {
            imageView = itemView.findViewById<BigImageView>(R.id.image)
            textView = itemView.findViewById<TextView>(R.id.text)
        }
    }

    fun dataChanged(photos: List<Photo>?) {
        this.photos = photos

        notifyDataSetChanged()
    }
}

import android.net.Uri


class Photo(
    //名称
    var name: String, //日期
    var date: String, //大小
    var size: Long,//路径
    var path: String,
    var uri: Uri?
)

<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<?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"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="1dp"
    android:layout_marginTop="1dp"
    android:layout_marginRight="1dp">

    <com.github.piasy.biv.view.BigImageView
        android:id="@+id/image"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        app:failureImage="@android:drawable/ic_dialog_alert"
        app:failureImageInitScaleType="center"
        app:optimizeDisplay="true" />

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/image"
        android:layout_centerHorizontal="true"
        android:maxLines="1"
        android:text="-.-"
        android:textColor="@android:color/black" />
</RelativeLayout>

Android load all photos into RecyclerView, support pinch to zoom by ScaleGestureDetector, Java(3)_zhangphil's blog-CSDN blog Android RecyclerView's StaggeredGridLayoutManager implements staggered sub-element grouping First look at the results of the implementation as shown in the figure: Design background: current product pairs Design requirements are becoming more and more diverse. For example, appendix article 2 is a typical contact grouping RecyclerView, and the sub-elements are arranged into the same group. However, sometimes, the UI requires that these elements are not vertically oriented, but like the one at the beginning of this article The style arrangement shown in the figure requires the use of StaggeredGridLayoutMa. In the process of browsing and viewing large images, there are often other additional things that need to be dealt with, typically WeChat. https://blog.csdn.net/zhangphil/article/details/130708679

Guess you like

Origin blog.csdn.net/zhangphil/article/details/131296499