initial rewrite of RecyclerAdapter

This commit is contained in:
tibbi 2017-11-11 17:54:34 +01:00
parent 56ffc7284f
commit 97d1ddb78d
2 changed files with 109 additions and 107 deletions

View File

@ -6,14 +6,12 @@ import android.net.Uri
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.widget.ImageView
import com.simplemobiletools.applauncher.BuildConfig
import com.simplemobiletools.applauncher.R
import com.simplemobiletools.applauncher.adapters.RecyclerAdapter
import com.simplemobiletools.applauncher.dialogs.AddAppDialog
import com.simplemobiletools.applauncher.extensions.dbHelper
import com.simplemobiletools.applauncher.models.AppLauncher
import com.simplemobiletools.commons.extensions.beInvisible
import com.simplemobiletools.commons.extensions.checkWhatsNew
import com.simplemobiletools.commons.extensions.updateTextColors
import com.simplemobiletools.commons.helpers.LICENSE_KOTLIN
@ -23,7 +21,7 @@ import com.simplemobiletools.commons.models.Release
import kotlinx.android.synthetic.main.activity_main.*
import java.util.*
class MainActivity : SimpleActivity(), RecyclerAdapter.RecyclerInterface {
class MainActivity : SimpleActivity(), RecyclerAdapter.AppLaunchersListener {
private var launchers = ArrayList<AppLauncher>()
private var remainingLaunchers = ArrayList<AppLauncher>()
@ -35,7 +33,7 @@ class MainActivity : SimpleActivity(), RecyclerAdapter.RecyclerInterface {
fab.setOnClickListener {
AddAppDialog(this, getNotDisplayedLaunchers()) {
refreshLaunchers()
}
}
}
@ -71,7 +69,7 @@ class MainActivity : SimpleActivity(), RecyclerAdapter.RecyclerInterface {
private fun setupLaunchers() {
launchers = dbHelper.getLaunchers()
checkInvalidApps()
launchers_holder.adapter = RecyclerAdapter(this, launchers) {
launchers_holder.adapter = RecyclerAdapter(this, launchers, this) {
val launchIntent = packageManager.getLaunchIntentForPackage(it.pkgName)
if (launchIntent != null) {
startActivity(launchIntent)
@ -116,32 +114,10 @@ class MainActivity : SimpleActivity(), RecyclerAdapter.RecyclerInterface {
launchers = launchers.filter { !invalidIds.contains(it.id.toString()) } as ArrayList<AppLauncher>
}
override fun launchersDeleted(indexes: List<Int>, deletedLaunchers: List<AppLauncher>) {
val reversed = indexes.reversed()
for (index in reversed) {
launchers.removeAt(index)
launchers_holder.adapter.notifyItemRemoved(index)
}
remainingLaunchers.addAll(deletedLaunchers)
remainingLaunchers.sortBy { it.name }
}
override fun launcherRenamed() {
refreshLaunchers()
}
private fun refreshLaunchers() {
(launchers_holder.adapter as RecyclerAdapter).finishActionMode()
override fun refreshLaunchers() {
setupLaunchers()
}
override fun refreshLauncherIcons() {
for (pos in 0 until launchers_holder.childCount) {
launchers_holder.getChildAt(pos).findViewById<ImageView>(R.id.launcher_check).beInvisible()
}
}
private fun checkWhatsNewDialog() {
arrayListOf<Release>().apply {
checkWhatsNew(this, BuildConfig.VERSION_CODE)

View File

@ -1,88 +1,122 @@
package com.simplemobiletools.applauncher.adapters
import android.app.Activity
import android.app.AlertDialog
import android.content.pm.PackageManager
import android.support.v7.app.AppCompatActivity
import android.graphics.PorterDuff
import android.support.v7.view.ActionMode
import android.support.v7.widget.RecyclerView
import android.util.SparseArray
import android.view.*
import com.bignerdranch.android.multiselector.ModalMultiSelectorCallback
import com.bignerdranch.android.multiselector.MultiSelector
import com.bignerdranch.android.multiselector.SwappingHolder
import com.simplemobiletools.applauncher.R
import com.simplemobiletools.applauncher.activities.SimpleActivity
import com.simplemobiletools.applauncher.extensions.config
import com.simplemobiletools.applauncher.extensions.dbHelper
import com.simplemobiletools.applauncher.models.AppLauncher
import com.simplemobiletools.commons.extensions.beInvisibleIf
import com.simplemobiletools.commons.extensions.beVisible
import com.simplemobiletools.commons.extensions.beGone
import com.simplemobiletools.commons.extensions.beVisibleIf
import com.simplemobiletools.commons.extensions.toast
import kotlinx.android.synthetic.main.app_launcher_item.view.*
import kotlinx.android.synthetic.main.dialog_edit_launcher.view.*
import java.util.*
class RecyclerAdapter(val act: Activity, val launchers: List<AppLauncher>, val itemClick: (AppLauncher) -> Unit) :
class RecyclerAdapter(val activity: SimpleActivity, val launchers: List<AppLauncher>, val listener: AppLaunchersListener?, val itemClick: (AppLauncher) -> Unit) :
RecyclerView.Adapter<RecyclerAdapter.ViewHolder>() {
val multiSelector = MultiSelector()
private val config = activity.config
var actMode: ActionMode? = null
var primaryColor = config.primaryColor
companion object {
var actMode: ActionMode? = null
private val multiSelector = MultiSelector()
private var itemViews = SparseArray<View>()
private val selectedPositions = HashSet<Int>()
private var textColor = config.textColor
fun toggleItemSelection(select: Boolean, pos: Int) {
if (select) {
if (itemViews[pos] != null) {
itemViews[pos].launcher_check?.background?.setColorFilter(primaryColor, PorterDuff.Mode.SRC_IN)
selectedPositions.add(pos)
}
} else {
selectedPositions.remove(pos)
}
itemViews[pos]?.launcher_check?.beVisibleIf(select)
if (selectedPositions.isEmpty()) {
actMode?.finish()
return
}
updateTitle(selectedPositions.size)
}
private fun updateTitle(cnt: Int) {
actMode?.title = "$cnt / ${launchers.size}"
actMode?.invalidate()
}
private val adapterListener = object : MyAdapterListener {
override fun toggleItemSelectionAdapter(select: Boolean, position: Int) {
toggleItemSelection(select, position)
}
override fun getSelectedPositions(): HashSet<Int> = selectedPositions
}
private val multiSelectorMode = object : ModalMultiSelectorCallback(multiSelector) {
override fun onActionItemClicked(mode: ActionMode?, item: MenuItem): Boolean {
return when (item.itemId) {
R.id.cab_edit -> {
showEditDialog()
true
}
R.id.cab_delete -> {
deleteSelectedItems()
true
}
else -> false
when (item.itemId) {
R.id.cab_edit -> showEditDialog()
R.id.cab_delete -> deleteSelectedItems()
else -> return false
}
return true
}
override fun onCreateActionMode(actionMode: ActionMode?, menu: Menu?): Boolean {
super.onCreateActionMode(actionMode, menu)
actMode = actionMode
act.menuInflater.inflate(R.menu.cab, menu)
activity.menuInflater.inflate(R.menu.cab, menu)
return true
}
override fun onPrepareActionMode(actionMode: ActionMode?, menu: Menu?): Boolean {
val menuItem = menu?.findItem(R.id.cab_edit)
menuItem?.isVisible = multiSelector.selectedPositions.size == 1
override fun onPrepareActionMode(actionMode: ActionMode?, menu: Menu): Boolean {
menu.findItem(R.id.cab_edit).isVisible = multiSelector.selectedPositions.size == 1
return true
}
override fun onDestroyActionMode(actionMode: ActionMode?) {
super.onDestroyActionMode(actionMode)
(act as RecyclerInterface).refreshLauncherIcons()
selectedPositions.forEach {
itemViews[it]?.launcher_check?.beGone()
}
selectedPositions.clear()
actMode = null
}
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bindView(act, multiSelectorMode, multiSelector, launchers[position])
holder.bindView(launchers[position], textColor)
}
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent?.context).inflate(R.layout.app_launcher_item, parent, false)
return ViewHolder(view, itemClick)
return ViewHolder(view, adapterListener, activity, multiSelectorMode, multiSelector, listener, itemClick)
}
override fun getItemCount(): Int {
return launchers.count()
}
override fun getItemCount() = launchers.count()
private fun showEditDialog() {
val selectedLauncher = launchers[multiSelector.selectedPositions[0]]
val editView = act.layoutInflater.inflate(R.layout.dialog_edit_launcher, null)
val editView = activity.layoutInflater.inflate(R.layout.dialog_edit_launcher, null)
editView.edit_launcher_edittext.setText(selectedLauncher.name)
AlertDialog.Builder(act).apply {
setTitle(act.getString(R.string.rename))
AlertDialog.Builder(activity).apply {
setTitle(activity.getString(R.string.rename))
setView(editView)
setPositiveButton(R.string.ok, null)
setNegativeButton(R.string.cancel, null)
@ -92,22 +126,21 @@ class RecyclerAdapter(val act: Activity, val launchers: List<AppLauncher>, val i
getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
val newName = editView.edit_launcher_edittext.text.toString().trim()
if (!newName.isEmpty()) {
if (act.dbHelper.updateLauncherName(selectedLauncher.id, newName) > 0) {
(act as RecyclerInterface).launcherRenamed()
finishActionMode()
if (activity.dbHelper.updateLauncherName(selectedLauncher.id, newName) > 0) {
listener?.refreshLaunchers()
dismiss()
} else {
act.toast(R.string.unknown_error_occurred)
activity.toast(R.string.unknown_error_occurred)
}
} else {
act.toast(R.string.enter_launcher_name)
activity.toast(R.string.enter_launcher_name)
}
}
}
}
}
fun finishActionMode() {
private fun finishActionMode() {
actMode?.finish()
}
@ -123,74 +156,67 @@ class RecyclerAdapter(val act: Activity, val launchers: List<AppLauncher>, val i
if (launcher.name.isNotEmpty())
deletedLaunchers.add(launcher)
}
act.dbHelper.deleteLaunchers(deleteIds)
activity.dbHelper.deleteLaunchers(deleteIds)
finishActionMode()
(act as RecyclerInterface).launchersDeleted(positions, deletedLaunchers)
listener?.refreshLaunchers()
}
private fun getRealAppName(launcher: AppLauncher): String {
return try {
val applicationInfo = act.packageManager.getApplicationInfo(launcher.pkgName, 0)
act.packageManager.getApplicationLabel(applicationInfo).toString()
val applicationInfo = activity.packageManager.getApplicationInfo(launcher.pkgName, 0)
activity.packageManager.getApplicationLabel(applicationInfo).toString()
} catch (e: PackageManager.NameNotFoundException) {
""
}
}
class ViewHolder(view: View, val itemClick: (AppLauncher) -> (Unit)) : SwappingHolder(view, MultiSelector()) {
val viewHolder = this
class ViewHolder(view: View, val adapterListener: MyAdapterListener, val activity: SimpleActivity, val multiSelectorCallback: ModalMultiSelectorCallback,
val multiSelector: MultiSelector, val listener: AppLaunchersListener?, val itemClick: (AppLauncher) -> (Unit)) : SwappingHolder(view, MultiSelector()) {
fun bindView(launcher: AppLauncher, textColor: Int): View {
itemView.apply {
launcher_label.text = launcher.name
launcher_label.setTextColor(textColor)
fun bindView(act: Activity, multiSelectorCallback: ModalMultiSelectorCallback, multiSelector: MultiSelector, launcher: AppLauncher) {
with(launcher) {
itemView.launcher_label.text = launcher.name
itemView.setOnClickListener {
viewClicked(multiSelector, launcher)
}
setOnClickListener { viewClicked(launcher) }
setOnLongClickListener { viewLongClicked(); true }
itemView.setOnLongClickListener {
if (!multiSelector.isSelectable) {
(act as AppCompatActivity).startSupportActionMode(multiSelectorCallback)
multiSelector.setSelected(viewHolder, true)
actMode?.title = multiSelector.selectedPositions.size.toString()
itemView.launcher_check.beVisible()
}
true
}
if (launcher.iconId != 0) {
/*if (launcher.iconId != 0) {
val icon = act.resources.getDrawable(launcher.iconId)
itemView.launcher_icon.setImageDrawable(icon)
launcher_icon.setImageDrawable(icon)
} else {
val icon = act.packageManager.getApplicationIcon(launcher.pkgName)
itemView.launcher_icon.setImageDrawable(icon)
}
launcher_icon.setImageDrawable(icon)
}*/
}
return itemView
}
private fun viewClicked(multiSelector: MultiSelector, appLauncher: AppLauncher) {
private fun viewClicked(appLauncher: AppLauncher) {
if (multiSelector.isSelectable) {
val isSelected = multiSelector.selectedPositions.contains(viewHolder.layoutPosition)
multiSelector.setSelected(viewHolder, !isSelected)
itemView.launcher_check.beInvisibleIf(isSelected)
val selectedCnt = multiSelector.selectedPositions.size
if (selectedCnt == 0) {
actMode?.finish()
} else {
actMode?.title = selectedCnt.toString()
}
actMode?.invalidate()
val isSelected = adapterListener.getSelectedPositions().contains(adapterPosition)
adapterListener.toggleItemSelectionAdapter(!isSelected, adapterPosition)
} else {
itemClick(appLauncher)
}
}
private fun viewLongClicked() {
if (listener != null) {
if (!multiSelector.isSelectable) {
activity.startSupportActionMode(multiSelectorCallback)
adapterListener.toggleItemSelectionAdapter(true, adapterPosition)
}
}
}
}
interface RecyclerInterface {
fun launchersDeleted(indexes: List<Int>, deletedLaunchers: List<AppLauncher>)
interface MyAdapterListener {
fun toggleItemSelectionAdapter(select: Boolean, position: Int)
fun launcherRenamed()
fun getSelectedPositions(): HashSet<Int>
}
fun refreshLauncherIcons()
interface AppLaunchersListener {
fun refreshLaunchers()
}
}