From 245791389eb09a56658d81e9894881584a712461 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Sat, 24 Jun 2017 00:16:08 -0700 Subject: Initialize searchview --- gradle.properties | 1 + library/build.gradle | 3 + .../kotlin/ca/allanwang/kau/kpref/KPrefBinder.kt | 12 ++- .../ca/allanwang/kau/kpref/items/KPrefPlainText.kt | 2 + .../ca/allanwang/kau/searchview/SearchItem.kt | 53 ++++++++++ .../ca/allanwang/kau/searchview/SearchView.kt | 97 ++++++++++++++++++ .../kotlin/ca/allanwang/kau/utils/ActivityUtils.kt | 4 +- .../kotlin/ca/allanwang/kau/utils/AnimUtils.kt | 26 +++++ .../kotlin/ca/allanwang/kau/utils/ContextUtils.kt | 7 +- .../kotlin/ca/allanwang/kau/utils/ViewUtils.kt | 8 ++ library/src/main/res/layout/kau_search_item.xml | 33 ++++++ library/src/main/res/layout/kau_search_view.xml | 112 +++++++++++++++++++++ library/src/main/res/values/dimens.xml | 3 + library/src/main/res/values/dimens_search.xml | 24 +++++ library/src/main/res/values/ids.xml | 1 + library/src/main/res/values/strings_commons.xml | 1 + library/src/main/res/values/styles.xml | 8 ++ .../kotlin/ca/allanwang/kau/sample/MainActivity.kt | 1 + sample/src/main/res/menu/menu_main.xml | 11 ++ 19 files changed, 402 insertions(+), 5 deletions(-) create mode 100644 library/src/main/kotlin/ca/allanwang/kau/searchview/SearchItem.kt create mode 100644 library/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt create mode 100644 library/src/main/res/layout/kau_search_item.xml create mode 100644 library/src/main/res/layout/kau_search_view.xml create mode 100644 library/src/main/res/values/dimens_search.xml create mode 100644 library/src/main/res/values/styles.xml diff --git a/gradle.properties b/gradle.properties index 9ca7d9e..504fd7a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -31,4 +31,5 @@ TIMBER=4.5.1 CONSTRAINT_LAYOUT=1.1.0-beta1 FAST_ADAPTER=2.6.2 FAST_ADAPTER_COMMONS=2.6.0 +ANKO=0.10.1 diff --git a/library/build.gradle b/library/build.gradle index 0f1282b..3498378 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -57,8 +57,11 @@ dependencies { compile "com.afollestad.material-dialogs:commons:${MATERIAL_DIALOG}" compile "com.mikepenz:iconics-core:${ICONICS}@aar" + compile "com.mikepenz:google-material-typeface:${IICON_GOOGLE}.original@aar" compile "com.jakewharton.timber:timber:${TIMBER}" + + compile "org.jetbrains.anko:anko-commons:${ANKO}" } // build a jar with source files diff --git a/library/src/main/kotlin/ca/allanwang/kau/kpref/KPrefBinder.kt b/library/src/main/kotlin/ca/allanwang/kau/kpref/KPrefBinder.kt index 89afaab..723af45 100644 --- a/library/src/main/kotlin/ca/allanwang/kau/kpref/KPrefBinder.kt +++ b/library/src/main/kotlin/ca/allanwang/kau/kpref/KPrefBinder.kt @@ -6,6 +6,8 @@ import android.support.v7.widget.RecyclerView import ca.allanwang.kau.R import ca.allanwang.kau.kpref.items.* import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter +import org.jetbrains.anko.doAsync +import org.jetbrains.anko.uiThread /** * Created by Allan Wang on 2017-06-08. @@ -21,10 +23,14 @@ fun RecyclerView.setKPrefAdapter(globalOptions: GlobalOptions, builder: KPrefAda layoutManager = LinearLayoutManager(context) val adapter = FastItemAdapter() adapter.withOnClickListener { v, _, item, _ -> item.onClick(v, v.findViewById(R.id.kau_pref_inner_content)) } - val items = KPrefAdapterBuilder(globalOptions) - builder.invoke(items) - adapter.add(items.list) this.adapter = adapter + doAsync { + val items = KPrefAdapterBuilder(globalOptions) + builder.invoke(items) + uiThread { + adapter.add(items.list) + } + } return adapter } diff --git a/library/src/main/kotlin/ca/allanwang/kau/kpref/items/KPrefPlainText.kt b/library/src/main/kotlin/ca/allanwang/kau/kpref/items/KPrefPlainText.kt index 9732b98..a782430 100644 --- a/library/src/main/kotlin/ca/allanwang/kau/kpref/items/KPrefPlainText.kt +++ b/library/src/main/kotlin/ca/allanwang/kau/kpref/items/KPrefPlainText.kt @@ -8,6 +8,8 @@ import ca.allanwang.kau.kpref.GlobalOptions * Created by Allan Wang on 2017-06-14. * * Just text with the core options. Extends base preference but has an empty getter and setter + * Useful replacement of [KPrefText] when nothing is displayed on the right side, + * and when the preference is completely handled by the click * */ class KPrefPlainText(val builder: KPrefPlainTextBuilder) : KPrefItemBase(builder) { diff --git a/library/src/main/kotlin/ca/allanwang/kau/searchview/SearchItem.kt b/library/src/main/kotlin/ca/allanwang/kau/searchview/SearchItem.kt new file mode 100644 index 0000000..0b36a5d --- /dev/null +++ b/library/src/main/kotlin/ca/allanwang/kau/searchview/SearchItem.kt @@ -0,0 +1,53 @@ +package ca.allanwang.kau.searchview + +import android.support.v7.widget.RecyclerView +import android.view.View +import android.widget.ImageView +import android.widget.TextView +import ca.allanwang.kau.R +import ca.allanwang.kau.utils.LazyResettable +import ca.allanwang.kau.utils.bindView +import com.mikepenz.fastadapter.items.AbstractItem + +/** + * Created by Allan Wang on 2017-06-23. + * + * A holder for each individual search item + * Contains a [key] which acts as a unique identifier (eg url) + * and a [content] which is displayed in the item + */ +class SearchItem(val key: String, val content: String = key) : AbstractItem() { + + companion object { + var foregroundColor: Int?=null + } + + override fun getLayoutRes(): Int = R.layout.kau_search_item + + override fun getType(): Int = R.id.kau_item_search + + override fun getViewHolder(v: View): ViewHolder = ViewHolder(v) + + override fun bindView(holder: ViewHolder, payloads: MutableList?) { + super.bindView(holder, payloads) + if (foregroundColor != null) { + holder.text.setTextColor(foregroundColor!!) + holder.icon.drawable.setTint(foregroundColor!!) + } + holder.text.text = content + } + + override fun unbindView(holder: ViewHolder) { + super.unbindView(holder) + holder.text.text = null + } + + class ViewHolder(v: View) : RecyclerView.ViewHolder(v) { + val icon: ImageView by bindView(R.id.search_icon) + val text: TextView by bindView(R.id.search_text) + + init { + + } + } +} \ No newline at end of file diff --git a/library/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt b/library/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt new file mode 100644 index 0000000..d786e13 --- /dev/null +++ b/library/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt @@ -0,0 +1,97 @@ +package ca.allanwang.kau.searchview + +import android.content.Context +import android.support.annotation.ColorInt +import android.support.annotation.IdRes +import android.support.v7.widget.CardView +import android.support.v7.widget.LinearLayoutManager +import android.support.v7.widget.RecyclerView +import android.util.AttributeSet +import android.view.Menu +import android.view.View +import android.widget.FrameLayout +import android.widget.ImageView +import android.widget.ProgressBar +import ca.allanwang.kau.R +import ca.allanwang.kau.utils.* +import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter +import com.mikepenz.google_material_typeface_library.GoogleMaterial +import com.mikepenz.iconics.typeface.IIcon + +/** + * Created by Allan Wang on 2017-06-23. + */ +class SearchView @JvmOverloads constructor( + context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 +) : FrameLayout(context, attrs, defStyleAttr) { + + //configs + var foregroundColor: Int = 0xddffffff.toInt() + set(value) { + if (field == value) return + field = value + tintForeground(value) + } + var navIcon: IIcon? = GoogleMaterial.Icon.gmd_arrow_back + set(value) { + field = value + iconNav.setIcon(value) + if (value == null) iconNav.gone() + } + var micIcon: IIcon? = GoogleMaterial.Icon.gmd_mic + set(value) { + field = value + iconMic.setIcon(value) + if (value == null) iconMic.gone() + } + var clearIcon: IIcon? = GoogleMaterial.Icon.gmd_clear + set(value) { + field = value + iconClear.setIcon(value) + if (value == null) iconClear.gone() + } + + //views + private val shadow: View by bindView(R.id.search_shadow) + private val card: CardView by bindView(R.id.search_shadow) + private val iconNav: ImageView by bindView(R.id.search_nav) + //TODO edittext + private val progress: ProgressBar by bindView(R.id.search_progress) + private val iconMic: ImageView by bindView(R.id.search_mic) + private val iconClear: ImageView by bindView(R.id.search_clear) + private val recycler: RecyclerView by bindView(R.id.search_recycler) + private val adapter = FastItemAdapter() + + init { + View.inflate(context, R.layout.kau_search_view, this) + iconNav.setIcon(navIcon) + iconMic.setIcon(micIcon) + iconClear.setIcon(clearIcon) + tintForeground(foregroundColor) + with(recycler) { + layoutManager = LinearLayoutManager(context) + addOnScrollListener(object : RecyclerView.OnScrollListener() { + override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { + super.onScrollStateChanged(recyclerView, newState) + if (newState == RecyclerView.SCROLL_STATE_DRAGGING) hideKeyboard() + } + }) + adapter = this@SearchView.adapter + } + } + + fun config(action: SearchView.() -> Unit) = action() + + fun bind(menu: Menu, @IdRes id: Int) { + val item = menu.findItem(id) + if (item.icon == null) item.icon = GoogleMaterial.Icon.gmd_search.toDrawable(context, 20) + gone() + } + + fun tintForeground(@ColorInt color: Int) { + iconNav.drawable.setTint(color) + iconMic.drawable.setTint(color) + iconClear.drawable.setTint(color) + SearchItem.foregroundColor = color + } +} \ No newline at end of file diff --git a/library/src/main/kotlin/ca/allanwang/kau/utils/ActivityUtils.kt b/library/src/main/kotlin/ca/allanwang/kau/utils/ActivityUtils.kt index c74a3ec..7a13685 100644 --- a/library/src/main/kotlin/ca/allanwang/kau/utils/ActivityUtils.kt +++ b/library/src/main/kotlin/ca/allanwang/kau/utils/ActivityUtils.kt @@ -53,4 +53,6 @@ fun Activity.setMenuIcons(menu: Menu, @ColorInt color: Int = Color.WHITE, vararg iicons.forEach { (id, iicon) -> menu.findItem(id).icon = iicon.toDrawable(this, sizeDp = 20, color = color) } -} \ No newline at end of file +} + +fun Activity.hideKeyboard() = currentFocus.hideKeyboard() \ No newline at end of file diff --git a/library/src/main/kotlin/ca/allanwang/kau/utils/AnimUtils.kt b/library/src/main/kotlin/ca/allanwang/kau/utils/AnimUtils.kt index d1e527e..3cf3309 100644 --- a/library/src/main/kotlin/ca/allanwang/kau/utils/AnimUtils.kt +++ b/library/src/main/kotlin/ca/allanwang/kau/utils/AnimUtils.kt @@ -67,6 +67,32 @@ fun View.circularReveal(x: Int = 0, y: Int = 0, offset: Long = 0L, radius: Float anim.start() } +fun View.circularHide(x: Int = 0, y: Int = 0, offset: Long = 0L, radius: Float = -1.0f, duration: Long = 500L, onStart: (() -> Unit)? = null, onFinish: (() -> Unit)? = null) { + if (!isAttachedToWindow) { + onStart?.invoke() + invisible() + onFinish?.invoke() + return + } + var r = radius + if (r < 0.0f) { + r = Math.max(Math.hypot(x.toDouble(), y.toDouble()), Math.hypot((width - x.toDouble()), (height - y.toDouble()))).toFloat() + } + val anim = ViewAnimationUtils.createCircularReveal(this, x, y, r, 0f).setDuration(duration) + anim.startDelay = offset + anim.addListener(object : AnimatorListenerAdapter() { + override fun onAnimationStart(animation: Animator?) = onStart?.invoke() ?: Unit + + override fun onAnimationEnd(animation: Animator?) { + invisible() + onFinish?.invoke() ?: Unit + } + + override fun onAnimationCancel(animation: Animator?) = onFinish?.invoke() ?: Unit + }) + anim.start() +} + fun View.fadeIn(offset: Long = 0L, duration: Long = 200L, onStart: (() -> Unit)? = null, onFinish: (() -> Unit)? = null) { if (!isAttachedToWindow) { onStart?.invoke() diff --git a/library/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt b/library/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt index 7597f80..31bff97 100644 --- a/library/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt +++ b/library/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt @@ -11,6 +11,8 @@ import android.support.annotation.* import android.support.v4.app.ActivityOptionsCompat import android.support.v4.content.ContextCompat import android.util.TypedValue +import android.view.View +import android.view.inputmethod.InputMethodManager import android.widget.Toast import ca.allanwang.kau.R import com.afollestad.materialdialogs.MaterialDialog @@ -121,4 +123,7 @@ val Context.isNetworkAvailable: Boolean return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting } -fun Context.getDip(value: Float): Float = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, resources.displayMetrics) \ No newline at end of file +fun Context.getDip(value: Float): Float = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, resources.displayMetrics) + +val Context.isRtl: Boolean + get() = resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_RTL diff --git a/library/src/main/kotlin/ca/allanwang/kau/utils/ViewUtils.kt b/library/src/main/kotlin/ca/allanwang/kau/utils/ViewUtils.kt index c64220c..4ec7a4e 100644 --- a/library/src/main/kotlin/ca/allanwang/kau/utils/ViewUtils.kt +++ b/library/src/main/kotlin/ca/allanwang/kau/utils/ViewUtils.kt @@ -1,11 +1,14 @@ package ca.allanwang.kau.utils +import android.app.Activity +import android.content.Context import android.graphics.Color import android.support.annotation.ColorInt import android.support.annotation.StringRes import android.support.design.widget.Snackbar import android.view.View import android.view.ViewGroup +import android.view.inputmethod.InputMethodManager import android.widget.FrameLayout import android.widget.ImageView import android.widget.TextView @@ -53,3 +56,8 @@ fun ImageView.setIcon(icon: IIcon?, sizeDp: Int = 24, @ColorInt color: Int = Col setImageDrawable(icon.toDrawable(context, sizeDp = sizeDp, color = color, builder = builder)) } +fun View.hideKeyboard() { + clearFocus() + (context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).hideSoftInputFromWindow(windowToken, 0) +} + diff --git a/library/src/main/res/layout/kau_search_item.xml b/library/src/main/res/layout/kau_search_item.xml new file mode 100644 index 0000000..fbdc826 --- /dev/null +++ b/library/src/main/res/layout/kau_search_item.xml @@ -0,0 +1,33 @@ + + + + + + + + \ No newline at end of file diff --git a/library/src/main/res/layout/kau_search_view.xml b/library/src/main/res/layout/kau_search_view.xml new file mode 100644 index 0000000..799d4df --- /dev/null +++ b/library/src/main/res/layout/kau_search_view.xml @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/library/src/main/res/values/dimens.xml b/library/src/main/res/values/dimens.xml index fddb6e3..0c0e749 100644 --- a/library/src/main/res/values/dimens.xml +++ b/library/src/main/res/values/dimens.xml @@ -13,4 +13,7 @@ 56dp 24dp + + 32dip + diff --git a/library/src/main/res/values/dimens_search.xml b/library/src/main/res/values/dimens_search.xml new file mode 100644 index 0000000..3664403 --- /dev/null +++ b/library/src/main/res/values/dimens_search.xml @@ -0,0 +1,24 @@ + + + + 46dp + + 8dp + 16dp + 1dp + + 24dp + 56dp + 56dp + 24dp + 14sp + 16sp + 24dp + + 4dp + 12dp + + 1dp + 2dp + + \ No newline at end of file diff --git a/library/src/main/res/values/ids.xml b/library/src/main/res/values/ids.xml index 54f01af..cda9faa 100644 --- a/library/src/main/res/values/ids.xml +++ b/library/src/main/res/values/ids.xml @@ -7,4 +7,5 @@ + \ No newline at end of file diff --git a/library/src/main/res/values/strings_commons.xml b/library/src/main/res/values/strings_commons.xml index 2673738..b37c1ea 100644 --- a/library/src/main/res/values/strings_commons.xml +++ b/library/src/main/res/values/strings_commons.xml @@ -49,4 +49,5 @@ Most resources are verbatim and x represents a formatted item %d minutes Warning Yes + Search diff --git a/library/src/main/res/values/styles.xml b/library/src/main/res/values/styles.xml new file mode 100644 index 0000000..c8e2197 --- /dev/null +++ b/library/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt b/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt index 2914824..a6f4b92 100644 --- a/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt +++ b/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt @@ -122,6 +122,7 @@ class MainActivity : KPrefActivity() { override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_main, menu) + return true } diff --git a/sample/src/main/res/menu/menu_main.xml b/sample/src/main/res/menu/menu_main.xml index dd07031..3bfc3d2 100644 --- a/sample/src/main/res/menu/menu_main.xml +++ b/sample/src/main/res/menu/menu_main.xml @@ -2,20 +2,31 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context="com.pitchedapps.myapplication.MainActivity"> + + + + + + -- cgit v1.2.3