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? = 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 {
val photos: MutableList = ArrayList()
//读取手机图片
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() {
private var photos: List? = 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(R.id.image)
textView = itemView.findViewById(R.id.text)
}
}
fun dataChanged(photos: List?) {
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?
)
Android load all photos into RecyclerView,support pinch to zoom by ScaleGestureDetector,Java(3)_zhangphil的博客-CSDN博客Android RecyclerView的StaggeredGridLayoutManager实现交错排列的子元素分组先看实现的结果如图:设计背景:现在的产品对设计的需求越来越多样化,如附录文章2是典型的联系人分组RecyclerView,子元素排列到一个相同的组,但是有些时候,UI要求把这些元素不是垂直方向的,而是像本文开头的图中所示样式排列,这就需要用StaggeredGridLayoutMa。在处理大图的浏览查看动作过程中,往往还有其他额外的事情需要处理,典型的以微信。https://blog.csdn.net/zhangphil/article/details/130708679