Merge pull request #1245 from KryptKode/feat/bottom_cab
Feat/bottom cab
This commit is contained in:
commit
2cc4d857a4
16 changed files with 750 additions and 45 deletions
|
@ -1,13 +1,13 @@
|
|||
package com.simplemobiletools.commons.adapters
|
||||
|
||||
import android.util.TypedValue
|
||||
import android.view.Menu
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.simplemobiletools.commons.R
|
||||
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
||||
import com.simplemobiletools.commons.extensions.getTextSize
|
||||
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||
import com.simplemobiletools.commons.views.bottomactionmenu.BottomActionMenuView
|
||||
import kotlinx.android.synthetic.main.filepicker_favorite.view.*
|
||||
|
||||
class FilepickerFavoritesAdapter(
|
||||
|
@ -35,7 +35,7 @@ class FilepickerFavoritesAdapter(
|
|||
|
||||
override fun getItemCount() = paths.size
|
||||
|
||||
override fun prepareActionMode(menu: Menu) {}
|
||||
override fun onBottomActionMenuCreated(view: BottomActionMenuView) {}
|
||||
|
||||
override fun actionItemPressed(id: Int) {}
|
||||
|
||||
|
@ -47,8 +47,6 @@ class FilepickerFavoritesAdapter(
|
|||
|
||||
override fun getItemSelectionKey(position: Int) = paths[position].hashCode()
|
||||
|
||||
override fun onActionModeCreated() {}
|
||||
|
||||
override fun onActionModeDestroyed() {}
|
||||
|
||||
private fun setupView(view: View, path: String) {
|
||||
|
|
|
@ -3,7 +3,6 @@ package com.simplemobiletools.commons.adapters
|
|||
import android.content.pm.PackageManager
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.util.TypedValue
|
||||
import android.view.Menu
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.bumptech.glide.Glide
|
||||
|
@ -19,6 +18,7 @@ import com.simplemobiletools.commons.extensions.*
|
|||
import com.simplemobiletools.commons.helpers.getFilePlaceholderDrawables
|
||||
import com.simplemobiletools.commons.models.FileDirItem
|
||||
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||
import com.simplemobiletools.commons.views.bottomactionmenu.BottomActionMenuView
|
||||
import kotlinx.android.synthetic.main.item_filepicker_list.view.*
|
||||
import java.util.*
|
||||
|
||||
|
@ -55,7 +55,7 @@ class FilepickerItemsAdapter(
|
|||
|
||||
override fun getItemCount() = fileDirItems.size
|
||||
|
||||
override fun prepareActionMode(menu: Menu) {}
|
||||
override fun onBottomActionMenuCreated(view: BottomActionMenuView) {}
|
||||
|
||||
override fun actionItemPressed(id: Int) {}
|
||||
|
||||
|
@ -67,8 +67,6 @@ class FilepickerItemsAdapter(
|
|||
|
||||
override fun getItemSelectionKey(position: Int) = fileDirItems[position].path.hashCode()
|
||||
|
||||
override fun onActionModeCreated() {}
|
||||
|
||||
override fun onActionModeDestroyed() {}
|
||||
|
||||
override fun onViewRecycled(holder: ViewHolder) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.simplemobiletools.commons.adapters
|
||||
|
||||
import android.view.Menu
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.simplemobiletools.commons.R
|
||||
|
@ -10,6 +9,7 @@ import com.simplemobiletools.commons.extensions.deleteBlockedNumber
|
|||
import com.simplemobiletools.commons.interfaces.RefreshRecyclerViewListener
|
||||
import com.simplemobiletools.commons.models.BlockedNumber
|
||||
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||
import com.simplemobiletools.commons.views.bottomactionmenu.BottomActionMenuView
|
||||
import kotlinx.android.synthetic.main.item_manage_blocked_number.view.*
|
||||
import java.util.*
|
||||
|
||||
|
@ -23,10 +23,8 @@ class ManageBlockedNumbersAdapter(
|
|||
|
||||
override fun getActionMenuId() = R.menu.cab_blocked_numbers
|
||||
|
||||
override fun prepareActionMode(menu: Menu) {
|
||||
menu.apply {
|
||||
findItem(R.id.cab_copy_number).isVisible = isOneItemSelected()
|
||||
}
|
||||
override fun onBottomActionMenuCreated(view: BottomActionMenuView) {
|
||||
view.toggleItemVisibility(R.id.cab_copy_number, isOneItemSelected())
|
||||
}
|
||||
|
||||
override fun actionItemPressed(id: Int) {
|
||||
|
@ -44,8 +42,6 @@ class ManageBlockedNumbersAdapter(
|
|||
|
||||
override fun getItemKeyPosition(key: Int) = blockedNumbers.indexOfFirst { it.id.toInt() == key }
|
||||
|
||||
override fun onActionModeCreated() {}
|
||||
|
||||
override fun onActionModeDestroyed() {}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = createViewHolder(R.layout.item_manage_blocked_number, parent)
|
||||
|
|
|
@ -16,6 +16,10 @@ import com.simplemobiletools.commons.extensions.getAdjustedPrimaryColor
|
|||
import com.simplemobiletools.commons.extensions.getContrastColor
|
||||
import com.simplemobiletools.commons.interfaces.MyActionModeCallback
|
||||
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||
import com.simplemobiletools.commons.views.bottomactionmenu.BottomActionMenuView
|
||||
import com.simplemobiletools.commons.views.bottomactionmenu.BottomActionMenuCallback
|
||||
import com.simplemobiletools.commons.views.bottomactionmenu.BottomActionMenuItem
|
||||
import com.simplemobiletools.commons.views.bottomactionmenu.BottomActionMenuPopup
|
||||
import java.util.*
|
||||
|
||||
abstract class MyRecyclerViewAdapter(val activity: BaseSimpleActivity, val recyclerView: MyRecyclerView, val itemClick: (Any) -> Unit) :
|
||||
|
@ -32,13 +36,15 @@ abstract class MyRecyclerViewAdapter(val activity: BaseSimpleActivity, val recyc
|
|||
protected var selectedKeys = LinkedHashSet<Int>()
|
||||
protected var positionOffset = 0
|
||||
protected var actMode: ActionMode? = null
|
||||
protected var contextCallback: BottomActionMenuCallback? = null
|
||||
protected var contextPopup: BottomActionMenuPopup? = null
|
||||
|
||||
private var actBarTextView: TextView? = null
|
||||
private var lastLongPressedItem = -1
|
||||
|
||||
abstract fun getActionMenuId(): Int
|
||||
|
||||
abstract fun prepareActionMode(menu: Menu)
|
||||
abstract fun onBottomActionMenuCreated(view: BottomActionMenuView)
|
||||
|
||||
abstract fun actionItemPressed(id: Int)
|
||||
|
||||
|
@ -50,24 +56,27 @@ abstract class MyRecyclerViewAdapter(val activity: BaseSimpleActivity, val recyc
|
|||
|
||||
abstract fun getItemKeyPosition(key: Int): Int
|
||||
|
||||
abstract fun onActionModeCreated()
|
||||
|
||||
abstract fun onActionModeDestroyed()
|
||||
|
||||
protected fun isOneItemSelected() = selectedKeys.size == 1
|
||||
|
||||
init {
|
||||
contextCallback = object : BottomActionMenuCallback {
|
||||
override fun onViewCreated(view: BottomActionMenuView) {
|
||||
onBottomActionMenuCreated(view)
|
||||
}
|
||||
|
||||
override fun onItemClicked(item: BottomActionMenuItem) {
|
||||
actionItemPressed(item.id)
|
||||
}
|
||||
}
|
||||
|
||||
actModeCallback = object : MyActionModeCallback() {
|
||||
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
|
||||
actionItemPressed(item.itemId)
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onCreateActionMode(actionMode: ActionMode, menu: Menu?): Boolean {
|
||||
if (getActionMenuId() == 0) {
|
||||
return true
|
||||
}
|
||||
|
||||
isSelectable = true
|
||||
actMode = actionMode
|
||||
actBarTextView = layoutInflater.inflate(R.layout.actionbar_title, null) as TextView
|
||||
|
@ -80,18 +89,16 @@ abstract class MyRecyclerViewAdapter(val activity: BaseSimpleActivity, val recyc
|
|||
selectAll()
|
||||
}
|
||||
}
|
||||
activity.menuInflater.inflate(getActionMenuId(), menu)
|
||||
onActionModeCreated()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onPrepareActionMode(actionMode: ActionMode, menu: Menu): Boolean {
|
||||
prepareActionMode(menu)
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onDestroyActionMode(actionMode: ActionMode) {
|
||||
isSelectable = false
|
||||
contextPopup?.dismiss()
|
||||
(selectedKeys.clone() as HashSet<Int>).forEach {
|
||||
val position = getItemKeyPosition(it)
|
||||
if (position != -1) {
|
||||
|
@ -143,6 +150,7 @@ abstract class MyRecyclerViewAdapter(val activity: BaseSimpleActivity, val recyc
|
|||
if (oldTitle != newTitle) {
|
||||
actBarTextView?.text = newTitle
|
||||
actMode?.invalidate()
|
||||
contextPopup?.invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,6 +337,7 @@ abstract class MyRecyclerViewAdapter(val activity: BaseSimpleActivity, val recyc
|
|||
val currentPosition = adapterPosition - positionOffset
|
||||
if (!actModeCallback.isSelectable) {
|
||||
activity.startSupportActionMode(actModeCallback)
|
||||
contextPopup = BottomActionMenuPopup(activity, getActionMenuId()).also { it.show(contextCallback) }
|
||||
}
|
||||
|
||||
toggleItemSelection(true, currentPosition, true)
|
||||
|
|
|
@ -18,6 +18,10 @@ import com.simplemobiletools.commons.extensions.getAdjustedPrimaryColor
|
|||
import com.simplemobiletools.commons.extensions.getContrastColor
|
||||
import com.simplemobiletools.commons.interfaces.MyActionModeCallback
|
||||
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||
import com.simplemobiletools.commons.views.bottomactionmenu.BottomActionMenuView
|
||||
import com.simplemobiletools.commons.views.bottomactionmenu.BottomActionMenuCallback
|
||||
import com.simplemobiletools.commons.views.bottomactionmenu.BottomActionMenuItem
|
||||
import com.simplemobiletools.commons.views.bottomactionmenu.BottomActionMenuPopup
|
||||
import java.util.*
|
||||
|
||||
abstract class MyRecyclerViewListAdapter<T>(
|
||||
|
@ -39,13 +43,15 @@ abstract class MyRecyclerViewListAdapter<T>(
|
|||
protected var selectedKeys = LinkedHashSet<Int>()
|
||||
protected var positionOffset = 0
|
||||
protected var actMode: ActionMode? = null
|
||||
protected var contextCallback: BottomActionMenuCallback? = null
|
||||
protected var contextPopup: BottomActionMenuPopup? = null
|
||||
|
||||
private var actBarTextView: TextView? = null
|
||||
private var lastLongPressedItem = -1
|
||||
|
||||
abstract fun getActionMenuId(): Int
|
||||
|
||||
abstract fun prepareActionMode(menu: Menu)
|
||||
abstract fun onBottomActionMenuCreated(view: BottomActionMenuView)
|
||||
|
||||
abstract fun actionItemPressed(id: Int)
|
||||
|
||||
|
@ -57,24 +63,27 @@ abstract class MyRecyclerViewListAdapter<T>(
|
|||
|
||||
abstract fun getItemKeyPosition(key: Int): Int
|
||||
|
||||
abstract fun onActionModeCreated()
|
||||
|
||||
abstract fun onActionModeDestroyed()
|
||||
|
||||
protected fun isOneItemSelected() = selectedKeys.size == 1
|
||||
|
||||
init {
|
||||
contextCallback = object : BottomActionMenuCallback {
|
||||
override fun onViewCreated(view: BottomActionMenuView) {
|
||||
onBottomActionMenuCreated(view)
|
||||
}
|
||||
|
||||
override fun onItemClicked(item: BottomActionMenuItem) {
|
||||
actionItemPressed(item.id)
|
||||
}
|
||||
}
|
||||
|
||||
actModeCallback = object : MyActionModeCallback() {
|
||||
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
|
||||
actionItemPressed(item.itemId)
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onCreateActionMode(actionMode: ActionMode, menu: Menu?): Boolean {
|
||||
if (getActionMenuId() == 0) {
|
||||
return true
|
||||
}
|
||||
|
||||
isSelectable = true
|
||||
actMode = actionMode
|
||||
actBarTextView = layoutInflater.inflate(R.layout.actionbar_title, null) as TextView
|
||||
|
@ -87,18 +96,16 @@ abstract class MyRecyclerViewListAdapter<T>(
|
|||
selectAll()
|
||||
}
|
||||
}
|
||||
activity.menuInflater.inflate(getActionMenuId(), menu)
|
||||
onActionModeCreated()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onPrepareActionMode(actionMode: ActionMode, menu: Menu): Boolean {
|
||||
prepareActionMode(menu)
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onDestroyActionMode(actionMode: ActionMode) {
|
||||
isSelectable = false
|
||||
contextPopup?.dismiss()
|
||||
(selectedKeys.clone() as HashSet<Int>).forEach {
|
||||
val position = getItemKeyPosition(it)
|
||||
if (position != -1) {
|
||||
|
@ -150,6 +157,7 @@ abstract class MyRecyclerViewListAdapter<T>(
|
|||
if (oldTitle != newTitle) {
|
||||
actBarTextView?.text = newTitle
|
||||
actMode?.invalidate()
|
||||
contextPopup?.invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -336,6 +344,7 @@ abstract class MyRecyclerViewListAdapter<T>(
|
|||
val currentPosition = adapterPosition - positionOffset
|
||||
if (!actModeCallback.isSelectable) {
|
||||
activity.startSupportActionMode(actModeCallback)
|
||||
contextPopup = BottomActionMenuPopup(activity, getActionMenuId()).also { it.show(contextCallback) }
|
||||
}
|
||||
|
||||
toggleItemSelection(true, currentPosition, true)
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package com.simplemobiletools.commons.views.bottomactionmenu
|
||||
|
||||
interface BottomActionMenuCallback {
|
||||
fun onItemClicked(item: BottomActionMenuItem){}
|
||||
fun onViewCreated(view: BottomActionMenuView){}
|
||||
fun onViewDestroyed(){}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.simplemobiletools.commons.views.bottomactionmenu
|
||||
|
||||
import android.view.View
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.IdRes
|
||||
|
||||
data class BottomActionMenuItem(
|
||||
@IdRes val id: Int,
|
||||
val title: String,
|
||||
@DrawableRes val icon: Int = View.NO_ID,
|
||||
val showAsAction: Boolean,
|
||||
val isVisible: Boolean = true,
|
||||
)
|
|
@ -0,0 +1,253 @@
|
|||
package com.simplemobiletools.commons.views.bottomactionmenu
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Rect
|
||||
import android.view.*
|
||||
import android.view.View.MeasureSpec
|
||||
import android.widget.*
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.widget.PopupWindowCompat
|
||||
import com.simplemobiletools.commons.R
|
||||
import com.simplemobiletools.commons.extensions.applyColorFilter
|
||||
import com.simplemobiletools.commons.extensions.getAdjustedPrimaryColor
|
||||
import com.simplemobiletools.commons.extensions.windowManager
|
||||
import com.simplemobiletools.commons.helpers.isRPlus
|
||||
import kotlinx.android.synthetic.main.item_action_mode_popup.view.*
|
||||
import kotlin.math.ceil
|
||||
|
||||
class BottomActionMenuItemPopup(
|
||||
private val context: Context,
|
||||
private val items: List<BottomActionMenuItem>,
|
||||
private val onSelect: (BottomActionMenuItem) -> Unit
|
||||
) {
|
||||
|
||||
private val popup = PopupWindow(context, null, android.R.attr.popupMenuStyle)
|
||||
private var anchorView: View? = null
|
||||
private var dropDownWidth = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
private var dropDownHeight = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
private var dropDownVerticalOffset: Int = 0
|
||||
private var dropDownHorizontalOffset: Int = 0
|
||||
private val tempRect = Rect()
|
||||
private val popupMinWidth: Int
|
||||
private val popupPaddingBottom: Int
|
||||
private val popupPaddingStart: Int
|
||||
private val popupPaddingEnd: Int
|
||||
private val popupPaddingTop: Int
|
||||
private val dropDownGravity: Int = Gravity.TOP or Gravity.END
|
||||
|
||||
private val popupListAdapter = object : ArrayAdapter<BottomActionMenuItem>(context, R.layout.item_action_mode_popup, items) {
|
||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
||||
var view = convertView
|
||||
if (view == null) {
|
||||
view = LayoutInflater.from(context).inflate(R.layout.item_action_mode_popup, parent, false)
|
||||
}
|
||||
val item = items[position]
|
||||
view!!.cab_item.text = item.title
|
||||
if (item.icon != View.NO_ID) {
|
||||
val icon = ContextCompat.getDrawable(context, item.icon)
|
||||
icon?.applyColorFilter(context.getAdjustedPrimaryColor())
|
||||
view.cab_item.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null)
|
||||
}
|
||||
view.setOnClickListener {
|
||||
onSelect.invoke(item)
|
||||
popup.dismiss()
|
||||
}
|
||||
return view
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
popup.isFocusable = true
|
||||
popupMinWidth = context.resources.getDimensionPixelSize(R.dimen.cab_popup_menu_min_width)
|
||||
popupPaddingStart = context.resources.getDimensionPixelSize(R.dimen.smaller_margin)
|
||||
popupPaddingEnd = context.resources.getDimensionPixelSize(R.dimen.smaller_margin)
|
||||
popupPaddingTop = context.resources.getDimensionPixelSize(R.dimen.smaller_margin)
|
||||
popupPaddingBottom = context.resources.getDimensionPixelSize(R.dimen.smaller_margin)
|
||||
}
|
||||
|
||||
fun show(anchorView: View) {
|
||||
this.anchorView = anchorView
|
||||
buildDropDown()
|
||||
PopupWindowCompat.setWindowLayoutType(popup, WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL)
|
||||
popup.isOutsideTouchable = true
|
||||
if (popup.isShowing) {
|
||||
popup.update(anchorView, dropDownHorizontalOffset, dropDownVerticalOffset, dropDownWidth, if (dropDownHeight < 0) -1 else dropDownHeight)
|
||||
} else {
|
||||
popup.width = dropDownWidth
|
||||
popup.height = dropDownHeight
|
||||
PopupWindowCompat.showAsDropDown(popup, anchorView, dropDownHorizontalOffset, dropDownVerticalOffset, dropDownGravity)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun dismiss() {
|
||||
popup.dismiss()
|
||||
popup.contentView = null
|
||||
}
|
||||
|
||||
internal fun setOnDismissListener(listener: (() -> Unit)?) {
|
||||
if (listener != null) {
|
||||
popup.setOnDismissListener { listener.invoke() }
|
||||
} else {
|
||||
popup.setOnDismissListener(null)
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildDropDown() {
|
||||
var otherHeights = 0
|
||||
val dropDownList = ListView(context).apply {
|
||||
adapter = popupListAdapter
|
||||
isFocusable = true
|
||||
divider = null
|
||||
isFocusableInTouchMode = true
|
||||
clipToPadding = false
|
||||
isVerticalScrollBarEnabled = false
|
||||
isHorizontalScrollBarEnabled = false
|
||||
clipToOutline = true
|
||||
setPaddingRelative(popupPaddingStart, popupPaddingTop, popupPaddingEnd, popupPaddingBottom)
|
||||
}
|
||||
|
||||
val screenWidth = if (isRPlus()) {
|
||||
context.windowManager.currentWindowMetrics.bounds.width()
|
||||
} else {
|
||||
context.windowManager.defaultDisplay.width
|
||||
}
|
||||
|
||||
val width = measureMenuSizeAndGetWidth((0.8 * screenWidth).toInt())
|
||||
updateContentWidth(width)
|
||||
popup.contentView = dropDownList
|
||||
|
||||
// getMaxAvailableHeight() subtracts the padding, so we put it back
|
||||
// to get the available height for the whole window.
|
||||
val padding: Int
|
||||
val popupBackground = popup.background
|
||||
if (popupBackground != null) {
|
||||
popupBackground.getPadding(tempRect)
|
||||
padding = tempRect.top + tempRect.bottom
|
||||
|
||||
// If we don't have an explicit vertical offset, determine one from
|
||||
// the window background so that content will line up.
|
||||
dropDownVerticalOffset -= tempRect.top
|
||||
} else {
|
||||
tempRect.setEmpty()
|
||||
padding = 0
|
||||
}
|
||||
|
||||
if ((dropDownGravity and Gravity.BOTTOM) == Gravity.BOTTOM) {
|
||||
dropDownVerticalOffset += anchorView!!.height
|
||||
}
|
||||
|
||||
val maxHeight = popup.getMaxAvailableHeight(anchorView!!, dropDownVerticalOffset)
|
||||
val listContent = measureHeightOfChildrenCompat(maxHeight - otherHeights)
|
||||
if (listContent > 0) {
|
||||
val listPadding = dropDownList.paddingTop + dropDownList.paddingBottom
|
||||
otherHeights += padding + listPadding
|
||||
}
|
||||
|
||||
dropDownHeight = listContent + otherHeights
|
||||
dropDownList.layoutParams = ViewGroup.LayoutParams(dropDownWidth, dropDownHeight)
|
||||
}
|
||||
|
||||
private fun updateContentWidth(width: Int) {
|
||||
val popupBackground = popup.background
|
||||
dropDownWidth = if (popupBackground != null) {
|
||||
popupBackground.getPadding(tempRect)
|
||||
tempRect.left + tempRect.right + width
|
||||
} else {
|
||||
width
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see androidx.appcompat.widget.DropDownListView.measureHeightOfChildrenCompat
|
||||
*/
|
||||
private fun measureHeightOfChildrenCompat(maxHeight: Int): Int {
|
||||
|
||||
val parent = FrameLayout(context)
|
||||
val widthMeasureSpec = MeasureSpec.makeMeasureSpec(dropDownWidth, MeasureSpec.EXACTLY)
|
||||
|
||||
// Include the padding of the list
|
||||
var returnedHeight = 0
|
||||
|
||||
val count = popupListAdapter.count
|
||||
|
||||
var child: View? = null
|
||||
var viewType = 0
|
||||
for (i in 0 until count) {
|
||||
val positionType = popupListAdapter.getItemViewType(i)
|
||||
if (positionType != viewType) {
|
||||
child = null
|
||||
viewType = positionType
|
||||
}
|
||||
child = popupListAdapter.getView(i, child, parent)
|
||||
|
||||
// Compute child height spec
|
||||
val heightMeasureSpec: Int
|
||||
var childLp: ViewGroup.LayoutParams? = child.layoutParams
|
||||
|
||||
if (childLp == null) {
|
||||
childLp = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
child.layoutParams = childLp
|
||||
}
|
||||
|
||||
heightMeasureSpec = if (childLp.height > 0) {
|
||||
MeasureSpec.makeMeasureSpec(
|
||||
childLp.height,
|
||||
MeasureSpec.EXACTLY
|
||||
)
|
||||
} else {
|
||||
MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
|
||||
}
|
||||
child.measure(widthMeasureSpec, heightMeasureSpec)
|
||||
// Since this view was measured directly against the parent measure
|
||||
// spec, we must measure it again before reuse.
|
||||
child.forceLayout()
|
||||
|
||||
val marginLayoutParams = childLp as? ViewGroup.MarginLayoutParams
|
||||
val topMargin = marginLayoutParams?.topMargin ?: 0
|
||||
val bottomMargin = marginLayoutParams?.bottomMargin ?: 0
|
||||
val verticalMargin = topMargin + bottomMargin
|
||||
|
||||
returnedHeight += child.measuredHeight + verticalMargin
|
||||
|
||||
if (returnedHeight >= maxHeight) {
|
||||
// We went over, figure out which height to return. If returnedHeight >
|
||||
// maxHeight, then the i'th position did not fit completely.
|
||||
return maxHeight
|
||||
}
|
||||
}
|
||||
|
||||
// At this point, we went through the range of children, and they each
|
||||
// completely fit, so return the returnedHeight
|
||||
return returnedHeight
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see androidx.appcompat.view.menu.MenuPopup.measureIndividualMenuWidth
|
||||
*/
|
||||
private fun measureMenuSizeAndGetWidth(maxAllowedWidth: Int): Int {
|
||||
val parent = FrameLayout(context)
|
||||
var maxWidth = popupMinWidth
|
||||
var itemView: View? = null
|
||||
var itemType = 0
|
||||
|
||||
val widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
|
||||
val heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
|
||||
for (i in 0 until popupListAdapter.count) {
|
||||
val positionType: Int = popupListAdapter.getItemViewType(i)
|
||||
if (positionType != itemType) {
|
||||
itemType = positionType
|
||||
itemView = null
|
||||
}
|
||||
itemView = popupListAdapter.getView(i, itemView, parent)
|
||||
itemView.measure(widthMeasureSpec, heightMeasureSpec)
|
||||
val itemWidth = itemView.measuredWidth
|
||||
if (itemWidth >= maxAllowedWidth) {
|
||||
return maxAllowedWidth
|
||||
} else if (itemWidth > maxWidth) {
|
||||
maxWidth = itemWidth
|
||||
}
|
||||
}
|
||||
return maxWidth
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package com.simplemobiletools.commons.views.bottomactionmenu
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.util.Xml
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import com.simplemobiletools.commons.R
|
||||
import org.xmlpull.v1.XmlPullParser
|
||||
|
||||
internal class BottomActionMenuParser(private val context: Context) {
|
||||
companion object {
|
||||
private const val NO_TEXT = ""
|
||||
private const val MENU_TAG = "menu"
|
||||
private const val MENU_ITEM_TAG = "item"
|
||||
}
|
||||
|
||||
fun inflate(menuId: Int): List<BottomActionMenuItem> {
|
||||
val parser = context.resources.getLayout(menuId)
|
||||
parser.use {
|
||||
val attrs = Xml.asAttributeSet(parser)
|
||||
return readContextItems(parser, attrs)
|
||||
}
|
||||
}
|
||||
|
||||
private fun readContextItems(parser: XmlPullParser, attrs: AttributeSet): List<BottomActionMenuItem> {
|
||||
val items = mutableListOf<BottomActionMenuItem>()
|
||||
var eventType = parser.eventType
|
||||
var tagName: String
|
||||
|
||||
// This loop will skip to the menu start tag
|
||||
do {
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
tagName = parser.name
|
||||
|
||||
if (tagName == MENU_TAG) {
|
||||
// Go to next tag
|
||||
eventType = parser.next()
|
||||
break
|
||||
}
|
||||
throw RuntimeException("Expecting menu, got $tagName")
|
||||
}
|
||||
eventType = parser.next()
|
||||
} while (eventType != XmlPullParser.END_DOCUMENT)
|
||||
|
||||
var reachedEndOfMenu = false
|
||||
while (!reachedEndOfMenu) {
|
||||
tagName = parser.name
|
||||
|
||||
if (eventType == XmlPullParser.END_TAG) {
|
||||
if (tagName == MENU_TAG) {
|
||||
reachedEndOfMenu = true
|
||||
}
|
||||
}
|
||||
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
when (tagName) {
|
||||
MENU_ITEM_TAG -> items.add(readBottomActionMenuItem(parser, attrs))
|
||||
}
|
||||
}
|
||||
|
||||
eventType = parser.next()
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
|
||||
private fun readBottomActionMenuItem(parser: XmlPullParser, attrs: AttributeSet): BottomActionMenuItem {
|
||||
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.BottomActionMenuItem)
|
||||
val id = typedArray.getResourceId(R.styleable.BottomActionMenuItem_android_id, View.NO_ID)
|
||||
val text = typedArray.getString(R.styleable.BottomActionMenuItem_android_title) ?: NO_TEXT
|
||||
val iconId = typedArray.getResourceId(R.styleable.BottomActionMenuItem_android_icon, View.NO_ID)
|
||||
val showAsAction = typedArray.getInt(R.styleable.BottomActionMenuItem_showAsAction, -1)
|
||||
val visible = typedArray.getBoolean(R.styleable.BottomActionMenuItem_android_visible, true)
|
||||
typedArray.recycle()
|
||||
parser.require(XmlPullParser.START_TAG, null, MENU_ITEM_TAG)
|
||||
return BottomActionMenuItem(id, text, iconId, showAsAction == MenuItem.SHOW_AS_ACTION_ALWAYS || showAsAction == MenuItem.SHOW_AS_ACTION_IF_ROOM, visible)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package com.simplemobiletools.commons.views.bottomactionmenu
|
||||
|
||||
import android.view.Gravity
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowManager
|
||||
import android.view.accessibility.AccessibilityEvent
|
||||
import android.widget.PopupWindow
|
||||
import androidx.annotation.MenuRes
|
||||
import androidx.core.widget.PopupWindowCompat
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
||||
|
||||
|
||||
class BottomActionMenuPopup(private val activity: BaseSimpleActivity, items: List<BottomActionMenuItem>) {
|
||||
private val bottomActionMenuView = BottomActionMenuView(activity)
|
||||
private val popup = PopupWindow(activity, null, android.R.attr.popupMenuStyle)
|
||||
private var floatingActionButton: FloatingActionButton? = null
|
||||
private var callback: BottomActionMenuCallback? = null
|
||||
|
||||
|
||||
constructor(activity: BaseSimpleActivity, @MenuRes menuResId: Int) : this(activity, BottomActionMenuParser(activity).inflate(menuResId))
|
||||
|
||||
init {
|
||||
popup.contentView = bottomActionMenuView
|
||||
popup.width = ViewGroup.LayoutParams.MATCH_PARENT
|
||||
popup.height = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
popup.isOutsideTouchable = false
|
||||
popup.setOnDismissListener {
|
||||
callback?.onViewDestroyed()
|
||||
floatingActionButton?.show()
|
||||
}
|
||||
PopupWindowCompat.setWindowLayoutType(popup, WindowManager.LayoutParams.TYPE_APPLICATION)
|
||||
bottomActionMenuView.setup(items)
|
||||
}
|
||||
|
||||
fun show(callback: BottomActionMenuCallback?, hideFab: Boolean = true) {
|
||||
this.callback = callback
|
||||
callback?.onViewCreated(bottomActionMenuView)
|
||||
if (hideFab) {
|
||||
floatingActionButton?.hide() ?: findFABAndHide()
|
||||
}
|
||||
bottomActionMenuView.setCallback(callback)
|
||||
bottomActionMenuView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED)
|
||||
popup.showAtLocation(bottomActionMenuView, Gravity.BOTTOM or Gravity.FILL_HORIZONTAL, 0, 0)
|
||||
bottomActionMenuView.show()
|
||||
}
|
||||
|
||||
fun dismiss() {
|
||||
popup.dismiss()
|
||||
}
|
||||
|
||||
private fun findFABAndHide() {
|
||||
val parent = activity.findViewById<ViewGroup>(android.R.id.content)
|
||||
findFab(parent)
|
||||
floatingActionButton?.hide()
|
||||
}
|
||||
|
||||
private fun findFab(parent: ViewGroup) {
|
||||
val count = parent.childCount
|
||||
for (i in 0 until count) {
|
||||
val child = parent.getChildAt(i)
|
||||
if (child is FloatingActionButton) {
|
||||
floatingActionButton = child
|
||||
break
|
||||
} else if (child is ViewGroup) {
|
||||
findFab(child)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun invalidate() {
|
||||
callback?.onViewCreated(bottomActionMenuView)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,228 @@
|
|||
package com.simplemobiletools.commons.views.bottomactionmenu
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.AnimatorListenerAdapter
|
||||
import android.animation.TimeInterpolator
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.util.TypedValue
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewPropertyAnimator
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.annotation.MenuRes
|
||||
import androidx.annotation.StringRes
|
||||
import com.google.android.material.animation.AnimationUtils
|
||||
import com.simplemobiletools.commons.R
|
||||
import com.simplemobiletools.commons.extensions.*
|
||||
import com.simplemobiletools.commons.helpers.isRPlus
|
||||
|
||||
|
||||
class BottomActionMenuView : LinearLayout {
|
||||
|
||||
companion object {
|
||||
private const val ENTER_ANIMATION_DURATION = 225
|
||||
private const val EXIT_ANIMATION_DURATION = 175
|
||||
}
|
||||
|
||||
constructor(context: Context) : super(context)
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle)
|
||||
|
||||
private val inflater = LayoutInflater.from(context)
|
||||
private val itemsLookup = LinkedHashMap<Int, BottomActionMenuItem>()
|
||||
private val items: List<BottomActionMenuItem>
|
||||
get() = itemsLookup.values.toList().sortedWith(compareByDescending<BottomActionMenuItem> { it.showAsAction }.thenBy { it.icon != View.NO_ID }).filter { it.isVisible }
|
||||
private var currentAnimator: ViewPropertyAnimator? = null
|
||||
private var callback: BottomActionMenuCallback? = null
|
||||
|
||||
init {
|
||||
orientation = HORIZONTAL
|
||||
elevation = 2f
|
||||
setDefaultHeight()
|
||||
}
|
||||
|
||||
private fun setDefaultHeight() {
|
||||
val typedValue = TypedValue()
|
||||
val defaultHeight = TypedValue.complexToDimensionPixelSize(typedValue.data, resources.displayMetrics)
|
||||
minimumHeight = defaultHeight
|
||||
}
|
||||
|
||||
fun setCallback(listener: BottomActionMenuCallback?) {
|
||||
this.callback = listener
|
||||
}
|
||||
|
||||
fun hide() {
|
||||
slideDownToGone()
|
||||
}
|
||||
|
||||
fun show() {
|
||||
slideUpToVisible()
|
||||
}
|
||||
|
||||
private fun slideUpToVisible() {
|
||||
currentAnimator?.also {
|
||||
it.cancel()
|
||||
clearAnimation()
|
||||
}
|
||||
animateChildTo(0, ENTER_ANIMATION_DURATION.toLong(), AnimationUtils.LINEAR_OUT_SLOW_IN_INTERPOLATOR, true)
|
||||
}
|
||||
|
||||
private fun slideDownToGone() {
|
||||
currentAnimator?.also {
|
||||
currentAnimator?.cancel()
|
||||
clearAnimation()
|
||||
}
|
||||
animateChildTo(
|
||||
height + (layoutParams as MarginLayoutParams).bottomMargin,
|
||||
EXIT_ANIMATION_DURATION.toLong(),
|
||||
AnimationUtils.FAST_OUT_LINEAR_IN_INTERPOLATOR
|
||||
)
|
||||
}
|
||||
|
||||
private fun animateChildTo(targetY: Int, duration: Long, interpolator: TimeInterpolator, visible: Boolean = false) {
|
||||
currentAnimator = animate()
|
||||
.translationY(targetY.toFloat())
|
||||
.setInterpolator(interpolator)
|
||||
.setDuration(duration)
|
||||
.setListener(
|
||||
object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
currentAnimator = null
|
||||
beVisibleIf(visible)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun createFromMenu(@MenuRes menuResId: Int) {
|
||||
if (menuResId != View.NO_ID) {
|
||||
val menuParser = BottomActionMenuParser(context)
|
||||
val items = menuParser.inflate(menuResId)
|
||||
setup(items)
|
||||
}
|
||||
}
|
||||
|
||||
fun setup(items: List<BottomActionMenuItem>) {
|
||||
items.forEach { itemsLookup[it.id] = it }
|
||||
init()
|
||||
}
|
||||
|
||||
fun add(item: BottomActionMenuItem) {
|
||||
setItem(item)
|
||||
}
|
||||
|
||||
fun setItemShowAsAction(@IdRes itemId: Int, showAsAction: Boolean) {
|
||||
val item = itemsLookup[itemId]
|
||||
setItem(item?.copy(showAsAction = showAsAction))
|
||||
}
|
||||
|
||||
fun changeItemIcon(@IdRes itemId: Int, @DrawableRes iconRes: Int) {
|
||||
val item = itemsLookup[itemId]
|
||||
setItem(item?.copy(icon = iconRes))
|
||||
}
|
||||
|
||||
fun changeItemTitle(@IdRes itemId: Int, @StringRes stringRes: Int) {
|
||||
changeItemTitle(itemId, context.getString(stringRes))
|
||||
}
|
||||
|
||||
fun changeItemTitle(@IdRes itemId: Int, title: String) {
|
||||
val item = itemsLookup[itemId]
|
||||
setItem(item?.copy(title = title))
|
||||
}
|
||||
|
||||
private fun setItem(item: BottomActionMenuItem?) {
|
||||
item?.let {
|
||||
itemsLookup[item.id] = item
|
||||
init()
|
||||
}
|
||||
}
|
||||
|
||||
fun toggleItemVisibility(@IdRes itemId: Int, show: Boolean) {
|
||||
val item = itemsLookup[itemId]
|
||||
setItem(item?.copy(isVisible = show))
|
||||
}
|
||||
|
||||
private fun init() {
|
||||
removeAllViews()
|
||||
val maxItemsBeforeOverflow = computeMaxItemsBeforeOverflow()
|
||||
val allItems = items
|
||||
for (i in allItems.indices) {
|
||||
if (i <= maxItemsBeforeOverflow) {
|
||||
drawNormalItem(allItems[i])
|
||||
} else {
|
||||
drawOverflowItem(allItems.slice(i until allItems.size))
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun computeMaxItemsBeforeOverflow(): Int {
|
||||
val itemsToShowAsAction = items.filter { it.showAsAction && it.icon != View.NO_ID }
|
||||
val itemMinWidth = context.resources.getDimensionPixelSize(R.dimen.cab_item_min_width)
|
||||
val totalActionWidth = (itemsToShowAsAction.size + 1) * itemMinWidth
|
||||
val screenWidth = if (isRPlus()) {
|
||||
context.windowManager.currentWindowMetrics.bounds.width()
|
||||
} else {
|
||||
context.windowManager.defaultDisplay.width
|
||||
}
|
||||
val result = if (screenWidth > totalActionWidth) {
|
||||
itemsToShowAsAction.size
|
||||
} else {
|
||||
screenWidth / itemMinWidth
|
||||
}
|
||||
return result - 1
|
||||
}
|
||||
|
||||
private fun drawNormalItem(item: BottomActionMenuItem) {
|
||||
(inflater.inflate(R.layout.item_action_mode, this, false) as ImageView).apply {
|
||||
setupItem(item)
|
||||
setOnClickListener {
|
||||
callback?.onItemClicked(item)
|
||||
}
|
||||
setOnLongClickListener {
|
||||
context.toast(item.title)
|
||||
true
|
||||
}
|
||||
addView(this)
|
||||
}
|
||||
}
|
||||
|
||||
private fun drawOverflowItem(overFlowItems: List<BottomActionMenuItem>) {
|
||||
(inflater.inflate(R.layout.item_action_mode, this, false) as ImageView).apply {
|
||||
setImageResource(R.drawable.ic_three_dots_vector)
|
||||
val contentDesc = context.getString(R.string.more_info)
|
||||
contentDescription = contentDesc
|
||||
applyColorFilter(context.getAdjustedPrimaryColor())
|
||||
val popup = getOverflowPopup(overFlowItems)
|
||||
setOnClickListener {
|
||||
popup.show(it)
|
||||
}
|
||||
setOnLongClickListener {
|
||||
context.toast(contentDesc)
|
||||
true
|
||||
}
|
||||
addView(this)
|
||||
}
|
||||
}
|
||||
|
||||
private fun ImageView.setupItem(item: BottomActionMenuItem) {
|
||||
id = item.id
|
||||
contentDescription = item.title
|
||||
if (item.icon != View.NO_ID) {
|
||||
setImageResource(item.icon)
|
||||
}
|
||||
beVisibleIf(item.isVisible)
|
||||
applyColorFilter(context.getAdjustedPrimaryColor())
|
||||
}
|
||||
|
||||
private fun getOverflowPopup(overFlowItems: List<BottomActionMenuItem>): BottomActionMenuItemPopup {
|
||||
return BottomActionMenuItemPopup(context, overFlowItems) {
|
||||
callback?.onItemClicked(it)
|
||||
}
|
||||
}
|
||||
}
|
12
commons/src/main/res/layout/item_action_mode.xml
Normal file
12
commons/src/main/res/layout/item_action_mode.xml
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@null"
|
||||
android:minWidth="@dimen/cab_item_min_width"
|
||||
android:padding="@dimen/normal_margin"
|
||||
tools:src="@drawable/ic_rename_vector"
|
||||
tools:tint="@color/color_primary" />
|
15
commons/src/main/res/layout/item_action_mode_popup.xml
Normal file
15
commons/src/main/res/layout/item_action_mode_popup.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.simplemobiletools.commons.views.MyTextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/cab_item"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/listChoiceBackgroundIndicator"
|
||||
android:contentDescription="@null"
|
||||
android:drawablePadding="@dimen/medium_margin"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="@dimen/normal_margin"
|
||||
android:textSize="@dimen/bigger_text_size"
|
||||
tools:drawableStart="@drawable/ic_rename_vector"
|
||||
tools:drawableTint="@color/color_primary"
|
||||
tools:text="@tools:sample/cities" />
|
10
commons/src/main/res/values/attrs.xml
Normal file
10
commons/src/main/res/values/attrs.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<declare-styleable name="BottomActionMenuItem">
|
||||
<attr name="android:id" />
|
||||
<attr name="android:title" />
|
||||
<attr name="android:icon" />
|
||||
<attr name="android:visible" />
|
||||
<attr name="showAsAction" />
|
||||
</declare-styleable>
|
||||
</resources>
|
|
@ -20,6 +20,8 @@
|
|||
<dimen name="colorpicker_color_width">70dp</dimen>
|
||||
|
||||
<dimen name="normal_icon_size">48dp</dimen>
|
||||
<dimen name="fastscroll_width">8dp</dimen>
|
||||
<dimen name="fastscroll_height">40dp</dimen>
|
||||
<dimen name="fingerprint_icon_size">72dp</dimen>
|
||||
<dimen name="fab_size">56dp</dimen>
|
||||
<dimen name="secondary_fab_bottom_margin">76dp</dimen>
|
||||
|
@ -48,4 +50,8 @@
|
|||
<dimen name="big_text_size">18sp</dimen>
|
||||
<dimen name="actionbar_text_size">20sp</dimen>
|
||||
<dimen name="extra_big_text_size">22sp</dimen>
|
||||
|
||||
<dimen name="cab_popup_menu_max_width">336dp</dimen>
|
||||
<dimen name="cab_popup_menu_min_width">168dp</dimen>
|
||||
<dimen name="cab_item_min_width">85dp</dimen>
|
||||
</resources>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.simplemobiletools.commons.samples.activities
|
||||
|
||||
import android.view.Menu
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
@ -15,6 +14,7 @@ import com.simplemobiletools.commons.interfaces.ItemTouchHelperContract
|
|||
import com.simplemobiletools.commons.interfaces.StartReorderDragListener
|
||||
import com.simplemobiletools.commons.samples.R
|
||||
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||
import com.simplemobiletools.commons.views.bottomactionmenu.BottomActionMenuView
|
||||
import kotlinx.android.synthetic.main.list_item.view.*
|
||||
import java.util.*
|
||||
|
||||
|
@ -41,7 +41,7 @@ class StringsAdapter(
|
|||
|
||||
override fun getActionMenuId() = R.menu.cab_delete_only
|
||||
|
||||
override fun prepareActionMode(menu: Menu) {}
|
||||
override fun onBottomActionMenuCreated(view: BottomActionMenuView) {}
|
||||
|
||||
override fun actionItemPressed(id: Int) {
|
||||
if (selectedKeys.isEmpty()) {
|
||||
|
@ -63,8 +63,6 @@ class StringsAdapter(
|
|||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = createViewHolder(R.layout.list_item, parent)
|
||||
|
||||
override fun onActionModeCreated() {}
|
||||
|
||||
override fun onActionModeDestroyed() {
|
||||
if (isChangingOrder) {
|
||||
notifyDataSetChanged()
|
||||
|
|
Loading…
Reference in a new issue