diff options
Diffstat (limited to 'library')
16 files changed, 389 insertions, 5 deletions
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<KPrefItemCore>() 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<Unit>(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<SearchItem, SearchItem.ViewHolder>() { + + 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<Any>?) { + 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<SearchItem>() + + 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 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/linearLayout" + android:layout_width="match_parent" + android:layout_height="@dimen/kau_search_item_height" + android:background="?android:attr/selectableItemBackground" + android:clickable="true" + android:focusable="true" + android:gravity="start|center_vertical" + android:orientation="horizontal"> + + <ImageView + android:id="@+id/search_icon" + android:layout_width="@dimen/kau_search_icon" + android:layout_height="match_parent" + android:contentDescription="@string/kau_search" + android:scaleType="center" /> + + <TextView + android:id="@+id/search_text" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_gravity="start|center_vertical" + android:layout_weight="1" + android:ellipsize="end" + android:gravity="start|center_vertical" + android:maxLines="1" + android:paddingEnd="@dimen/kau_search_key_line_16" + android:paddingStart="@dimen/kau_search_key_line_8" + android:textIsSelectable="false" + android:textSize="@dimen/kau_search_text_small" /> + +</LinearLayout>
\ 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 @@ +<?xml version="1.0" encoding="utf-8"?> +<merge xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <View + android:id="@+id/search_shadow" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + + <android.support.v7.widget.CardView + android:id="@+id/search_cardview" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <LinearLayout + android:id="@+id/linearLayout" + android:layout_width="match_parent" + android:layout_height="@dimen/kau_search_height" + android:focusable="true" + android:focusableInTouchMode="true" + android:gravity="start|center_vertical" + android:orientation="horizontal"> + + <ImageView + android:id="@+id/search_nav" + android:layout_width="@dimen/kau_search_icon" + android:layout_height="match_parent" + android:background="?android:attr/selectableItemBackgroundBorderless" + android:clickable="true" + android:contentDescription="@string/kau_search" + android:focusable="true" + android:scaleType="centerInside" /> + + <com.lapism.searchview.SearchEditText + android:id="@+id/search_edit_text" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_gravity="start|center_vertical" + android:layout_weight="1" + android:background="@android:color/transparent" + android:ellipsize="end" + android:ems="10" + android:gravity="start|center_vertical" + android:imeOptions="actionSearch|flagNoExtractUi" + android:inputType="textNoSuggestions" + android:maxLines="1" + android:paddingEnd="@dimen/kau_search_key_line_16" + android:paddingStart="@dimen/kau_search_key_line_8" + android:privateImeOptions="nm" + android:textSize="@dimen/kau_search_text_medium" + android:windowSoftInputMode="stateAlwaysHidden" /> + + <ProgressBar + android:id="@+id/search_progress" + style="?android:attr/indeterminateProgressStyle" + android:layout_width="@dimen/kau_search_progress" + android:visibility="gone" + android:layout_height="match_parent" /> + + <FrameLayout + android:layout_width="48dp" + android:layout_height="match_parent"> + + <ImageView + android:id="@+id/search_mic" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="?android:attr/selectableItemBackgroundBorderless" + android:clickable="true" + android:contentDescription="@string/kau_search" + android:focusable="true" + android:visibility="gone" + android:scaleType="center" /> + + <ImageView + android:id="@+id/search_clear" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="?android:attr/selectableItemBackgroundBorderless" + android:clickable="true" + android:contentDescription="@string/kau_search" + android:focusable="true" + android:scaleType="center" /> + + </FrameLayout> + + </LinearLayout> + + <View + android:id="@+id/search_divider" + android:layout_width="match_parent" + android:layout_height="@dimen/kau_search_divider" + android:background="?android:attr/listDivider" /> + + <android.support.v7.widget.RecyclerView + android:id="@+id/search_recycler" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:overScrollMode="never" /> + + </LinearLayout> + + </android.support.v7.widget.CardView> + +</merge>
\ 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 @@ <dimen name="kau_color_circle_size">56dp</dimen> <dimen name="kau_status_bar_height">24dp</dimen> + + <dimen name="kau_search_dropdownitem_icon_width">32dip</dimen> + </resources> 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 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + <dimen name="kau_search_height">46dp</dimen> + + <dimen name="kau_search_key_line_8">8dp</dimen> + <dimen name="kau_search_key_line_16">16dp</dimen> + <dimen name="kau_search_divider">1dp</dimen> + + <dimen name="kau_search_item_margin_text">24dp</dimen> + <dimen name="kau_search_item_height">56dp</dimen> + <dimen name="kau_search_icon">56dp</dimen> + <dimen name="kau_search_progress">24dp</dimen> + <dimen name="kau_search_text_small">14sp</dimen> + <dimen name="kau_search_text_medium">16sp</dimen> + <dimen name="kau_search_reveal">24dp</dimen> + + <dimen name="kau_search_filter_margin_top">4dp</dimen> + <dimen name="kau_search_filter_margin_start">12dp</dimen> + + <dimen name="kau_search_menu_item_margin">1dp</dimen> + <dimen name="kau_search_menu_item_margin_left_right">2dp</dimen> + +</resources>
\ 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 @@ <item name="kau_item_pref_color_picker" type="id" /> <item name="kau_item_pref_sub_item" type="id" /> <item name="kau_item_pref_plain_text" type="id" /> + <item name="kau_item_search" type="id" /> </resources>
\ 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 <string name="kau_x_minutes">%d minutes</string> <string name="kau_warning">Warning</string> <string name="kau_yes">Yes</string> + <string name="kau_search">Search</string> </resources> 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 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + <style name="KauSearchView" parent="Widget.AppCompat.SearchView.ActionBar"> + + </style> + +</resources>
\ No newline at end of file |