package <%= appPackage %>.ui.base import android.support.annotation.LayoutRes import android.support.transition.TransitionManager import android.support.v7.widget.RecyclerView import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.AdapterView import android.widget.Filter import android.widget.Filterable import java.util.* abstract class BaseAdapter : RecyclerView.Adapter>(), Filterable { private var items: MutableList protected var originalItems: List private var mOnItemClickListener: AdapterView.OnItemClickListener? = null private var baseFilter: BaseFilter? = null protected var parent : ViewGroup? = null init { items = ArrayList() originalItems = ArrayList() } protected fun setItems(items: MutableList) { this.items = items } @LayoutRes protected abstract fun getLayoutForType(viewType: Int): Int override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val inflatedView = LayoutInflater.from(parent.context).inflate(getLayoutForType(viewType), parent, false) this.parent = parent return onCreateViewHolder(inflatedView, viewType) } protected abstract fun onCreateViewHolder(inflatedView: View, viewType: Int = 0): ViewHolder override fun onBindViewHolder(holder: ViewHolder, position: Int) { holder.bindItem(items[position], position) } fun getItem(position: Int): T? { return this.items[position] } override fun getFilter(): Filter { if (baseFilter == null){ originalItems = ArrayList(items) baseFilter = BaseFilter(this, originalItems) } return baseFilter as BaseFilter } protected fun getBaseFilter(): BaseFilter { if (baseFilter == null){ originalItems = ArrayList(items) baseFilter = BaseFilter(this, originalItems) } return baseFilter as BaseFilter } /** * @param item * * * @param position */ fun add(item: T?, position: Int) { if (item == null || position >= items.size || position == -1) { return } items.add(position, item) notifyItemInserted(position) notifyDataSetChanged() } /** * @param item */ fun add(item: T?) { if (item == null) { return } items.add(item) notifyItemInserted(items.size - 1) } /** * @param item */ fun remove(item: T?) { if (item == null) { return } val position = items.indexOf(item) items.remove(item) notifyItemRemoved(position) notifyDataSetChanged() } /** * @param items */ fun addAll(items: List?) { if (items == null) { return } val length = items.size val start = itemCount this.items.addAll(items) notifyItemRangeInserted(start, length) } /** * @param items */ fun replace(items: List?) { if (items == null) { this.items = ArrayList() } else { this.items = ArrayList(items) } notifyDataSetChanged() } fun clear() { this.items = ArrayList() notifyDataSetChanged() } override fun getItemCount(): Int { return items.size } fun setOnItemClickListener(onItemClickListener: AdapterView.OnItemClickListener) { mOnItemClickListener = onItemClickListener } private fun onItemHolderClick(itemHolder: ViewHolder) { if (mOnItemClickListener != null) { mOnItemClickListener?.onItemClick(null, itemHolder.itemView, itemHolder.adapterPosition, itemHolder.itemId) } } abstract class ViewHolder(root: View?, val adapter: BaseAdapter) : RecyclerView.ViewHolder(root), View.OnClickListener { init { root?.setOnClickListener(this) } abstract fun bindItem(value: T, position: Int) override fun onClick(v: View) { adapter.onItemHolderClick(this) } } inner class BaseFilter(val baseAdapter : BaseAdapter, val originalList : List) : Filter() { var filteredList : MutableList = mutableListOf() var filterExpression: ((predicate: T, filterPattern: String) -> Boolean )? = null override fun performFiltering(constraint: CharSequence?): FilterResults { filteredList.clear() val results = FilterResults() if(filterExpression == null) filterExpression = { predicate, filterPattern -> predicate.toString().contains(filterPattern) } if (constraint?.length == 0) { filteredList.addAll(originalList) } else { val filterPattern: String = constraint.toString().toLowerCase().trim() filteredList.addAll( originalList.filter { filterExpression?.invoke(it, filterPattern) ?: false } ) } results.values = filteredList results.count = filteredList.size return results } @Suppress("UNCHECKED_CAST") override fun publishResults(constraint: CharSequence?, results: FilterResults?) { baseAdapter.clear() baseAdapter.addAll(results?.values as ArrayList) } } interface OnItemClick { fun itemClick(item: T, position: Int) } }