From 94930e653fc318f2ddcabe45b96908c66943a0d4 Mon Sep 17 00:00:00 2001 From: tibbi Date: Wed, 23 Nov 2016 23:04:27 +0100 Subject: [PATCH] rewriting eventslist to recyclerview, initial version --- .../calendar/adapters/EventListAdapter.kt | 151 ++++++++++++++++++ .../calendar/adapters/EventsListAdapter.kt | 120 -------------- .../calendar/fragments/EventListFragment.kt | 74 ++------- .../main/res/layout/fragment_event_list.xml | 8 +- app/src/main/res/menu/cab_event_list.xml | 9 ++ 5 files changed, 177 insertions(+), 185 deletions(-) create mode 100644 app/src/main/kotlin/com/simplemobiletools/calendar/adapters/EventListAdapter.kt delete mode 100644 app/src/main/kotlin/com/simplemobiletools/calendar/adapters/EventsListAdapter.kt create mode 100644 app/src/main/res/menu/cab_event_list.xml diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/adapters/EventListAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/adapters/EventListAdapter.kt new file mode 100644 index 000000000..f77c4791f --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/adapters/EventListAdapter.kt @@ -0,0 +1,151 @@ +package com.simplemobiletools.calendar.adapters + +import android.graphics.drawable.Drawable +import android.support.v7.view.ActionMode +import android.support.v7.widget.RecyclerView +import android.view.* +import com.bignerdranch.android.multiselector.ModalMultiSelectorCallback +import com.bignerdranch.android.multiselector.MultiSelector +import com.bignerdranch.android.multiselector.SwappingHolder +import com.simplemobiletools.calendar.R +import com.simplemobiletools.calendar.activities.SimpleActivity +import com.simplemobiletools.calendar.helpers.Formatter +import com.simplemobiletools.calendar.models.ListEvent +import com.simplemobiletools.calendar.models.ListItem +import com.simplemobiletools.calendar.models.ListSection +import kotlinx.android.synthetic.main.event_item.view.* +import java.util.* + +class EventListAdapter(val activity: SimpleActivity, val mItems: List, val listener: EventListAdapter.ItemOperationsListener?, val itemClick: (ListItem) -> Unit) : + RecyclerView.Adapter() { + val multiSelector = MultiSelector() + val views = ArrayList() + + val ITEM_EVENT = 0 + val ITEM_HEADER = 1 + + companion object { + var actMode: ActionMode? = null + val markedItems = HashSet() + + var mTopDivider: Drawable? = null + var mNow = (System.currentTimeMillis() / 1000).toInt() + var mOrangeColor = 0 + var mGreyColor = 0 + var mTodayDate = "" + + fun toggleItemSelection(itemView: View, select: Boolean, pos: Int = -1) { + itemView.event_item_frame.isSelected = select + if (pos == -1) + return + + if (select) + markedItems.add(pos) + else + markedItems.remove(pos) + } + } + + init { + mTopDivider = activity.resources.getDrawable(R.drawable.divider) + mOrangeColor = activity.resources.getColor(R.color.colorPrimary) + val mTodayCode = Formatter.getDayCodeFromTS(mNow) + mTodayDate = Formatter.getEventDate(activity, mTodayCode) + } + + val multiSelectorMode = object : ModalMultiSelectorCallback(multiSelector) { + override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean { + return when (item.itemId) { + else -> false + } + } + + override fun onCreateActionMode(actionMode: ActionMode?, menu: Menu?): Boolean { + super.onCreateActionMode(actionMode, menu) + actMode = actionMode + activity.menuInflater.inflate(R.menu.cab_event_list, menu) + return true + } + + override fun onPrepareActionMode(actionMode: ActionMode?, menu: Menu) = true + + override fun onDestroyActionMode(actionMode: ActionMode?) { + super.onDestroyActionMode(actionMode) + views.forEach { toggleItemSelection(it, false) } + markedItems.clear() + } + } + + override fun getItemViewType(position: Int) = if (mItems[position] is ListEvent) ITEM_EVENT else ITEM_HEADER + + override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): RecyclerView.ViewHolder { + val layoutId = if (viewType == ITEM_EVENT) R.layout.event_list_item else R.layout.event_list_section + val view = LayoutInflater.from(parent?.context).inflate(layoutId, parent, false) + return if (viewType == ITEM_EVENT) + EventListAdapter.ViewHolder(activity, view, itemClick) + else + EventListAdapter.SectionHolder(view) + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + if (holder.itemViewType == ITEM_EVENT) + views.add((holder as ViewHolder).bindView(multiSelectorMode, multiSelector, mItems[position], position)) + else + (holder as SectionHolder).bindView(mItems[position]) + } + + override fun getItemCount() = mItems.size + + class ViewHolder(val activity: SimpleActivity, view: View, val itemClick: (ListItem) -> (Unit)) : SwappingHolder(view, MultiSelector()) { + fun bindView(multiSelectorCallback: ModalMultiSelectorCallback, multiSelector: MultiSelector, listItem: ListItem, pos: Int): View { + val item = listItem as ListEvent + itemView.apply { + event_item_title.text = item.title + event_item_description.text = item.description + event_item_start.text = Formatter.getTime(item.startTS) + + if (item.startTS == item.endTS) { + event_item_end.visibility = View.INVISIBLE + } else { + event_item_end.text = Formatter.getTime(item.endTS) + event_item_end.visibility = View.VISIBLE + + val startCode = Formatter.getDayCodeFromTS(item.startTS) + val endCode = Formatter.getDayCodeFromTS(item.endTS) + if (startCode != endCode) { + event_item_end.append(" (${Formatter.getEventDate(context, endCode)})") + } + } + + val currTextColor = if (item.startTS <= mNow) mOrangeColor else mGreyColor + event_item_start.setTextColor(currTextColor) + event_item_end.setTextColor(currTextColor) + event_item_title.setTextColor(currTextColor) + event_item_description.setTextColor(currTextColor) + } + + return itemView + } + } + + class SectionHolder(view: View) : RecyclerView.ViewHolder(view) { + fun bindView(listItem: ListItem): View { + val item = listItem as ListSection + itemView.apply { + event_item_title.text = item.title + event_item_title.setCompoundDrawablesWithIntrinsicBounds(null, if (position == 0) null else mTopDivider, null, null) + + if (mGreyColor == 0) + mGreyColor = event_item_title.currentTextColor + + event_item_title.setTextColor(if (item.title == mTodayDate) mOrangeColor else mGreyColor) + } + + return itemView + } + } + + interface ItemOperationsListener { + fun prepareForDeleting(ids: ArrayList) + } +} diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/adapters/EventsListAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/adapters/EventsListAdapter.kt deleted file mode 100644 index f83925c1b..000000000 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/adapters/EventsListAdapter.kt +++ /dev/null @@ -1,120 +0,0 @@ -package com.simplemobiletools.calendar.adapters - -import android.content.Context -import android.graphics.drawable.Drawable -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.BaseAdapter -import android.widget.TextView -import com.simplemobiletools.calendar.helpers.Formatter -import com.simplemobiletools.calendar.R -import com.simplemobiletools.calendar.models.ListEvent -import com.simplemobiletools.calendar.models.ListItem -import com.simplemobiletools.calendar.models.ListSection -import kotlinx.android.synthetic.main.event_item.view.* - -class EventsListAdapter(val context: Context, val mEvents: List) : BaseAdapter() { - val ITEM_EVENT = 0 - val ITEM_HEADER = 1 - - private val mInflater: LayoutInflater - private var mTopDivider: Drawable? = null - private var mNow = (System.currentTimeMillis() / 1000).toInt() - private var mOrangeColor = 0 - private var mGreyColor = 0 - private var mTodayDate = "" - - init { - mInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater - mTopDivider = context.resources.getDrawable(R.drawable.divider) - mOrangeColor = context.resources.getColor(R.color.colorPrimary) - val mTodayCode = Formatter.getDayCodeFromTS(mNow) - mTodayDate = Formatter.getEventDate(context, mTodayCode) - } - - override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { - var view = convertView - val viewHolder: ViewHolder - val type = getItemViewType(position) - - if (view == null) { - if (type == ITEM_EVENT) { - view = mInflater.inflate(R.layout.event_list_item, parent, false) - } else { - view = mInflater.inflate(R.layout.event_list_section, parent, false) - view.setOnClickListener(null) - } - viewHolder = ViewHolder(view) - view!!.tag = viewHolder - } else { - viewHolder = view.tag as ViewHolder - } - - if (type == ITEM_EVENT) { - val item = mEvents[position] as ListEvent - viewHolder.apply { - title.text = item.title - description?.text = item.description - start?.text = Formatter.getTime(item.startTS) - - if (item.startTS == item.endTS) { - end?.visibility = View.INVISIBLE - } else { - end?.text = Formatter.getTime(item.endTS) - end?.visibility = View.VISIBLE - - val startCode = Formatter.getDayCodeFromTS(item.startTS) - val endCode = Formatter.getDayCodeFromTS(item.endTS) - if (startCode != endCode) { - end?.append(" (${Formatter.getEventDate(context, endCode)})") - } - } - - val currTextColor = if (item.startTS <= mNow) mOrangeColor else mGreyColor - start?.setTextColor(currTextColor) - end?.setTextColor(currTextColor) - title.setTextColor(currTextColor) - description?.setTextColor(currTextColor) - } - } else { - val item = mEvents[position] as ListSection - viewHolder.title.text = item.title - viewHolder.title.setCompoundDrawablesWithIntrinsicBounds(null, if (position == 0) null else mTopDivider, null, null) - - if (mGreyColor == 0) - mGreyColor = viewHolder.title.currentTextColor - - viewHolder.title.setTextColor(if (item.title == mTodayDate) mOrangeColor else mGreyColor) - } - - return view - } - - override fun getItemViewType(position: Int): Int { - return if (mEvents[position] is ListEvent) ITEM_EVENT else ITEM_HEADER - } - - override fun getViewTypeCount(): Int { - return 2 - } - - override fun getCount(): Int { - return mEvents.size - } - - override fun getItem(position: Int): Any { - return mEvents[position] - } - - override fun getItemId(position: Int): Long { - return 0 - } - - internal class ViewHolder(view: View) { - val title = view.event_item_title - val description: TextView? = view.event_item_description - val start: TextView? = view.event_item_start - val end: TextView? = view.event_item_end - } -} diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/fragments/EventListFragment.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/fragments/EventListFragment.kt index 459aa5720..abebc0fd2 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/fragments/EventListFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/fragments/EventListFragment.kt @@ -3,15 +3,15 @@ package com.simplemobiletools.calendar.fragments import android.app.Activity import android.content.Intent import android.os.Bundle -import android.os.Parcelable import android.support.v4.app.Fragment -import android.view.* -import android.widget.AbsListView -import android.widget.AdapterView +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup import com.simplemobiletools.calendar.R import com.simplemobiletools.calendar.activities.EventActivity import com.simplemobiletools.calendar.activities.MainActivity -import com.simplemobiletools.calendar.adapters.EventsListAdapter +import com.simplemobiletools.calendar.activities.SimpleActivity +import com.simplemobiletools.calendar.adapters.EventListAdapter import com.simplemobiletools.calendar.extensions.beGoneIf import com.simplemobiletools.calendar.extensions.beVisibleIf import com.simplemobiletools.calendar.helpers.DBHelper @@ -27,13 +27,11 @@ import org.joda.time.DateTime import java.util.* import kotlin.comparisons.compareBy -class EventListFragment : Fragment(), DBHelper.GetEventsListener, AdapterView.OnItemClickListener, AbsListView.MultiChoiceModeListener, DBHelper.EventsListener { +class EventListFragment : Fragment(), DBHelper.GetEventsListener, DBHelper.EventsListener, EventListAdapter.ItemOperationsListener { private val EDIT_EVENT = 1 - var mSelectedItemsCnt = 0 var mListItems: ArrayList = ArrayList() var mAllEvents: MutableList? = null - var mState: Parcelable? = null lateinit var mToBeDeleted: MutableList lateinit var mView: View @@ -50,7 +48,6 @@ class EventListFragment : Fragment(), DBHelper.GetEventsListener, AdapterView.On override fun onPause() { super.onPause() - mState = mView.calendar_events_list.onSaveInstanceState() } private fun checkEvents() { @@ -75,15 +72,13 @@ class EventListFragment : Fragment(), DBHelper.GetEventsListener, AdapterView.On } mAllEvents = events - val eventsAdapter = EventsListAdapter(context, mListItems) + val eventsAdapter = EventListAdapter(activity as SimpleActivity, mListItems, this) { + /*(activity as MainActivity).checkDeleteEvents() + (mListItems[position] as ListEvent).id*/ + } activity?.runOnUiThread { mView.calendar_events_list.apply { - adapter = eventsAdapter - onItemClickListener = this@EventListFragment - setMultiChoiceModeListener(this@EventListFragment) - - if (mState != null) - onRestoreInstanceState(mState) + this@apply.adapter = eventsAdapter } checkPlaceholderVisibility() } @@ -97,20 +92,11 @@ class EventListFragment : Fragment(), DBHelper.GetEventsListener, AdapterView.On private fun getEventsToShow(events: MutableList?) = events?.filter { !mToBeDeleted.contains(it.id) } ?: ArrayList() - private fun prepareDeleteEvents() { - val checked = mView.calendar_events_list.checkedItemPositions - mListItems.indices.filter { checked.get(it) } - .map { mListItems[it] } - .forEach { mToBeDeleted.add((it as ListEvent).id) } - + override fun prepareForDeleting(ids: ArrayList) { + mToBeDeleted = ids notifyDeletion() } - override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { - (activity as MainActivity).checkDeleteEvents() - editEvent((mListItems[position] as ListEvent).id) - } - private fun editEvent(eventId: Int) { Intent(activity.applicationContext, EventActivity::class.java).apply { putExtra(EVENT_ID, eventId) @@ -148,40 +134,6 @@ class EventListFragment : Fragment(), DBHelper.GetEventsListener, AdapterView.On checkEvents() } - override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?) = true - - override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean { - return when (item.itemId) { - R.id.cab_delete -> { - prepareDeleteEvents() - mode.finish() - true - } - else -> false - } - } - - override fun onCreateActionMode(mode: ActionMode, menu: Menu?): Boolean { - val inflater = mode.menuInflater - inflater.inflate(R.menu.cab_day, menu) - return true - } - - override fun onDestroyActionMode(mode: ActionMode?) { - mSelectedItemsCnt = 0 - } - - override fun onItemCheckedStateChanged(mode: ActionMode, position: Int, id: Long, checked: Boolean) { - if (checked) { - mSelectedItemsCnt++ - } else { - mSelectedItemsCnt-- - } - - mode.title = mSelectedItemsCnt.toString() - mode.invalidate() - } - override fun eventInserted(event: Event) { checkEvents() } diff --git a/app/src/main/res/layout/fragment_event_list.xml b/app/src/main/res/layout/fragment_event_list.xml index a40cd7430..3bbf49351 100644 --- a/app/src/main/res/layout/fragment_event_list.xml +++ b/app/src/main/res/layout/fragment_event_list.xml @@ -1,20 +1,20 @@ - + android:visibility="gone" + app:layoutManager="android.support.v7.widget.LinearLayoutManager"/> + + +