change the media gridview to recyclerview

This commit is contained in:
tibbi 2016-11-19 19:20:50 +01:00
parent 4b243b5498
commit 0824c66784
7 changed files with 109 additions and 76 deletions

View File

@ -5,7 +5,6 @@ import android.app.WallpaperManager
import android.content.Intent import android.content.Intent
import android.database.Cursor import android.database.Cursor
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.Color
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.provider.MediaStore import android.provider.MediaStore
@ -20,16 +19,15 @@ import android.widget.AdapterView
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget import com.bumptech.glide.request.target.SimpleTarget
import com.simplemobiletools.filepicker.asynctasks.CopyMoveTask import com.simplemobiletools.filepicker.extensions.hasStoragePermission
import com.simplemobiletools.filepicker.extensions.* import com.simplemobiletools.filepicker.extensions.scanFiles
import com.simplemobiletools.fileproperties.dialogs.PropertiesDialog import com.simplemobiletools.filepicker.extensions.scanPath
import com.simplemobiletools.filepicker.extensions.toast
import com.simplemobiletools.gallery.Constants import com.simplemobiletools.gallery.Constants
import com.simplemobiletools.gallery.R import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.adapters.MediaAdapter import com.simplemobiletools.gallery.adapters.MediaAdapter
import com.simplemobiletools.gallery.dialogs.ChangeSortingDialog import com.simplemobiletools.gallery.dialogs.ChangeSortingDialog
import com.simplemobiletools.gallery.dialogs.CopyDialog
import com.simplemobiletools.gallery.extensions.getHumanizedFilename import com.simplemobiletools.gallery.extensions.getHumanizedFilename
import com.simplemobiletools.gallery.extensions.shareMedium
import com.simplemobiletools.gallery.models.Medium import com.simplemobiletools.gallery.models.Medium
import kotlinx.android.synthetic.main.activity_media.* import kotlinx.android.synthetic.main.activity_media.*
import java.io.File import java.io.File
@ -37,7 +35,7 @@ import java.io.IOException
import java.util.* import java.util.*
import java.util.regex.Pattern import java.util.regex.Pattern
class MediaActivity : SimpleActivity(), AdapterView.OnItemClickListener, View.OnTouchListener, SwipeRefreshLayout.OnRefreshListener { class MediaActivity : SimpleActivity(), AdapterView.OnItemClickListener, View.OnTouchListener, SwipeRefreshLayout.OnRefreshListener, MediaAdapter.MediaOperationsListener {
companion object { companion object {
private val TAG = MediaActivity::class.java.simpleName private val TAG = MediaActivity::class.java.simpleName
@ -75,7 +73,7 @@ class MediaActivity : SimpleActivity(), AdapterView.OnItemClickListener, View.On
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
deleteFiles() //deleteFiles()
} }
private fun tryloadGallery() { private fun tryloadGallery() {
@ -96,9 +94,11 @@ class MediaActivity : SimpleActivity(), AdapterView.OnItemClickListener, View.On
if (isDirEmpty()) if (isDirEmpty())
return return
val adapter = MediaAdapter(this, mMedia) val adapter = MediaAdapter(this, mMedia, this) {
}
media_grid.adapter = adapter media_grid.adapter = adapter
media_grid.onItemClickListener = this
media_grid.setOnTouchListener(this) media_grid.setOnTouchListener(this)
mIsSnackbarShown = false mIsSnackbarShown = false
@ -232,12 +232,12 @@ class MediaActivity : SimpleActivity(), AdapterView.OnItemClickListener, View.On
} }
private fun shareMedia() { private fun shareMedia() {
val selectedMedia = getSelectedMedia() /*val selectedMedia = getSelectedMedia()
if (selectedMedia.size <= 1) { if (selectedMedia.size <= 1) {
shareMedium(selectedMedia[0]) shareMedium(selectedMedia[0])
} else { } else {
shareMedia(selectedMedia) shareMedia(selectedMedia)
} }*/
} }
private fun shareMedia(media: List<Medium>) { private fun shareMedia(media: List<Medium>) {
@ -254,7 +254,7 @@ class MediaActivity : SimpleActivity(), AdapterView.OnItemClickListener, View.On
} }
} }
private fun getSelectedMedia(): List<Medium> { /*private fun getSelectedMedia(): List<Medium> {
val items = media_grid.checkedItemPositions val items = media_grid.checkedItemPositions
val cnt = items.size() val cnt = items.size()
val media = (0..cnt - 1) val media = (0..cnt - 1)
@ -347,30 +347,30 @@ class MediaActivity : SimpleActivity(), AdapterView.OnItemClickListener, View.On
mToBeDeleted.clear() mToBeDeleted.clear()
mMedia = getMedia() mMedia = getMedia()
updateGridView() updateGridView()
} }*/
private fun updateGridView() { private fun updateGridView() {
if (!isDirEmpty()) { if (!isDirEmpty()) {
(media_grid.adapter as MediaAdapter).updateItems(mMedia) //(media_grid.adapter as MediaAdapter).updateItems(mMedia)
} }
} }
private fun showProperties() { private fun showProperties() {
val selectedMedia = getSelectedMedia() /*val selectedMedia = getSelectedMedia()
if (selectedMedia.size == 1) { if (selectedMedia.size == 1) {
PropertiesDialog(this, selectedMedia[0].path, false) PropertiesDialog(this, selectedMedia[0].path, false)
} else { } else {
val paths = ArrayList<String>(selectedMedia.size) val paths = ArrayList<String>(selectedMedia.size)
selectedMedia.mapTo(paths) { it.path } selectedMedia.mapTo(paths) { it.path }
PropertiesDialog(this, paths, false) PropertiesDialog(this, paths, false)
} }*/
} }
private fun isSetWallpaperIntent() = intent.getBooleanExtra(Constants.SET_WALLPAPER_INTENT, false) private fun isSetWallpaperIntent() = intent.getBooleanExtra(Constants.SET_WALLPAPER_INTENT, false)
private fun displayCopyDialog() { private fun displayCopyDialog() {
val items = media_grid.checkedItemPositions /*val items = media_grid.checkedItemPositions
val cnt = items.size() val cnt = items.size()
val files = (0..cnt - 1) val files = (0..cnt - 1)
.filter { items.valueAt(it) } .filter { items.valueAt(it) }
@ -390,7 +390,7 @@ class MediaActivity : SimpleActivity(), AdapterView.OnItemClickListener, View.On
override fun copyFailed() { override fun copyFailed() {
toast(R.string.copy_move_failed) toast(R.string.copy_move_failed)
} }
}) })*/
} }
override fun onItemClick(parent: AdapterView<*>, view: View, position: Int, id: Long) { override fun onItemClick(parent: AdapterView<*>, view: View, position: Int, id: Long) {
@ -484,7 +484,7 @@ class MediaActivity : SimpleActivity(), AdapterView.OnItemClickListener, View.On
override fun onTouch(v: View, event: MotionEvent): Boolean { override fun onTouch(v: View, event: MotionEvent): Boolean {
if (mIsSnackbarShown) { if (mIsSnackbarShown) {
deleteFiles() //deleteFiles()
} }
return false return false

View File

@ -1,58 +1,73 @@
package com.simplemobiletools.gallery.adapters package com.simplemobiletools.gallery.adapters
import android.content.Context import android.os.Build
import android.view.LayoutInflater import android.support.v7.view.ActionMode
import android.view.View import android.support.v7.widget.RecyclerView
import android.view.ViewGroup import android.view.*
import android.widget.BaseAdapter import com.bignerdranch.android.multiselector.ModalMultiSelectorCallback
import android.widget.ImageView import com.bignerdranch.android.multiselector.MultiSelector
import android.widget.TextView import com.bignerdranch.android.multiselector.SwappingHolder
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.signature.StringSignature import com.bumptech.glide.signature.StringSignature
import com.simplemobiletools.gallery.Config import com.simplemobiletools.gallery.Config
import com.simplemobiletools.gallery.R import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.activities.SimpleActivity
import com.simplemobiletools.gallery.extensions.beVisibleIf import com.simplemobiletools.gallery.extensions.beVisibleIf
import com.simplemobiletools.gallery.models.Medium import com.simplemobiletools.gallery.models.Medium
import kotlinx.android.synthetic.main.photo_video_item.view.* import kotlinx.android.synthetic.main.photo_video_item.view.*
import kotlinx.android.synthetic.main.photo_video_tmb.view.* import kotlinx.android.synthetic.main.photo_video_tmb.view.*
import java.util.*
class MediaAdapter(private val context: Context, private val media: MutableList<Medium>) : BaseAdapter() { class MediaAdapter(val activity: SimpleActivity, val media: MutableList<Medium>, val listener: MediaAdapter.MediaOperationsListener?, val itemClick: (Medium) -> Unit) :
private val mInflater: LayoutInflater RecyclerView.Adapter<MediaAdapter.ViewHolder>() {
var displayFilenames = false val multiSelector = MultiSelector()
val views = ArrayList<View>()
val config = Config.newInstance(activity)
init { companion object {
mInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater var actMode: ActionMode? = null
displayFilenames = Config.newInstance(context).displayFileNames var displayFilenames = false
fun toggleItemSelection(itemView: View, select: Boolean) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
itemView.medium_thumbnail_holder.isActivated = select
else
itemView.medium_thumbnail.isActivated = select
}
} }
override fun getView(position: Int, view: View?, parent: ViewGroup): View { val multiSelectorMode = object : ModalMultiSelectorCallback(multiSelector) {
var convertView = view override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
val medium = media[position] return false
val viewHolder: ViewHolder
if (convertView == null) {
convertView = mInflater.inflate(R.layout.photo_video_item, parent, false)
viewHolder = ViewHolder(convertView)
convertView!!.tag = viewHolder
} else {
viewHolder = convertView.tag as ViewHolder
} }
viewHolder.playOutline.visibility = if (medium.isVideo) View.VISIBLE else View.GONE override fun onCreateActionMode(actionMode: ActionMode?, menu: Menu?): Boolean {
super.onCreateActionMode(actionMode, menu)
viewHolder.fileName.beVisibleIf(displayFilenames) DirectoryAdapter.actMode = actionMode
if (displayFilenames) activity.menuInflater.inflate(R.menu.cab_media, menu)
viewHolder.fileName.text = medium.name return true
val path = medium.path
val timestampSignature = StringSignature(medium.timestamp.toString())
if (medium.isGif) {
Glide.with(context).load(path).asGif().diskCacheStrategy(DiskCacheStrategy.NONE).signature(timestampSignature).into(viewHolder.photoThumbnail)
} else {
Glide.with(context).load(path).diskCacheStrategy(DiskCacheStrategy.NONE).signature(timestampSignature)
.placeholder(R.color.tmb_background).centerCrop().crossFade().into(viewHolder.photoThumbnail)
} }
return convertView override fun onPrepareActionMode(actionMode: ActionMode?, menu: Menu): Boolean {
val menuItem = menu.findItem(R.id.cab_edit)
menuItem.isVisible = multiSelector.selectedPositions.size <= 1
return true
}
override fun onDestroyActionMode(actionMode: ActionMode?) {
super.onDestroyActionMode(actionMode)
views.forEach { MediaAdapter.toggleItemSelection(it, false) }
}
}
override fun onBindViewHolder(holder: MediaAdapter.ViewHolder, position: Int) {
views.add(holder.bindView(activity, multiSelectorMode, multiSelector, media[position]))
}
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): MediaAdapter.ViewHolder {
val view = LayoutInflater.from(parent?.context).inflate(R.layout.photo_video_item, parent, false)
return MediaAdapter.ViewHolder(view, itemClick)
} }
fun updateDisplayFilenames(display: Boolean) { fun updateDisplayFilenames(display: Boolean) {
@ -60,21 +75,38 @@ class MediaAdapter(private val context: Context, private val media: MutableList<
notifyDataSetChanged() notifyDataSetChanged()
} }
override fun getCount() = media.size override fun getItemCount() = media.size
override fun getItem(position: Int) = media[position] class ViewHolder(view: View, val itemClick: (Medium) -> (Unit)) : SwappingHolder(view, MultiSelector()) {
fun bindView(activity: SimpleActivity, multiSelectorCallback: ModalMultiSelectorCallback, multiSelector: MultiSelector, medium: Medium): View {
itemView.play_outline.visibility = if (medium.isVideo) View.VISIBLE else View.GONE
itemView.file_name.beVisibleIf(displayFilenames)
itemView.file_name.text = medium.name
override fun getItemId(position: Int) = 0L val path = medium.path
val timestampSignature = StringSignature(medium.timestamp.toString())
if (medium.isGif) {
Glide.with(activity).load(path).asGif().diskCacheStrategy(DiskCacheStrategy.NONE).signature(timestampSignature).into(itemView.medium_thumbnail)
} else {
Glide.with(activity).load(path).diskCacheStrategy(DiskCacheStrategy.NONE).signature(timestampSignature)
.placeholder(R.color.tmb_background).centerCrop().crossFade().into(itemView.medium_thumbnail)
}
fun updateItems(newPhotos: List<Medium>) { itemView.setOnClickListener { viewClicked(multiSelector, medium) }
media.clear()
media.addAll(newPhotos) return itemView
notifyDataSetChanged() }
fun viewClicked(multiSelector: MultiSelector, medium: Medium) {
if (multiSelector.isSelectable) {
} else {
itemClick(medium)
}
}
} }
internal class ViewHolder(view: View) { interface MediaOperationsListener {
val photoThumbnail: ImageView = view.medium_thumbnail
val playOutline: View = view.play_outline
val fileName: TextView = view.file_name
} }
} }

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout <android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/coordinator_layout" android:id="@+id/coordinator_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
@ -10,16 +11,12 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<GridView <android.support.v7.widget.RecyclerView
android:id="@+id/media_grid" android:id="@+id/media_grid"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:choiceMode="multipleChoiceModal" app:layoutManager="android.support.v7.widget.GridLayoutManager"
android:columnWidth="@dimen/medium_tmb_size" app:spanCount="@integer/photo_columns"/>
android:horizontalSpacing="1dp"
android:numColumns="auto_fit"
android:stretchMode="columnWidth"
android:verticalSpacing="1dp"/>
</android.support.v4.widget.SwipeRefreshLayout> </android.support.v4.widget.SwipeRefreshLayout>
</android.support.design.widget.CoordinatorLayout> </android.support.design.widget.CoordinatorLayout>

View File

@ -3,7 +3,8 @@
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/media_item_holder" android:id="@+id/media_item_holder"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="wrap_content"
android:padding="1px">
<include layout="@layout/photo_video_tmb"/> <include layout="@layout/photo_video_tmb"/>
@ -11,9 +12,9 @@
android:id="@+id/play_outline" android:id="@+id/play_outline"
android:layout_width="@dimen/play_outline_size" android:layout_width="@dimen/play_outline_size"
android:layout_height="@dimen/play_outline_size" android:layout_height="@dimen/play_outline_size"
android:layout_margin="@dimen/tiny_margin"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_margin="@dimen/tiny_margin"
android:src="@mipmap/play_outline" android:src="@mipmap/play_outline"
android:visibility="gone"/> android:visibility="gone"/>

View File

@ -1,3 +1,4 @@
<resources> <resources>
<integer name="directory_columns">3</integer> <integer name="directory_columns">3</integer>
<integer name="photo_columns">5</integer>
</resources> </resources>

View File

@ -1,3 +1,4 @@
<resources> <resources>
<integer name="directory_columns">4</integer> <integer name="directory_columns">4</integer>
<integer name="photo_columns">7</integer>
</resources> </resources>

View File

@ -1,3 +1,4 @@
<resources> <resources>
<integer name="directory_columns">2</integer> <integer name="directory_columns">2</integer>
<integer name="photo_columns">3</integer>
</resources> </resources>