Loading build.gradle +18 −15 Original line number Diff line number Diff line // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { ext { propBuildToolsVersion = '27.0.1' propCompileSdkVersion = 27 propMinSdkVersion = 16 propTargetSdkVersion = propCompileSdkVersion propVersionCode = 1 propVersionName = '2.41.4' kotlin_version = '1.1.60' support_libs = '27.0.1' } repositories { jcenter() maven { url 'https://maven.google.com' } google() } dependencies { classpath 'com.android.tools.build:gradle:3.0.0' classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } Loading @@ -17,7 +31,7 @@ buildscript { allprojects { repositories { jcenter() maven { url 'https://maven.google.com' } google() maven { url 'https://jitpack.io' } } } Loading @@ -25,14 +39,3 @@ allprojects { task clean(type: Delete) { delete rootProject.buildDir } ext { propBuildToolsVersion = '27.0.1' propCompileSdkVersion = 27 propMinSdkVersion = 16 propTargetSdkVersion = propCompileSdkVersion propVersionCode = 1 propVersionName = '2.37.12' kotlin_version = '1.1.51' support_libs = '27.0.0' } commons/build.gradle +4 −13 Original line number Diff line number Diff line apply plugin: 'com.android.library' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' android { compileSdkVersion propCompileSdkVersion Loading Loading @@ -32,21 +33,11 @@ dependencies { compile 'com.github.bumptech.glide:glide:4.3.1' compile 'com.booking:rtlviewpager:1.0.1' compile 'com.andrognito.patternlockview:patternlockview:1.0.0' compile 'com.github.ajalt.reprint:core:3.2.0@aar' compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile 'com.bignerdranch.android:recyclerview-multiselect:0.2' compile 'com.github.ajalt.reprint:core:3.2.0@aar' annotationProcessor 'com.github.bumptech.glide:compiler:4.2.0' } buildscript { repositories { mavenCentral() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version" } kapt 'com.github.bumptech.glide:compiler:4.3.1' } apply from: '../bintray-upload.gradle' commons/src/main/kotlin/com/simplemobiletools/commons/activities/BaseSimpleActivity.kt +16 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ import android.annotation.SuppressLint import android.annotation.TargetApi import android.app.Activity import android.content.Intent import android.content.res.Resources import android.graphics.Color import android.graphics.drawable.ColorDrawable import android.net.Uri Loading @@ -12,6 +13,9 @@ import android.provider.DocumentsContract import android.support.v4.app.ActivityCompat import android.support.v4.util.Pair import android.support.v7.app.AppCompatActivity import android.text.SpannableString import android.text.style.AbsoluteSizeSpan import android.view.Menu import android.view.MenuItem import com.simplemobiletools.commons.R import com.simplemobiletools.commons.asynctasks.CopyMoveTask Loading Loading @@ -75,6 +79,18 @@ open class BaseSimpleActivity : AppCompatActivity() { } } fun updateMenuTextSize(resources: Resources, menu: Menu) { val textSize = resources.getDimension(R.dimen.normal_text_size).toInt() (0 until menu.size()) .map { menu.getItem(it) } .forEach { SpannableString(it.title).apply { setSpan(AbsoluteSizeSpan(textSize, false), 0, length, 0) it.title = this } } } override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) { super.onActivityResult(requestCode, resultCode, resultData) if (requestCode == OPEN_DOCUMENT_TREE && resultCode == Activity.RESULT_OK && resultData != null) { Loading commons/src/main/kotlin/com/simplemobiletools/commons/activities/LicenseActivity.kt +5 −3 Original line number Diff line number Diff line Loading @@ -39,13 +39,13 @@ class LicenseActivity : BaseSimpleActivity() { } } fun getUnderlinedTitle(title: String): SpannableString { private fun getUnderlinedTitle(title: String): SpannableString { val underlined = SpannableString(title) underlined.setSpan(UnderlineSpan(), 0, title.length, 0) return underlined } fun initLicenses() = private fun initLicenses() = arrayOf( License(LICENSE_KOTLIN, R.string.kotlin_title, R.string.kotlin_text, R.string.kotlin_url), License(LICENSE_SUBSAMPLING, R.string.subsampling_title, R.string.subsampling_text, R.string.subsampling_url), Loading @@ -63,6 +63,8 @@ class LicenseActivity : BaseSimpleActivity() { License(LICENSE_GIF_DRAWABLE, R.string.gif_drawable_title, R.string.gif_drawable_text, R.string.gif_drawable_url), License(LICENSE_AUTOFITTEXTVIEW, R.string.autofittextview_title, R.string.autofittextview_text, R.string.autofittextview_url), License(LICENSE_ROBOLECTRIC, R.string.robolectric_title, R.string.robolectric_text, R.string.robolectric_url), License(LICENSE_ESPRESSO, R.string.espresso_title, R.string.espresso_text, R.string.espresso_url) License(LICENSE_ESPRESSO, R.string.espresso_title, R.string.espresso_text, R.string.espresso_url), License(LICENSE_GSON, R.string.gson_title, R.string.gson_text, R.string.gson_url), License(LICENSE_LEAK_CANARY, R.string.leak_canary_title, R.string.leakcanary_text, R.string.leakcanary_url) ) } commons/src/main/kotlin/com/simplemobiletools/commons/adapters/MyRecyclerViewAdapter.kt 0 → 100644 +237 −0 Original line number Diff line number Diff line package com.simplemobiletools.commons.adapters import android.support.v7.view.ActionMode import android.support.v7.widget.RecyclerView import android.util.SparseArray import android.view.Menu import android.view.MenuItem import android.view.View import android.view.ViewGroup import com.bignerdranch.android.multiselector.ModalMultiSelectorCallback import com.bignerdranch.android.multiselector.MultiSelector import com.bignerdranch.android.multiselector.SwappingHolder import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.extensions.baseConfig import com.simplemobiletools.commons.interfaces.MyAdapterListener import com.simplemobiletools.commons.views.MyRecyclerView import java.util.* abstract class MyRecyclerViewAdapter(val activity: BaseSimpleActivity, val recyclerView: MyRecyclerView, val itemClick: (Any) -> Unit) : RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder>() { val baseConfig = activity.baseConfig val resources = activity.resources!! var primaryColor = baseConfig.primaryColor var textColor = baseConfig.textColor var itemViews = SparseArray<View>() val selectedPositions = HashSet<Int>() var selectableItemCount = 0 private val multiSelector = MultiSelector() private var actMode: ActionMode? = null abstract fun getActionMenuId(): Int abstract fun prepareItemSelection(view: View) abstract fun markItemSelection(select: Boolean, view: View?) abstract fun prepareActionMode(menu: Menu) abstract fun actionItemPressed(id: Int) fun toggleItemSelection(select: Boolean, pos: Int) { if (select) { if (itemViews[pos] != null) { prepareItemSelection(itemViews[pos]) selectedPositions.add(pos) } } else { selectedPositions.remove(pos) } markItemSelection(select, itemViews[pos]) if (selectedPositions.isEmpty()) { finishActMode() return } updateTitle(selectedPositions.size) } private fun updateTitle(cnt: Int) { val selectedCount = Math.min(cnt, selectableItemCount) val oldTitle = actMode?.title val newTitle = "$selectedCount / $selectableItemCount" if (oldTitle != newTitle) { actMode?.title = newTitle actMode?.invalidate() } } fun selectAll() { val cnt = itemCount for (i in 0 until cnt) { selectedPositions.add(i) notifyItemChanged(i) } updateTitle(cnt) } fun setupDragListener(enable: Boolean) { if (enable) { recyclerView.setupDragListener(object : MyRecyclerView.MyDragListener { override fun selectItem(position: Int) { selectItemPosition(position) } override fun selectRange(initialSelection: Int, lastDraggedIndex: Int, minReached: Int, maxReached: Int) { selectItemRange(initialSelection, lastDraggedIndex, minReached, maxReached) } }) } else { recyclerView.setupDragListener(null) } } fun setupZoomListener(zoomListener: MyRecyclerView.MyZoomListener?) { recyclerView.setupZoomListener(zoomListener) } fun selectItemPosition(pos: Int) { toggleItemSelection(true, pos) } fun selectItemRange(from: Int, to: Int, min: Int, max: Int) { if (from == to) { (min..max).filter { it != from }.forEach { toggleItemSelection(false, it) } return } if (to < from) { for (i in to..from) { toggleItemSelection(true, i) } if (min > -1 && min < to) { (min until to).filter { it != from }.forEach { toggleItemSelection(false, it) } } if (max > -1) { for (i in from + 1..max) { toggleItemSelection(false, i) } } } else { for (i in from..to) { toggleItemSelection(true, i) } if (max > -1 && max > to) { (to + 1..max).filter { it != from }.forEach { toggleItemSelection(false, it) } } if (min > -1) { for (i in min until from) { toggleItemSelection(false, i) } } } } fun finishActMode() { actMode?.finish() } fun updateTextColor(textColor: Int) { this.textColor = textColor notifyDataSetChanged() } private val adapterListener = object : MyAdapterListener { override fun toggleItemSelectionAdapter(select: Boolean, position: Int) { toggleItemSelection(select, position) } override fun getSelectedPositions() = selectedPositions override fun itemLongClicked(position: Int) { recyclerView.setDragSelectActive(position) } } private val multiSelectorMode = object : ModalMultiSelectorCallback(multiSelector) { override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean { actionItemPressed(item.itemId) return true } override fun onCreateActionMode(actionMode: ActionMode?, menu: Menu?): Boolean { super.onCreateActionMode(actionMode, menu) actMode = actionMode activity.menuInflater.inflate(getActionMenuId(), menu) return true } override fun onPrepareActionMode(actionMode: ActionMode?, menu: Menu): Boolean { prepareActionMode(menu) return true } override fun onDestroyActionMode(actionMode: ActionMode?) { super.onDestroyActionMode(actionMode) selectedPositions.forEach { markItemSelection(false, itemViews[it]) } selectedPositions.clear() actMode?.title = "" actMode = null } } fun createViewHolder(layoutType: Int, parent: ViewGroup?): ViewHolder { val view = activity.layoutInflater.inflate(layoutType, parent, false) return ViewHolder(view, adapterListener, activity, multiSelectorMode, multiSelector, itemClick) } fun bindViewHolder(holder: MyRecyclerViewAdapter.ViewHolder, position: Int, view: View) { itemViews.put(position, view) toggleItemSelection(selectedPositions.contains(position), position) holder.itemView.tag = holder } class ViewHolder(view: View, val adapterListener: MyAdapterListener, val activity: BaseSimpleActivity, val multiSelectorCallback: ModalMultiSelectorCallback, val multiSelector: MultiSelector, val itemClick: (Any) -> (Unit)) : SwappingHolder(view, multiSelector) { fun bindView(any: Any, allowLongClick: Boolean = true, callback: (itemView: View) -> Unit): View { return itemView.apply { callback(this) if (isClickable) { setOnClickListener { viewClicked(any) } setOnLongClickListener { if (allowLongClick) viewLongClicked() else viewClicked(any); true } } else { setOnClickListener(null) setOnLongClickListener(null) } } } private fun viewClicked(any: Any) { if (multiSelector.isSelectable) { val isSelected = adapterListener.getSelectedPositions().contains(adapterPosition) adapterListener.toggleItemSelectionAdapter(!isSelected, adapterPosition) } else { itemClick(any) } } private fun viewLongClicked() { if (!multiSelector.isSelectable) { activity.startSupportActionMode(multiSelectorCallback) adapterListener.toggleItemSelectionAdapter(true, adapterPosition) } adapterListener.itemLongClicked(adapterPosition) } } } Loading
build.gradle +18 −15 Original line number Diff line number Diff line // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { ext { propBuildToolsVersion = '27.0.1' propCompileSdkVersion = 27 propMinSdkVersion = 16 propTargetSdkVersion = propCompileSdkVersion propVersionCode = 1 propVersionName = '2.41.4' kotlin_version = '1.1.60' support_libs = '27.0.1' } repositories { jcenter() maven { url 'https://maven.google.com' } google() } dependencies { classpath 'com.android.tools.build:gradle:3.0.0' classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } Loading @@ -17,7 +31,7 @@ buildscript { allprojects { repositories { jcenter() maven { url 'https://maven.google.com' } google() maven { url 'https://jitpack.io' } } } Loading @@ -25,14 +39,3 @@ allprojects { task clean(type: Delete) { delete rootProject.buildDir } ext { propBuildToolsVersion = '27.0.1' propCompileSdkVersion = 27 propMinSdkVersion = 16 propTargetSdkVersion = propCompileSdkVersion propVersionCode = 1 propVersionName = '2.37.12' kotlin_version = '1.1.51' support_libs = '27.0.0' }
commons/build.gradle +4 −13 Original line number Diff line number Diff line apply plugin: 'com.android.library' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' android { compileSdkVersion propCompileSdkVersion Loading Loading @@ -32,21 +33,11 @@ dependencies { compile 'com.github.bumptech.glide:glide:4.3.1' compile 'com.booking:rtlviewpager:1.0.1' compile 'com.andrognito.patternlockview:patternlockview:1.0.0' compile 'com.github.ajalt.reprint:core:3.2.0@aar' compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile 'com.bignerdranch.android:recyclerview-multiselect:0.2' compile 'com.github.ajalt.reprint:core:3.2.0@aar' annotationProcessor 'com.github.bumptech.glide:compiler:4.2.0' } buildscript { repositories { mavenCentral() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version" } kapt 'com.github.bumptech.glide:compiler:4.3.1' } apply from: '../bintray-upload.gradle'
commons/src/main/kotlin/com/simplemobiletools/commons/activities/BaseSimpleActivity.kt +16 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ import android.annotation.SuppressLint import android.annotation.TargetApi import android.app.Activity import android.content.Intent import android.content.res.Resources import android.graphics.Color import android.graphics.drawable.ColorDrawable import android.net.Uri Loading @@ -12,6 +13,9 @@ import android.provider.DocumentsContract import android.support.v4.app.ActivityCompat import android.support.v4.util.Pair import android.support.v7.app.AppCompatActivity import android.text.SpannableString import android.text.style.AbsoluteSizeSpan import android.view.Menu import android.view.MenuItem import com.simplemobiletools.commons.R import com.simplemobiletools.commons.asynctasks.CopyMoveTask Loading Loading @@ -75,6 +79,18 @@ open class BaseSimpleActivity : AppCompatActivity() { } } fun updateMenuTextSize(resources: Resources, menu: Menu) { val textSize = resources.getDimension(R.dimen.normal_text_size).toInt() (0 until menu.size()) .map { menu.getItem(it) } .forEach { SpannableString(it.title).apply { setSpan(AbsoluteSizeSpan(textSize, false), 0, length, 0) it.title = this } } } override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) { super.onActivityResult(requestCode, resultCode, resultData) if (requestCode == OPEN_DOCUMENT_TREE && resultCode == Activity.RESULT_OK && resultData != null) { Loading
commons/src/main/kotlin/com/simplemobiletools/commons/activities/LicenseActivity.kt +5 −3 Original line number Diff line number Diff line Loading @@ -39,13 +39,13 @@ class LicenseActivity : BaseSimpleActivity() { } } fun getUnderlinedTitle(title: String): SpannableString { private fun getUnderlinedTitle(title: String): SpannableString { val underlined = SpannableString(title) underlined.setSpan(UnderlineSpan(), 0, title.length, 0) return underlined } fun initLicenses() = private fun initLicenses() = arrayOf( License(LICENSE_KOTLIN, R.string.kotlin_title, R.string.kotlin_text, R.string.kotlin_url), License(LICENSE_SUBSAMPLING, R.string.subsampling_title, R.string.subsampling_text, R.string.subsampling_url), Loading @@ -63,6 +63,8 @@ class LicenseActivity : BaseSimpleActivity() { License(LICENSE_GIF_DRAWABLE, R.string.gif_drawable_title, R.string.gif_drawable_text, R.string.gif_drawable_url), License(LICENSE_AUTOFITTEXTVIEW, R.string.autofittextview_title, R.string.autofittextview_text, R.string.autofittextview_url), License(LICENSE_ROBOLECTRIC, R.string.robolectric_title, R.string.robolectric_text, R.string.robolectric_url), License(LICENSE_ESPRESSO, R.string.espresso_title, R.string.espresso_text, R.string.espresso_url) License(LICENSE_ESPRESSO, R.string.espresso_title, R.string.espresso_text, R.string.espresso_url), License(LICENSE_GSON, R.string.gson_title, R.string.gson_text, R.string.gson_url), License(LICENSE_LEAK_CANARY, R.string.leak_canary_title, R.string.leakcanary_text, R.string.leakcanary_url) ) }
commons/src/main/kotlin/com/simplemobiletools/commons/adapters/MyRecyclerViewAdapter.kt 0 → 100644 +237 −0 Original line number Diff line number Diff line package com.simplemobiletools.commons.adapters import android.support.v7.view.ActionMode import android.support.v7.widget.RecyclerView import android.util.SparseArray import android.view.Menu import android.view.MenuItem import android.view.View import android.view.ViewGroup import com.bignerdranch.android.multiselector.ModalMultiSelectorCallback import com.bignerdranch.android.multiselector.MultiSelector import com.bignerdranch.android.multiselector.SwappingHolder import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.extensions.baseConfig import com.simplemobiletools.commons.interfaces.MyAdapterListener import com.simplemobiletools.commons.views.MyRecyclerView import java.util.* abstract class MyRecyclerViewAdapter(val activity: BaseSimpleActivity, val recyclerView: MyRecyclerView, val itemClick: (Any) -> Unit) : RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder>() { val baseConfig = activity.baseConfig val resources = activity.resources!! var primaryColor = baseConfig.primaryColor var textColor = baseConfig.textColor var itemViews = SparseArray<View>() val selectedPositions = HashSet<Int>() var selectableItemCount = 0 private val multiSelector = MultiSelector() private var actMode: ActionMode? = null abstract fun getActionMenuId(): Int abstract fun prepareItemSelection(view: View) abstract fun markItemSelection(select: Boolean, view: View?) abstract fun prepareActionMode(menu: Menu) abstract fun actionItemPressed(id: Int) fun toggleItemSelection(select: Boolean, pos: Int) { if (select) { if (itemViews[pos] != null) { prepareItemSelection(itemViews[pos]) selectedPositions.add(pos) } } else { selectedPositions.remove(pos) } markItemSelection(select, itemViews[pos]) if (selectedPositions.isEmpty()) { finishActMode() return } updateTitle(selectedPositions.size) } private fun updateTitle(cnt: Int) { val selectedCount = Math.min(cnt, selectableItemCount) val oldTitle = actMode?.title val newTitle = "$selectedCount / $selectableItemCount" if (oldTitle != newTitle) { actMode?.title = newTitle actMode?.invalidate() } } fun selectAll() { val cnt = itemCount for (i in 0 until cnt) { selectedPositions.add(i) notifyItemChanged(i) } updateTitle(cnt) } fun setupDragListener(enable: Boolean) { if (enable) { recyclerView.setupDragListener(object : MyRecyclerView.MyDragListener { override fun selectItem(position: Int) { selectItemPosition(position) } override fun selectRange(initialSelection: Int, lastDraggedIndex: Int, minReached: Int, maxReached: Int) { selectItemRange(initialSelection, lastDraggedIndex, minReached, maxReached) } }) } else { recyclerView.setupDragListener(null) } } fun setupZoomListener(zoomListener: MyRecyclerView.MyZoomListener?) { recyclerView.setupZoomListener(zoomListener) } fun selectItemPosition(pos: Int) { toggleItemSelection(true, pos) } fun selectItemRange(from: Int, to: Int, min: Int, max: Int) { if (from == to) { (min..max).filter { it != from }.forEach { toggleItemSelection(false, it) } return } if (to < from) { for (i in to..from) { toggleItemSelection(true, i) } if (min > -1 && min < to) { (min until to).filter { it != from }.forEach { toggleItemSelection(false, it) } } if (max > -1) { for (i in from + 1..max) { toggleItemSelection(false, i) } } } else { for (i in from..to) { toggleItemSelection(true, i) } if (max > -1 && max > to) { (to + 1..max).filter { it != from }.forEach { toggleItemSelection(false, it) } } if (min > -1) { for (i in min until from) { toggleItemSelection(false, i) } } } } fun finishActMode() { actMode?.finish() } fun updateTextColor(textColor: Int) { this.textColor = textColor notifyDataSetChanged() } private val adapterListener = object : MyAdapterListener { override fun toggleItemSelectionAdapter(select: Boolean, position: Int) { toggleItemSelection(select, position) } override fun getSelectedPositions() = selectedPositions override fun itemLongClicked(position: Int) { recyclerView.setDragSelectActive(position) } } private val multiSelectorMode = object : ModalMultiSelectorCallback(multiSelector) { override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean { actionItemPressed(item.itemId) return true } override fun onCreateActionMode(actionMode: ActionMode?, menu: Menu?): Boolean { super.onCreateActionMode(actionMode, menu) actMode = actionMode activity.menuInflater.inflate(getActionMenuId(), menu) return true } override fun onPrepareActionMode(actionMode: ActionMode?, menu: Menu): Boolean { prepareActionMode(menu) return true } override fun onDestroyActionMode(actionMode: ActionMode?) { super.onDestroyActionMode(actionMode) selectedPositions.forEach { markItemSelection(false, itemViews[it]) } selectedPositions.clear() actMode?.title = "" actMode = null } } fun createViewHolder(layoutType: Int, parent: ViewGroup?): ViewHolder { val view = activity.layoutInflater.inflate(layoutType, parent, false) return ViewHolder(view, adapterListener, activity, multiSelectorMode, multiSelector, itemClick) } fun bindViewHolder(holder: MyRecyclerViewAdapter.ViewHolder, position: Int, view: View) { itemViews.put(position, view) toggleItemSelection(selectedPositions.contains(position), position) holder.itemView.tag = holder } class ViewHolder(view: View, val adapterListener: MyAdapterListener, val activity: BaseSimpleActivity, val multiSelectorCallback: ModalMultiSelectorCallback, val multiSelector: MultiSelector, val itemClick: (Any) -> (Unit)) : SwappingHolder(view, multiSelector) { fun bindView(any: Any, allowLongClick: Boolean = true, callback: (itemView: View) -> Unit): View { return itemView.apply { callback(this) if (isClickable) { setOnClickListener { viewClicked(any) } setOnLongClickListener { if (allowLongClick) viewLongClicked() else viewClicked(any); true } } else { setOnClickListener(null) setOnLongClickListener(null) } } } private fun viewClicked(any: Any) { if (multiSelector.isSelectable) { val isSelected = adapterListener.getSelectedPositions().contains(adapterPosition) adapterListener.toggleItemSelectionAdapter(!isSelected, adapterPosition) } else { itemClick(any) } } private fun viewLongClicked() { if (!multiSelector.isSelectable) { activity.startSupportActionMode(multiSelectorCallback) adapterListener.toggleItemSelectionAdapter(true, adapterPosition) } adapterListener.itemLongClicked(adapterPosition) } } }