allow drag selecting multiple events at the daily view
This commit is contained in:
parent
c2fe4d6bb0
commit
befacff4e4
|
@ -47,7 +47,7 @@ ext {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
compile 'com.simplemobiletools:commons:2.39.0'
|
||||
compile 'com.simplemobiletools:commons:2.39.3'
|
||||
compile 'joda-time:joda-time:2.9.9'
|
||||
compile 'com.facebook.stetho:stetho:1.5.0'
|
||||
compile 'com.bignerdranch.android:recyclerview-multiselect:0.2'
|
||||
|
|
|
@ -12,14 +12,19 @@ import com.simplemobiletools.calendar.models.Event
|
|||
import com.simplemobiletools.commons.extensions.applyColorFilter
|
||||
import com.simplemobiletools.commons.extensions.beInvisible
|
||||
import com.simplemobiletools.commons.extensions.beInvisibleIf
|
||||
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||
import kotlinx.android.synthetic.main.event_item_day_view.view.*
|
||||
|
||||
class DayEventsAdapter(activity: SimpleActivity, val events: List<Event>, val listener: DeleteEventsListener?, itemClick: (Any) -> Unit) :
|
||||
MyAdapter(activity, itemClick) {
|
||||
class DayEventsAdapter(activity: SimpleActivity, val events: List<Event>, val listener: DeleteEventsListener?, recyclerView: MyRecyclerView,
|
||||
itemClick: (Any) -> Unit) : MyAdapter(activity, itemClick) {
|
||||
|
||||
private var allDayString = resources.getString(R.string.all_day)
|
||||
private var replaceDescriptionWithLocation = config.replaceDescription
|
||||
|
||||
init {
|
||||
setDragListenerRecyclerView(recyclerView)
|
||||
}
|
||||
|
||||
override fun getActionMenuId() = R.menu.cab_day
|
||||
|
||||
override fun getSelectableItemCount() = events.size
|
||||
|
@ -47,13 +52,14 @@ class DayEventsAdapter(activity: SimpleActivity, val events: List<Event>, val li
|
|||
}
|
||||
itemViews.put(position, view)
|
||||
toggleItemSelection(selectedPositions.contains(position), position)
|
||||
holder.itemView.tag = holder
|
||||
}
|
||||
|
||||
override fun getItemCount() = events.size
|
||||
|
||||
private fun setupView(view: View, event: Event) {
|
||||
view.apply {
|
||||
event_item_title.text = event.title
|
||||
event_section_title.text = event.title
|
||||
event_item_description.text = if (replaceDescriptionWithLocation) event.location else event.description
|
||||
event_item_start.text = if (event.getIsAllDay()) allDayString else Formatter.getTimeFromTS(context, event.startTS)
|
||||
event_item_end.beInvisibleIf(event.startTS == event.endTS)
|
||||
|
@ -79,7 +85,7 @@ class DayEventsAdapter(activity: SimpleActivity, val events: List<Event>, val li
|
|||
|
||||
event_item_start.setTextColor(textColor)
|
||||
event_item_end.setTextColor(textColor)
|
||||
event_item_title.setTextColor(textColor)
|
||||
event_section_title.setTextColor(textColor)
|
||||
event_item_description.setTextColor(textColor)
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +96,6 @@ class DayEventsAdapter(activity: SimpleActivity, val events: List<Event>, val li
|
|||
eventIds.add(events[it].id)
|
||||
}
|
||||
activity.shareEvents(eventIds.distinct())
|
||||
finishActMode()
|
||||
}
|
||||
|
||||
private fun askConfirmDelete() {
|
||||
|
|
|
@ -70,7 +70,7 @@ class EventListAdapter(activity: SimpleActivity, val listItems: List<ListItem>,
|
|||
|
||||
private fun setupListEvent(view: View, listEvent: ListEvent) {
|
||||
view.apply {
|
||||
event_item_title.text = listEvent.title
|
||||
event_section_title.text = listEvent.title
|
||||
event_item_description.text = if (replaceDescriptionWithLocation) listEvent.location else listEvent.description
|
||||
event_item_start.text = if (listEvent.isAllDay) allDayString else Formatter.getTimeFromTS(context, listEvent.startTS)
|
||||
event_item_end.beInvisibleIf(listEvent.startTS == listEvent.endTS)
|
||||
|
@ -110,13 +110,13 @@ class EventListAdapter(activity: SimpleActivity, val listItems: List<ListItem>,
|
|||
|
||||
event_item_start.setTextColor(startTextColor)
|
||||
event_item_end.setTextColor(endTextColor)
|
||||
event_item_title.setTextColor(startTextColor)
|
||||
event_section_title.setTextColor(startTextColor)
|
||||
event_item_description.setTextColor(startTextColor)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupListSection(view: View, listSection: ListSection, position: Int) {
|
||||
view.event_item_title.apply {
|
||||
view.event_section_title.apply {
|
||||
text = listSection.title
|
||||
setCompoundDrawablesWithIntrinsicBounds(null, if (position == 0) null else topDivider, null, null)
|
||||
setTextColor(if (listSection.title == todayDate) primaryColor else textColor)
|
||||
|
|
|
@ -40,7 +40,7 @@ class EventListWidgetAdapter(val context: Context) : RemoteViewsService.RemoteVi
|
|||
if (type == ITEM_EVENT) {
|
||||
val item = events[position] as ListEvent
|
||||
remoteView = RemoteViews(context.packageName, R.layout.event_list_item_widget).apply {
|
||||
setText(R.id.event_item_title, item.title)
|
||||
setText(R.id.event_section_title, item.title)
|
||||
setText(R.id.event_item_description, if (replaceDescription) item.location else item.description)
|
||||
setText(R.id.event_item_start, if (item.isAllDay) allDayString else Formatter.getTimeFromTS(context, item.startTS))
|
||||
setImageViewBitmap(R.id.event_item_color, context.resources.getColoredBitmap(R.drawable.monthly_event_dot, item.color))
|
||||
|
@ -65,12 +65,12 @@ class EventListWidgetAdapter(val context: Context) : RemoteViewsService.RemoteVi
|
|||
setText(R.id.event_item_end, endString)
|
||||
}
|
||||
|
||||
setTextColor(R.id.event_item_title, textColor)
|
||||
setTextColor(R.id.event_section_title, textColor)
|
||||
setTextColor(R.id.event_item_description, textColor)
|
||||
setTextColor(R.id.event_item_start, textColor)
|
||||
setTextColor(R.id.event_item_end, textColor)
|
||||
|
||||
setTextSize(R.id.event_item_title, mediumFontSize)
|
||||
setTextSize(R.id.event_section_title, mediumFontSize)
|
||||
setTextSize(R.id.event_item_description, mediumFontSize)
|
||||
setTextSize(R.id.event_item_start, mediumFontSize)
|
||||
setTextSize(R.id.event_item_end, mediumFontSize)
|
||||
|
@ -84,9 +84,9 @@ class EventListWidgetAdapter(val context: Context) : RemoteViewsService.RemoteVi
|
|||
} else {
|
||||
val item = events[position] as ListSection
|
||||
remoteView = RemoteViews(context.packageName, R.layout.event_list_section_widget).apply {
|
||||
setTextColor(R.id.event_item_title, textColor)
|
||||
setTextSize(R.id.event_item_title, mediumFontSize)
|
||||
setText(R.id.event_item_title, item.title)
|
||||
setTextColor(R.id.event_section_title, textColor)
|
||||
setTextSize(R.id.event_section_title, mediumFontSize)
|
||||
setText(R.id.event_section_title, item.title)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ class EventListWidgetAdapterOld(val context: Context, val mEvents: List<ListItem
|
|||
override fun getItemId(position: Int) = 0L
|
||||
|
||||
internal class ViewHolder(view: View) {
|
||||
val title = view.event_item_title
|
||||
val title = view.event_section_title
|
||||
val description: TextView? = view.event_item_description
|
||||
val start: TextView? = view.event_item_start
|
||||
val end: TextView? = view.event_item_end
|
||||
|
|
|
@ -44,6 +44,8 @@ class FilterEventTypeAdapter(val activity: SimpleActivity, val eventTypes: List<
|
|||
}
|
||||
|
||||
override fun getSelectedPositions() = selectedPositions
|
||||
|
||||
override fun itemLongClicked(position: Int) {}
|
||||
}
|
||||
|
||||
fun getSelectedItemsSet(): HashSet<String> {
|
||||
|
|
|
@ -12,17 +12,20 @@ import com.bignerdranch.android.multiselector.SwappingHolder
|
|||
import com.simplemobiletools.calendar.activities.SimpleActivity
|
||||
import com.simplemobiletools.calendar.extensions.config
|
||||
import com.simplemobiletools.commons.interfaces.MyAdapterListener
|
||||
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||
import java.util.*
|
||||
|
||||
abstract class MyAdapter(val activity: SimpleActivity, val itemClick: (Any) -> Unit) : RecyclerView.Adapter<MyAdapter.ViewHolder>() {
|
||||
protected val config = activity.config
|
||||
protected val resources = activity.resources
|
||||
protected var actMode: ActionMode? = null
|
||||
protected val resources = activity.resources!!
|
||||
protected var primaryColor = config.primaryColor
|
||||
protected var textColor = config.textColor
|
||||
protected val itemViews = SparseArray<View>()
|
||||
protected val selectedPositions = HashSet<Int>()
|
||||
protected val multiSelector = MultiSelector()
|
||||
|
||||
private val multiSelector = MultiSelector()
|
||||
private var actMode: ActionMode? = null
|
||||
private var myRecyclerView: MyRecyclerView? = null
|
||||
|
||||
abstract fun getActionMenuId(): Int
|
||||
|
||||
|
@ -56,12 +59,74 @@ abstract class MyAdapter(val activity: SimpleActivity, val itemClick: (Any) -> U
|
|||
actMode?.invalidate()
|
||||
}
|
||||
|
||||
protected fun setDragListenerRecyclerView(recyclerView: MyRecyclerView) {
|
||||
myRecyclerView = recyclerView
|
||||
myRecyclerView!!.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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
private val adapterListener = object : MyAdapterListener {
|
||||
override fun toggleItemSelectionAdapter(select: Boolean, position: Int) {
|
||||
toggleItemSelection(select, position)
|
||||
}
|
||||
|
||||
override fun getSelectedPositions() = selectedPositions
|
||||
|
||||
override fun itemLongClicked(position: Int) {
|
||||
myRecyclerView?.setDragSelectActive(position)
|
||||
}
|
||||
}
|
||||
|
||||
private val multiSelectorMode = object : ModalMultiSelectorCallback(multiSelector) {
|
||||
|
@ -89,10 +154,6 @@ abstract class MyAdapter(val activity: SimpleActivity, val itemClick: (Any) -> U
|
|||
}
|
||||
}
|
||||
|
||||
fun finishActMode() {
|
||||
actMode?.finish()
|
||||
}
|
||||
|
||||
protected fun createViewHolder(view: View) = ViewHolder(view, adapterListener, activity, multiSelectorMode, multiSelector, itemClick)
|
||||
|
||||
class ViewHolder(view: View, val adapterListener: MyAdapterListener, val activity: SimpleActivity, val multiSelectorCallback: ModalMultiSelectorCallback,
|
||||
|
@ -100,8 +161,14 @@ abstract class MyAdapter(val activity: SimpleActivity, val itemClick: (Any) -> U
|
|||
fun bindView(any: Any, callback: (itemView: View) -> Unit): View {
|
||||
return itemView.apply {
|
||||
callback(this)
|
||||
itemView.setOnClickListener { viewClicked(any) }
|
||||
itemView.setOnLongClickListener { viewLongClicked(); true }
|
||||
|
||||
if (isClickable) {
|
||||
setOnClickListener { viewClicked(any) }
|
||||
setOnLongClickListener { viewLongClicked(); true }
|
||||
} else {
|
||||
setOnClickListener(null)
|
||||
setOnLongClickListener(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,6 +186,8 @@ abstract class MyAdapter(val activity: SimpleActivity, val itemClick: (Any) -> U
|
|||
activity.startSupportActionMode(multiSelectorCallback)
|
||||
adapterListener.toggleItemSelectionAdapter(true, adapterPosition)
|
||||
}
|
||||
|
||||
adapterListener.itemLongClicked(adapterPosition)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -138,7 +138,7 @@ class DayFragment : Fragment(), DBHelper.EventUpdateListener, DeleteEventsListen
|
|||
if (activity == null)
|
||||
return
|
||||
|
||||
val eventsAdapter = DayEventsAdapter(activity as SimpleActivity, events, this) {
|
||||
val eventsAdapter = DayEventsAdapter(activity as SimpleActivity, events, this, mHolder.day_events) {
|
||||
editEvent(it as Event)
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:foreground="@drawable/selector">
|
||||
|
||||
<RelativeLayout
|
||||
|
@ -31,7 +33,7 @@
|
|||
android:textSize="@dimen/day_text_size"/>
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/event_item_title"
|
||||
android:id="@+id/event_section_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/activity_margin"
|
||||
|
@ -47,7 +49,7 @@
|
|||
android:id="@+id/event_item_description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/event_item_title"
|
||||
android:layout_below="@+id/event_section_title"
|
||||
android:layout_marginLeft="@dimen/activity_margin"
|
||||
android:layout_toLeftOf="@+id/event_item_color"
|
||||
android:layout_toRightOf="@+id/event_item_end"
|
||||
|
@ -62,10 +64,10 @@
|
|||
android:id="@+id/event_item_color"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignBottom="@+id/event_item_title"
|
||||
android:layout_alignBottom="@+id/event_section_title"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignTop="@+id/event_item_title"
|
||||
android:layout_alignTop="@+id/event_section_title"
|
||||
android:paddingRight="@dimen/activity_margin"
|
||||
android:src="@drawable/monthly_event_dot"/>
|
||||
|
||||
|
|
|
@ -6,13 +6,14 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:foreground="@drawable/selector">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/event_item_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/selector"
|
||||
android:paddingBottom="@dimen/medium_margin"
|
||||
android:paddingLeft="@dimen/activity_margin"
|
||||
android:paddingRight="@dimen/activity_margin"
|
||||
|
@ -34,7 +35,7 @@
|
|||
android:textSize="@dimen/day_text_size"/>
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/event_item_title"
|
||||
android:id="@+id/event_section_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/activity_margin"
|
||||
|
@ -50,7 +51,7 @@
|
|||
android:id="@+id/event_item_description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/event_item_title"
|
||||
android:layout_below="@+id/event_section_title"
|
||||
android:layout_marginLeft="@dimen/activity_margin"
|
||||
android:layout_toLeftOf="@+id/event_item_color"
|
||||
android:layout_toRightOf="@+id/event_item_end"
|
||||
|
@ -65,10 +66,10 @@
|
|||
android:id="@+id/event_item_color"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignBottom="@+id/event_item_title"
|
||||
android:layout_alignBottom="@+id/event_section_title"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignTop="@+id/event_item_title"
|
||||
android:layout_alignTop="@+id/event_section_title"
|
||||
android:paddingRight="@dimen/medium_margin"
|
||||
android:src="@drawable/monthly_event_dot"/>
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
android:textSize="@dimen/day_text_size"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/event_item_title"
|
||||
android:id="@+id/event_section_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/big_margin"
|
||||
|
@ -40,7 +40,7 @@
|
|||
android:id="@+id/event_item_description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/event_item_title"
|
||||
android:layout_below="@+id/event_section_title"
|
||||
android:layout_marginLeft="@dimen/big_margin"
|
||||
android:layout_toLeftOf="@+id/event_item_color"
|
||||
android:layout_toRightOf="@+id/event_item_end"
|
||||
|
@ -55,10 +55,10 @@
|
|||
android:id="@+id/event_item_color"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignBottom="@+id/event_item_title"
|
||||
android:layout_alignBottom="@+id/event_section_title"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignTop="@+id/event_item_title"
|
||||
android:layout_alignTop="@+id/event_section_title"
|
||||
android:paddingRight="@dimen/activity_margin"
|
||||
android:src="@drawable/monthly_event_dot"/>
|
||||
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/event_item_title"
|
||||
android:id="@+id/event_section_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="false"
|
||||
android:drawablePadding="1dp"
|
||||
android:drawableTop="@drawable/divider_width"
|
||||
android:focusable="false"
|
||||
android:paddingTop="@dimen/medium_margin"
|
||||
android:textSize="@dimen/normal_text_size"
|
||||
android:textStyle="bold"/>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/event_item_title"
|
||||
android:id="@+id/event_section_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawablePadding="1dp"
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
<include layout="@layout/top_navigation"/>
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
<com.simplemobiletools.commons.views.MyRecyclerView
|
||||
android:id="@+id/day_events"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:foreground="@drawable/selector">
|
||||
|
||||
<RelativeLayout
|
||||
|
|
Loading…
Reference in New Issue