diff options
Diffstat (limited to 'searchview/src/main/kotlin/ca')
3 files changed, 151 insertions, 47 deletions
diff --git a/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchItem.kt b/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchItem.kt index 86ed83d..7d754c8 100644 --- a/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchItem.kt +++ b/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchItem.kt @@ -1,8 +1,22 @@ +/* + * Copyright 2018 Allan Wang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package ca.allanwang.kau.searchview import android.graphics.Typeface import android.graphics.drawable.Drawable -import androidx.recyclerview.widget.RecyclerView import android.text.Spannable import android.text.SpannableStringBuilder import android.text.style.StyleSpan @@ -10,8 +24,13 @@ import android.view.View import android.widget.ImageView import android.widget.TextView import androidx.constraintlayout.widget.ConstraintLayout +import androidx.recyclerview.widget.RecyclerView import ca.allanwang.kau.iitems.KauIItem -import ca.allanwang.kau.utils.* +import ca.allanwang.kau.utils.adjustAlpha +import ca.allanwang.kau.utils.gone +import ca.allanwang.kau.utils.setIcon +import ca.allanwang.kau.utils.setRippleBackground +import ca.allanwang.kau.utils.visible import com.mikepenz.google_material_typeface_library.GoogleMaterial import com.mikepenz.iconics.typeface.IIcon @@ -22,15 +41,16 @@ import com.mikepenz.iconics.typeface.IIcon * 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, - val description: String? = null, - val iicon: IIcon? = GoogleMaterial.Icon.gmd_search, - val image: Drawable? = null +class SearchItem( + val key: String, + val content: String = key, + val description: String? = null, + val iicon: IIcon? = GoogleMaterial.Icon.gmd_search, + val image: Drawable? = null ) : KauIItem<SearchItem, SearchItem.ViewHolder>( - R.layout.kau_search_iitem, - { ViewHolder(it) }, - R.id.kau_item_search + R.layout.kau_search_iitem, + { ViewHolder(it) }, + R.id.kau_item_search ) { companion object { @@ -48,7 +68,12 @@ class SearchItem(val key: String, val index = content.indexOf(subText, ignoreCase = true) if (index == -1) return styledContent = SpannableStringBuilder(content) - styledContent!!.setSpan(StyleSpan(Typeface.BOLD), index, index + subText.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) + styledContent!!.setSpan( + StyleSpan(Typeface.BOLD), + index, + index + subText.length, + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE + ) } override fun bindView(holder: ViewHolder, payloads: MutableList<Any>) { @@ -77,4 +102,4 @@ class SearchItem(val key: String, val desc: TextView = v.findViewById(R.id.kau_search_desc) val container: ConstraintLayout = v.findViewById(R.id.kau_search_item_frame) } -}
\ No newline at end of file +} diff --git a/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt b/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt index fecf6c5..11880cd 100644 --- a/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt +++ b/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt @@ -1,34 +1,72 @@ +/* + * Copyright 2018 Allan Wang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package ca.allanwang.kau.searchview import android.app.Activity import android.content.Context import android.content.res.ColorStateList import android.graphics.Color -import androidx.annotation.ColorInt -import androidx.annotation.IdRes -import androidx.transition.ChangeBounds -import androidx.transition.TransitionManager -import androidx.transition.TransitionSet -import androidx.recyclerview.widget.RecyclerView import android.text.Editable import android.text.TextWatcher import android.util.AttributeSet -import android.view.* +import android.view.Menu +import android.view.MenuItem +import android.view.View +import android.view.ViewGroup +import android.view.ViewTreeObserver import android.view.inputmethod.EditorInfo import android.widget.FrameLayout import android.widget.ImageView +import androidx.annotation.ColorInt +import androidx.annotation.IdRes +import androidx.recyclerview.widget.RecyclerView +import androidx.transition.ChangeBounds +import androidx.transition.TransitionManager +import androidx.transition.TransitionSet import ca.allanwang.kau.kotlin.Debouncer2 import ca.allanwang.kau.kotlin.debounce import ca.allanwang.kau.logging.KL import ca.allanwang.kau.searchview.SearchView.Configs -import ca.allanwang.kau.utils.* +import ca.allanwang.kau.utils.INVALID_ID +import ca.allanwang.kau.utils.addEndListener +import ca.allanwang.kau.utils.adjustAlpha +import ca.allanwang.kau.utils.circularHide +import ca.allanwang.kau.utils.circularReveal +import ca.allanwang.kau.utils.fadeIn +import ca.allanwang.kau.utils.fadeOut +import ca.allanwang.kau.utils.gone +import ca.allanwang.kau.utils.goneIf +import ca.allanwang.kau.utils.hideKeyboard +import ca.allanwang.kau.utils.invisibleIf +import ca.allanwang.kau.utils.isVisible +import ca.allanwang.kau.utils.parentViewGroup +import ca.allanwang.kau.utils.setIcon +import ca.allanwang.kau.utils.setMarginTop +import ca.allanwang.kau.utils.showKeyboard +import ca.allanwang.kau.utils.string +import ca.allanwang.kau.utils.tint +import ca.allanwang.kau.utils.toDrawable +import ca.allanwang.kau.utils.visible +import ca.allanwang.kau.utils.withLinearAdapter import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter import com.mikepenz.google_material_typeface_library.GoogleMaterial import com.mikepenz.iconics.typeface.IIcon import kotlinx.android.synthetic.main.kau_search_view.view.* import org.jetbrains.anko.runOnUiThread - /** * Created by Allan Wang on 2017-06-23. * @@ -41,7 +79,9 @@ import org.jetbrains.anko.runOnUiThread * https://github.com/lapism/SearchView */ class SearchView @JvmOverloads constructor( - context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 ) : FrameLayout(context, attrs, defStyleAttr) { /** @@ -162,13 +202,15 @@ class SearchView @JvmOverloads constructor( * Click event for suggestion items * This event is only triggered when [key] is not blank (like in [noResultsFound] */ - var onItemClick: (position: Int, key: String, content: String, searchView: SearchView) -> Unit = { _, _, _, _ -> } + var onItemClick: (position: Int, key: String, content: String, searchView: SearchView) -> Unit = + { _, _, _, _ -> } /** * Long click event for suggestion items * This event is only triggered when [key] is not blank (like in [noResultsFound] */ - var onItemLongClick: (position: Int, key: String, content: String, searchView: SearchView) -> Unit = { _, _, _, _ -> } + var onItemLongClick: (position: Int, key: String, content: String, searchView: SearchView) -> Unit = + { _, _, _, _ -> } /** * If a [SearchItem]'s title contains the submitted query, make that portion bold @@ -229,7 +271,8 @@ class SearchView @JvmOverloads constructor( private val configs = Configs() // views - private var textCallback: Debouncer2<String, SearchView> = debounce(0) { query, _ -> KL.d { "Search query $query found; set your own textCallback" } } + private var textCallback: Debouncer2<String, SearchView> = + debounce(0) { query, _ -> KL.d { "Search query $query found; set your own textCallback" } } private val adapter = FastItemAdapter<SearchItem>() private var menuItem: MenuItem? = null val isOpen: Boolean @@ -274,7 +317,12 @@ class SearchView @JvmOverloads constructor( if (item.key.isNotBlank()) configs.onItemClick(position, item.key, item.content, this@SearchView); true } withOnLongClickListener { _, _, item, position -> - if (item.key.isNotBlank()) configs.onItemLongClick(position, item.key, item.content, this@SearchView); true + if (item.key.isNotBlank()) configs.onItemLongClick( + position, + item.key, + item.content, + this@SearchView + ); true } } kau_search_edit_text.addTextChangedListener(object : TextWatcher { @@ -293,8 +341,11 @@ class SearchView @JvmOverloads constructor( }) kau_search_edit_text.setOnEditorActionListener { _, actionId, _ -> if (actionId == EditorInfo.IME_ACTION_SEARCH) { - if (configs.searchCallback(kau_search_edit_text.text?.toString() - ?: "", this)) revealClose() + if (configs.searchCallback( + kau_search_edit_text.text?.toString() + ?: "", this + ) + ) revealClose() else kau_search_edit_text.hideKeyboard() return@setOnEditorActionListener true } @@ -309,12 +360,12 @@ class SearchView @JvmOverloads constructor( internal fun cardTransition(builder: TransitionSet.() -> Unit = {}) { TransitionManager.beginDelayedTransition(kau_search_cardview, - //we are only using change bounds, as the recyclerview items may be animated as well, - //which causes a measure IllegalStateException - TransitionSet().addTransition(ChangeBounds()).apply { - duration = configs.transitionDuration - builder() - }) + //we are only using change bounds, as the recyclerview items may be animated as well, + //which causes a measure IllegalStateException + TransitionSet().addTransition(ChangeBounds()).apply { + duration = configs.transitionDuration + builder() + }) } /** @@ -330,10 +381,15 @@ class SearchView @JvmOverloads constructor( * This is assuming that SearchView has already been added to a ViewGroup * If not, see the extension function [bindSearchView] */ - fun bind(menu: Menu, @IdRes id: Int, @ColorInt menuIconColor: Int = Color.WHITE, config: Configs.() -> Unit = {}): SearchView { + fun bind( + menu: Menu, + @IdRes id: Int, + @ColorInt menuIconColor: Int = Color.WHITE, + config: Configs.() -> Unit = {} + ): SearchView { config(config) val menuItem = menu.findItem(id) - ?: throw IllegalArgumentException("Menu item with given id doesn't exist") + ?: throw IllegalArgumentException("Menu item with given id doesn't exist") if (menuItem.icon == null) menuItem.icon = GoogleMaterial.Icon.gmd_search.toDrawable(context, 18, menuIconColor) kau_search_cardview.gone() menuItem.setOnMenuItemClickListener { revealOpen(); true } @@ -430,17 +486,16 @@ class SearchView @JvmOverloads constructor( cardTransition { addEndListener { kau_search_cardview.circularHide(menuX, menuHalfHeight, duration = configs.revealDuration, - onFinish = { - configs.closeListener?.invoke(this@SearchView) - if (configs.shouldClearOnClose) kau_search_edit_text.text?.clear() - }) + onFinish = { + configs.closeListener?.invoke(this@SearchView) + if (configs.shouldClearOnClose) kau_search_edit_text.text?.clear() + }) } } kau_search_recycler.gone() kau_search_edit_text.hideKeyboard() } } - } @DslMarker @@ -450,7 +505,12 @@ annotation class KauSearch * Helper function that binds to an activity's main view */ @KauSearch -fun Activity.bindSearchView(menu: Menu, @IdRes id: Int, @ColorInt menuIconColor: Int = Color.WHITE, config: SearchView.Configs.() -> Unit = {}): SearchView = findViewById<ViewGroup>(android.R.id.content).bindSearchView(menu, id, menuIconColor, config) +fun Activity.bindSearchView( + menu: Menu, + @IdRes id: Int, + @ColorInt menuIconColor: Int = Color.WHITE, + config: SearchView.Configs.() -> Unit = {} +): SearchView = findViewById<ViewGroup>(android.R.id.content).bindSearchView(menu, id, menuIconColor, config) /** * Bind searchView to a menu item; call this in [Activity.onCreateOptionsMenu] @@ -458,11 +518,16 @@ fun Activity.bindSearchView(menu: Menu, @IdRes id: Int, @ColorInt menuIconColor: * it may be worthwhile to hold a reference to the searchview and only bind it if it hasn't been bound before */ @KauSearch -fun ViewGroup.bindSearchView(menu: Menu, @IdRes id: Int, @ColorInt menuIconColor: Int = Color.WHITE, config: SearchView.Configs.() -> Unit = {}): SearchView { +fun ViewGroup.bindSearchView( + menu: Menu, + @IdRes id: Int, + @ColorInt menuIconColor: Int = Color.WHITE, + config: SearchView.Configs.() -> Unit = {} +): SearchView { val searchView = SearchView(context) - searchView.layoutParams = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT) + searchView.layoutParams = + FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT) addView(searchView) searchView.bind(menu, id, menuIconColor, config) return searchView } - diff --git a/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchViewHolder.kt b/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchViewHolder.kt index 3f81dd0..a33b09b 100644 --- a/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchViewHolder.kt +++ b/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchViewHolder.kt @@ -1,3 +1,18 @@ +/* + * Copyright 2018 Allan Wang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package ca.allanwang.kau.searchview import android.view.MenuItem @@ -21,5 +36,4 @@ interface SearchViewHolder { searchView?.unBind(replacementMenuItemClickListener) searchView = null } - -}
\ No newline at end of file +} |