mirror of
https://github.com/SimpleMobileTools/Simple-App-Launcher.git
synced 2025-04-15 10:27:28 +02:00
initial rewrite of RecyclerAdapter
This commit is contained in:
parent
56ffc7284f
commit
97d1ddb78d
@ -6,14 +6,12 @@ import android.net.Uri
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.widget.ImageView
|
|
||||||
import com.simplemobiletools.applauncher.BuildConfig
|
import com.simplemobiletools.applauncher.BuildConfig
|
||||||
import com.simplemobiletools.applauncher.R
|
import com.simplemobiletools.applauncher.R
|
||||||
import com.simplemobiletools.applauncher.adapters.RecyclerAdapter
|
import com.simplemobiletools.applauncher.adapters.RecyclerAdapter
|
||||||
import com.simplemobiletools.applauncher.dialogs.AddAppDialog
|
import com.simplemobiletools.applauncher.dialogs.AddAppDialog
|
||||||
import com.simplemobiletools.applauncher.extensions.dbHelper
|
import com.simplemobiletools.applauncher.extensions.dbHelper
|
||||||
import com.simplemobiletools.applauncher.models.AppLauncher
|
import com.simplemobiletools.applauncher.models.AppLauncher
|
||||||
import com.simplemobiletools.commons.extensions.beInvisible
|
|
||||||
import com.simplemobiletools.commons.extensions.checkWhatsNew
|
import com.simplemobiletools.commons.extensions.checkWhatsNew
|
||||||
import com.simplemobiletools.commons.extensions.updateTextColors
|
import com.simplemobiletools.commons.extensions.updateTextColors
|
||||||
import com.simplemobiletools.commons.helpers.LICENSE_KOTLIN
|
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 kotlinx.android.synthetic.main.activity_main.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class MainActivity : SimpleActivity(), RecyclerAdapter.RecyclerInterface {
|
class MainActivity : SimpleActivity(), RecyclerAdapter.AppLaunchersListener {
|
||||||
private var launchers = ArrayList<AppLauncher>()
|
private var launchers = ArrayList<AppLauncher>()
|
||||||
private var remainingLaunchers = ArrayList<AppLauncher>()
|
private var remainingLaunchers = ArrayList<AppLauncher>()
|
||||||
|
|
||||||
@ -35,7 +33,7 @@ class MainActivity : SimpleActivity(), RecyclerAdapter.RecyclerInterface {
|
|||||||
|
|
||||||
fab.setOnClickListener {
|
fab.setOnClickListener {
|
||||||
AddAppDialog(this, getNotDisplayedLaunchers()) {
|
AddAppDialog(this, getNotDisplayedLaunchers()) {
|
||||||
|
refreshLaunchers()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,7 +69,7 @@ class MainActivity : SimpleActivity(), RecyclerAdapter.RecyclerInterface {
|
|||||||
private fun setupLaunchers() {
|
private fun setupLaunchers() {
|
||||||
launchers = dbHelper.getLaunchers()
|
launchers = dbHelper.getLaunchers()
|
||||||
checkInvalidApps()
|
checkInvalidApps()
|
||||||
launchers_holder.adapter = RecyclerAdapter(this, launchers) {
|
launchers_holder.adapter = RecyclerAdapter(this, launchers, this) {
|
||||||
val launchIntent = packageManager.getLaunchIntentForPackage(it.pkgName)
|
val launchIntent = packageManager.getLaunchIntentForPackage(it.pkgName)
|
||||||
if (launchIntent != null) {
|
if (launchIntent != null) {
|
||||||
startActivity(launchIntent)
|
startActivity(launchIntent)
|
||||||
@ -116,32 +114,10 @@ class MainActivity : SimpleActivity(), RecyclerAdapter.RecyclerInterface {
|
|||||||
launchers = launchers.filter { !invalidIds.contains(it.id.toString()) } as ArrayList<AppLauncher>
|
launchers = launchers.filter { !invalidIds.contains(it.id.toString()) } as ArrayList<AppLauncher>
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun launchersDeleted(indexes: List<Int>, deletedLaunchers: List<AppLauncher>) {
|
override fun refreshLaunchers() {
|
||||||
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()
|
|
||||||
setupLaunchers()
|
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() {
|
private fun checkWhatsNewDialog() {
|
||||||
arrayListOf<Release>().apply {
|
arrayListOf<Release>().apply {
|
||||||
checkWhatsNew(this, BuildConfig.VERSION_CODE)
|
checkWhatsNew(this, BuildConfig.VERSION_CODE)
|
||||||
|
@ -1,88 +1,122 @@
|
|||||||
package com.simplemobiletools.applauncher.adapters
|
package com.simplemobiletools.applauncher.adapters
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.app.AlertDialog
|
import android.app.AlertDialog
|
||||||
import android.content.pm.PackageManager
|
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.view.ActionMode
|
||||||
import android.support.v7.widget.RecyclerView
|
import android.support.v7.widget.RecyclerView
|
||||||
|
import android.util.SparseArray
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import com.bignerdranch.android.multiselector.ModalMultiSelectorCallback
|
import com.bignerdranch.android.multiselector.ModalMultiSelectorCallback
|
||||||
import com.bignerdranch.android.multiselector.MultiSelector
|
import com.bignerdranch.android.multiselector.MultiSelector
|
||||||
import com.bignerdranch.android.multiselector.SwappingHolder
|
import com.bignerdranch.android.multiselector.SwappingHolder
|
||||||
import com.simplemobiletools.applauncher.R
|
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.extensions.dbHelper
|
||||||
import com.simplemobiletools.applauncher.models.AppLauncher
|
import com.simplemobiletools.applauncher.models.AppLauncher
|
||||||
import com.simplemobiletools.commons.extensions.beInvisibleIf
|
import com.simplemobiletools.commons.extensions.beGone
|
||||||
import com.simplemobiletools.commons.extensions.beVisible
|
import com.simplemobiletools.commons.extensions.beVisibleIf
|
||||||
import com.simplemobiletools.commons.extensions.toast
|
import com.simplemobiletools.commons.extensions.toast
|
||||||
import kotlinx.android.synthetic.main.app_launcher_item.view.*
|
import kotlinx.android.synthetic.main.app_launcher_item.view.*
|
||||||
import kotlinx.android.synthetic.main.dialog_edit_launcher.view.*
|
import kotlinx.android.synthetic.main.dialog_edit_launcher.view.*
|
||||||
import java.util.*
|
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>() {
|
RecyclerView.Adapter<RecyclerAdapter.ViewHolder>() {
|
||||||
|
|
||||||
val multiSelector = MultiSelector()
|
private val config = activity.config
|
||||||
|
var actMode: ActionMode? = null
|
||||||
|
var primaryColor = config.primaryColor
|
||||||
|
|
||||||
companion object {
|
private val multiSelector = MultiSelector()
|
||||||
var actMode: ActionMode? = null
|
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) {
|
private val multiSelectorMode = object : ModalMultiSelectorCallback(multiSelector) {
|
||||||
override fun onActionItemClicked(mode: ActionMode?, item: MenuItem): Boolean {
|
override fun onActionItemClicked(mode: ActionMode?, item: MenuItem): Boolean {
|
||||||
return when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.cab_edit -> {
|
R.id.cab_edit -> showEditDialog()
|
||||||
showEditDialog()
|
R.id.cab_delete -> deleteSelectedItems()
|
||||||
true
|
else -> return false
|
||||||
}
|
|
||||||
R.id.cab_delete -> {
|
|
||||||
deleteSelectedItems()
|
|
||||||
true
|
|
||||||
}
|
|
||||||
else -> false
|
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateActionMode(actionMode: ActionMode?, menu: Menu?): Boolean {
|
override fun onCreateActionMode(actionMode: ActionMode?, menu: Menu?): Boolean {
|
||||||
super.onCreateActionMode(actionMode, menu)
|
super.onCreateActionMode(actionMode, menu)
|
||||||
actMode = actionMode
|
actMode = actionMode
|
||||||
act.menuInflater.inflate(R.menu.cab, menu)
|
activity.menuInflater.inflate(R.menu.cab, menu)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPrepareActionMode(actionMode: ActionMode?, menu: Menu?): Boolean {
|
override fun onPrepareActionMode(actionMode: ActionMode?, menu: Menu): Boolean {
|
||||||
val menuItem = menu?.findItem(R.id.cab_edit)
|
menu.findItem(R.id.cab_edit).isVisible = multiSelector.selectedPositions.size == 1
|
||||||
menuItem?.isVisible = multiSelector.selectedPositions.size == 1
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyActionMode(actionMode: ActionMode?) {
|
override fun onDestroyActionMode(actionMode: ActionMode?) {
|
||||||
super.onDestroyActionMode(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) {
|
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 {
|
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
|
||||||
val view = LayoutInflater.from(parent?.context).inflate(R.layout.app_launcher_item, parent, false)
|
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 {
|
override fun getItemCount() = launchers.count()
|
||||||
return launchers.count()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun showEditDialog() {
|
private fun showEditDialog() {
|
||||||
val selectedLauncher = launchers[multiSelector.selectedPositions[0]]
|
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)
|
editView.edit_launcher_edittext.setText(selectedLauncher.name)
|
||||||
|
|
||||||
AlertDialog.Builder(act).apply {
|
AlertDialog.Builder(activity).apply {
|
||||||
setTitle(act.getString(R.string.rename))
|
setTitle(activity.getString(R.string.rename))
|
||||||
setView(editView)
|
setView(editView)
|
||||||
setPositiveButton(R.string.ok, null)
|
setPositiveButton(R.string.ok, null)
|
||||||
setNegativeButton(R.string.cancel, 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 {
|
getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
|
||||||
val newName = editView.edit_launcher_edittext.text.toString().trim()
|
val newName = editView.edit_launcher_edittext.text.toString().trim()
|
||||||
if (!newName.isEmpty()) {
|
if (!newName.isEmpty()) {
|
||||||
if (act.dbHelper.updateLauncherName(selectedLauncher.id, newName) > 0) {
|
if (activity.dbHelper.updateLauncherName(selectedLauncher.id, newName) > 0) {
|
||||||
(act as RecyclerInterface).launcherRenamed()
|
listener?.refreshLaunchers()
|
||||||
finishActionMode()
|
|
||||||
dismiss()
|
dismiss()
|
||||||
} else {
|
} else {
|
||||||
act.toast(R.string.unknown_error_occurred)
|
activity.toast(R.string.unknown_error_occurred)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
act.toast(R.string.enter_launcher_name)
|
activity.toast(R.string.enter_launcher_name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun finishActionMode() {
|
private fun finishActionMode() {
|
||||||
actMode?.finish()
|
actMode?.finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,74 +156,67 @@ class RecyclerAdapter(val act: Activity, val launchers: List<AppLauncher>, val i
|
|||||||
if (launcher.name.isNotEmpty())
|
if (launcher.name.isNotEmpty())
|
||||||
deletedLaunchers.add(launcher)
|
deletedLaunchers.add(launcher)
|
||||||
}
|
}
|
||||||
act.dbHelper.deleteLaunchers(deleteIds)
|
activity.dbHelper.deleteLaunchers(deleteIds)
|
||||||
finishActionMode()
|
finishActionMode()
|
||||||
(act as RecyclerInterface).launchersDeleted(positions, deletedLaunchers)
|
listener?.refreshLaunchers()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getRealAppName(launcher: AppLauncher): String {
|
private fun getRealAppName(launcher: AppLauncher): String {
|
||||||
return try {
|
return try {
|
||||||
val applicationInfo = act.packageManager.getApplicationInfo(launcher.pkgName, 0)
|
val applicationInfo = activity.packageManager.getApplicationInfo(launcher.pkgName, 0)
|
||||||
act.packageManager.getApplicationLabel(applicationInfo).toString()
|
activity.packageManager.getApplicationLabel(applicationInfo).toString()
|
||||||
} catch (e: PackageManager.NameNotFoundException) {
|
} catch (e: PackageManager.NameNotFoundException) {
|
||||||
""
|
""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ViewHolder(view: View, val itemClick: (AppLauncher) -> (Unit)) : SwappingHolder(view, MultiSelector()) {
|
class ViewHolder(view: View, val adapterListener: MyAdapterListener, val activity: SimpleActivity, val multiSelectorCallback: ModalMultiSelectorCallback,
|
||||||
val viewHolder = this
|
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) {
|
setOnClickListener { viewClicked(launcher) }
|
||||||
with(launcher) {
|
setOnLongClickListener { viewLongClicked(); true }
|
||||||
itemView.launcher_label.text = launcher.name
|
|
||||||
itemView.setOnClickListener {
|
|
||||||
viewClicked(multiSelector, launcher)
|
|
||||||
}
|
|
||||||
|
|
||||||
itemView.setOnLongClickListener {
|
/*if (launcher.iconId != 0) {
|
||||||
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) {
|
|
||||||
val icon = act.resources.getDrawable(launcher.iconId)
|
val icon = act.resources.getDrawable(launcher.iconId)
|
||||||
itemView.launcher_icon.setImageDrawable(icon)
|
launcher_icon.setImageDrawable(icon)
|
||||||
} else {
|
} else {
|
||||||
val icon = act.packageManager.getApplicationIcon(launcher.pkgName)
|
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) {
|
if (multiSelector.isSelectable) {
|
||||||
val isSelected = multiSelector.selectedPositions.contains(viewHolder.layoutPosition)
|
val isSelected = adapterListener.getSelectedPositions().contains(adapterPosition)
|
||||||
multiSelector.setSelected(viewHolder, !isSelected)
|
adapterListener.toggleItemSelectionAdapter(!isSelected, adapterPosition)
|
||||||
itemView.launcher_check.beInvisibleIf(isSelected)
|
|
||||||
|
|
||||||
val selectedCnt = multiSelector.selectedPositions.size
|
|
||||||
if (selectedCnt == 0) {
|
|
||||||
actMode?.finish()
|
|
||||||
} else {
|
|
||||||
actMode?.title = selectedCnt.toString()
|
|
||||||
}
|
|
||||||
actMode?.invalidate()
|
|
||||||
} else {
|
} else {
|
||||||
itemClick(appLauncher)
|
itemClick(appLauncher)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun viewLongClicked() {
|
||||||
|
if (listener != null) {
|
||||||
|
if (!multiSelector.isSelectable) {
|
||||||
|
activity.startSupportActionMode(multiSelectorCallback)
|
||||||
|
adapterListener.toggleItemSelectionAdapter(true, adapterPosition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RecyclerInterface {
|
interface MyAdapterListener {
|
||||||
fun launchersDeleted(indexes: List<Int>, deletedLaunchers: List<AppLauncher>)
|
fun toggleItemSelectionAdapter(select: Boolean, position: Int)
|
||||||
|
|
||||||
fun launcherRenamed()
|
fun getSelectedPositions(): HashSet<Int>
|
||||||
|
}
|
||||||
|
|
||||||
fun refreshLauncherIcons()
|
interface AppLaunchersListener {
|
||||||
|
fun refreshLaunchers()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user