mirror of
				https://github.com/SimpleMobileTools/Simple-App-Launcher.git
				synced 2025-06-05 21:49:21 +02:00 
			
		
		
		
	initial rewrite of RecyclerAdapter
This commit is contained in:
		| @@ -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) | ||||
|   | ||||
| @@ -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() | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user