diff options
-rw-r--r-- | .travis.yml | 29 | ||||
-rw-r--r-- | library/src/main/kotlin/ca/allanwang/kau/kpref/KPrefActivity.kt | 2 | ||||
-rw-r--r-- | library/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt | 128 | ||||
-rw-r--r-- | library/src/main/res/layout/kau_activity_kpref.xml | 1 | ||||
-rw-r--r-- | library/src/main/res/layout/kau_search_view.xml | 15 | ||||
-rw-r--r-- | library/src/main/res/values/colors.xml | 3 | ||||
-rw-r--r-- | sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt | 3 |
7 files changed, 141 insertions, 40 deletions
diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..cc4bfda --- /dev/null +++ b/.travis.yml @@ -0,0 +1,29 @@ +language: android +android: + components: + - tools + - platform-tools + - build-tools-26.0.0 + - android-26 + - extra-google-m2repository + - extra-android-m2repository +jdk: + - oraclejdk8 +licenses: + - '.+' +script: ./gradlew clean test +branches: + except: + - gh-pages +notifications: + email: false + rooms: + - pitchedapps:G5OB9U1vsDxy9mxt0Nt6gbFu#kau + on_success: always + on_failure: always +sudo: false +cache: + directories: + - $HOME/.m2 +before_script: + - chmod +x gradlew
\ No newline at end of file diff --git a/library/src/main/kotlin/ca/allanwang/kau/kpref/KPrefActivity.kt b/library/src/main/kotlin/ca/allanwang/kau/kpref/KPrefActivity.kt index 8ec95ee..0c6b768 100644 --- a/library/src/main/kotlin/ca/allanwang/kau/kpref/KPrefActivity.kt +++ b/library/src/main/kotlin/ca/allanwang/kau/kpref/KPrefActivity.kt @@ -2,6 +2,7 @@ package ca.allanwang.kau.kpref import android.os.Bundle import android.support.annotation.StringRes +import android.support.constraint.ConstraintLayout import android.support.v4.widget.TextViewCompat import android.support.v7.app.AppCompatActivity import android.support.v7.widget.RecyclerView @@ -33,6 +34,7 @@ abstract class KPrefActivity : AppCompatActivity(), KPrefActivityContract { get() = recycler.adapter as FastItemAdapter<KPrefItemCore> val recycler: RecyclerView get() = prefHolder.currentView as RecyclerView + val container: ConstraintLayout by bindView(R.id.kau_container) val bgCanvas: RippleCanvas by bindView(R.id.kau_ripple) val toolbarCanvas: RippleCanvas by bindView(R.id.kau_toolbar_ripple) val toolbar: Toolbar by bindView(R.id.kau_toolbar) diff --git a/library/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt b/library/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt index d786e13..45274b8 100644 --- a/library/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt +++ b/library/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt @@ -3,12 +3,15 @@ package ca.allanwang.kau.searchview import android.content.Context import android.support.annotation.ColorInt import android.support.annotation.IdRes +import android.support.v7.widget.AppCompatEditText 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.MenuItem import android.view.View +import android.view.ViewGroup import android.widget.FrameLayout import android.widget.ImageView import android.widget.ProgressBar @@ -25,49 +28,73 @@ 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() + companion object { + fun bind(parent: ViewGroup, menu: Menu, @IdRes id: Int, config: Configs.() -> Unit = {}) { + SearchView(parent.context).apply { + layoutParams = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT) + parent.addView(this) + this.bind(parent, menu, id, config) + } } + } + //configs + inner class 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() + } + var revealDuration: Long = 700L + var shouldClearOnOpen: Boolean = true + var openListener: (() -> Unit)? = null + var closeListener: (() -> Unit)? = null + } + + val configs = Configs() //views private val shadow: View by bindView(R.id.search_shadow) - private val card: CardView by bindView(R.id.search_shadow) + private val card: CardView by bindView(R.id.search_cardview) private val iconNav: ImageView by bindView(R.id.search_nav) - //TODO edittext + private val editText: AppCompatEditText by bindView(R.id.search_edit_text) 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>() + private lateinit var parent: ViewGroup + val isOpen: Boolean + get() = card.isVisible() + + //menu view + private var revealX: Int = -1 + private var revealY: Int = -1 init { View.inflate(context, R.layout.kau_search_view, this) - iconNav.setIcon(navIcon) - iconMic.setIcon(micIcon) - iconClear.setIcon(clearIcon) - tintForeground(foregroundColor) + iconNav.setIcon(configs.navIcon) + iconMic.setIcon(configs.micIcon) + iconClear.setIcon(configs.clearIcon) + tintForeground(configs.foregroundColor) with(recycler) { layoutManager = LinearLayoutManager(context) addOnScrollListener(object : RecyclerView.OnScrollListener() { @@ -80,12 +107,26 @@ class SearchView @JvmOverloads constructor( } } - fun config(action: SearchView.() -> Unit) = action() + fun config(config: Configs.() -> Unit) { + configs.config() + } - fun bind(menu: Menu, @IdRes id: Int) { + fun bind(parent: ViewGroup, menu: Menu, @IdRes id: Int, config: Configs.() -> Unit = {}) { + config(config) + this.parent = parent val item = menu.findItem(id) if (item.icon == null) item.icon = GoogleMaterial.Icon.gmd_search.toDrawable(context, 20) gone() + item.setOnMenuItemClickListener { getMenuItemCoords(it); revealOpen(); true } + shadow.setOnClickListener { revealClose() } + } + + fun getMenuItemCoords(item: MenuItem) { + val view = parent.findViewById<View>(item.itemId) ?: return + val locations = IntArray(2) + view.getLocationOnScreen(locations) + revealX = locations[0] + revealY = locations[1] } fun tintForeground(@ColorInt color: Int) { @@ -94,4 +135,27 @@ class SearchView @JvmOverloads constructor( iconClear.drawable.setTint(color) SearchItem.foregroundColor = color } + + fun revealOpen() { + if (isOpen) return + card.circularReveal(revealX, revealY, duration = configs.revealDuration, + onStart = { + configs.openListener?.invoke() + if (configs.shouldClearOnOpen) editText.text.clear() + }, + onFinish = { + editText.requestFocus() + shadow.fadeIn() + }) + } + + fun revealClose() { + if (!isOpen) return + shadow.fadeOut() { + card.circularHide(revealX, revealY, duration = configs.revealDuration, + onFinish = { + configs.closeListener?.invoke() + }) + } + } }
\ No newline at end of file diff --git a/library/src/main/res/layout/kau_activity_kpref.xml b/library/src/main/res/layout/kau_activity_kpref.xml index acc1f76..856f168 100644 --- a/library/src/main/res/layout/kau_activity_kpref.xml +++ b/library/src/main/res/layout/kau_activity_kpref.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" + android:id="@+id/kau_container" android:layout_width="match_parent" android:layout_height="match_parent"> diff --git a/library/src/main/res/layout/kau_search_view.xml b/library/src/main/res/layout/kau_search_view.xml index 799d4df..72cfd02 100644 --- a/library/src/main/res/layout/kau_search_view.xml +++ b/library/src/main/res/layout/kau_search_view.xml @@ -1,13 +1,14 @@ <?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:layout_height="match_parent" + android:background="@color/kau_search_full_shadow" + android:visibility="gone" /> <android.support.v7.widget.CardView android:id="@+id/search_cardview" @@ -38,7 +39,7 @@ android:focusable="true" android:scaleType="centerInside" /> - <com.lapism.searchview.SearchEditText + <android.support.v7.widget.AppCompatEditText android:id="@+id/search_edit_text" android:layout_width="0dp" android:layout_height="match_parent" @@ -61,8 +62,8 @@ android:id="@+id/search_progress" style="?android:attr/indeterminateProgressStyle" android:layout_width="@dimen/kau_search_progress" - android:visibility="gone" - android:layout_height="match_parent" /> + android:layout_height="match_parent" + android:visibility="gone" /> <FrameLayout android:layout_width="48dp" @@ -76,8 +77,8 @@ android:clickable="true" android:contentDescription="@string/kau_search" android:focusable="true" - android:visibility="gone" - android:scaleType="center" /> + android:scaleType="center" + android:visibility="gone" /> <ImageView android:id="@+id/search_clear" diff --git a/library/src/main/res/values/colors.xml b/library/src/main/res/values/colors.xml new file mode 100644 index 0000000..dc95351 --- /dev/null +++ b/library/src/main/res/values/colors.xml @@ -0,0 +1,3 @@ +<resources> + <color name="kau_search_full_shadow">#80000000</color> +</resources> 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 a6f4b92..c21a7e1 100644 --- a/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt +++ b/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt @@ -7,6 +7,7 @@ import ca.allanwang.kau.email.sendEmail import ca.allanwang.kau.kpref.CoreAttributeContract import ca.allanwang.kau.kpref.KPrefActivity import ca.allanwang.kau.kpref.KPrefAdapterBuilder +import ca.allanwang.kau.searchview.SearchView import ca.allanwang.kau.utils.materialDialog import ca.allanwang.kau.utils.navigationBarColor import ca.allanwang.kau.utils.startActivity @@ -122,7 +123,7 @@ class MainActivity : KPrefActivity() { override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_main, menu) - + SearchView.bind(container, menu, R.id.action_search) return true } |