From 261f0be0190f673b8d9706de13fff2a4eaafe6e1 Mon Sep 17 00:00:00 2001 From: RaviKoradiya Date: Thu, 11 Jan 2018 20:34:32 +0530 Subject: [PATCH] fixed runtime title change issue --- .../toolbarcentertitle/MainActivity.kt | 32 ++++++- app/src/main/res/layout/activity_main.xml | 33 ++++++- .../com/ravikoradiya/library/CenterTitle.kt | 93 ++++++++++++++++--- 3 files changed, 143 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/com/ravikoradiya/toolbarcentertitle/MainActivity.kt b/app/src/main/java/com/ravikoradiya/toolbarcentertitle/MainActivity.kt index ffa19c5..3339253 100644 --- a/app/src/main/java/com/ravikoradiya/toolbarcentertitle/MainActivity.kt +++ b/app/src/main/java/com/ravikoradiya/toolbarcentertitle/MainActivity.kt @@ -4,13 +4,15 @@ import android.databinding.DataBindingUtil import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.support.v7.widget.LinearLayoutManager +import android.text.Editable +import android.text.TextWatcher import android.view.Menu import com.ravikoradiya.toolbarcentertitle.databinding.ActivityMainBinding class MainActivity : AppCompatActivity() { - lateinit var binding: ActivityMainBinding; + lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -23,6 +25,34 @@ class MainActivity : AppCompatActivity() { supportActionBar?.setDisplayShowHomeEnabled(true) binding.switch1.setOnCheckedChangeListener { compoundButton, b -> binding.isTitleInCenter = b } + + binding.editTitle.addTextChangedListener(object : TextWatcher { + override fun afterTextChanged(p0: Editable?) { + + } + + override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { + + } + + override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { + binding.toolbar.title = p0 + } + }) + + binding.editSubTitle.addTextChangedListener(object : TextWatcher { + override fun afterTextChanged(p0: Editable?) { + + } + + override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { + + } + + override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { + binding.toolbar.subtitle = p0 + } + }) } override fun onCreateOptionsMenu(menu: Menu): Boolean { diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 95a7fd0..6b8bd3d 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -9,6 +9,7 @@ + + + + + diff --git a/library/src/main/java/com/ravikoradiya/library/CenterTitle.kt b/library/src/main/java/com/ravikoradiya/library/CenterTitle.kt index f7b2a1d..71e107a 100644 --- a/library/src/main/java/com/ravikoradiya/library/CenterTitle.kt +++ b/library/src/main/java/com/ravikoradiya/library/CenterTitle.kt @@ -2,17 +2,28 @@ package com.ravikoradiya.library import android.databinding.BindingAdapter import android.support.v7.widget.Toolbar +import android.text.Editable +import android.text.TextWatcher +import android.util.Log import android.view.View -import android.view.ViewTreeObserver +import android.view.ViewTreeObserver.OnGlobalLayoutListener import android.widget.ImageButton import android.widget.TextView object CenterTitle { + lateinit var titleWatcher: TextWatcher + lateinit var subTitleWatcher: TextWatcher + lateinit var globalLayoutListener: OnGlobalLayoutListener + @JvmStatic + var isCenter = true + @BindingAdapter("centerTitle") @JvmStatic - fun centerTitle(toolbar: Toolbar, textAlignment: Boolean) { + fun centerTitle(toolbar: Toolbar, flagCenter: Boolean) { + + isCenter = flagCenter // title val fieldTitle = Toolbar::class.java.getDeclaredField("mTitleTextView") @@ -29,9 +40,53 @@ object CenterTitle { fieldNav.isAccessible = true val mNavButtonView: ImageButton? = fieldNav.get(toolbar) as ImageButton? + mTitleTextView?.let { - // + //removing observer for avoid recursive call + if (::globalLayoutListener.isInitialized) + removeAllListners(mTitleTextView, mSubtitleTextView, globalLayoutListener, titleWatcher, subTitleWatcher) + + // view tree observer for listen any layout changes + globalLayoutListener = object : OnGlobalLayoutListener { + + override fun onGlobalLayout() { + removeAllListners(mTitleTextView, mSubtitleTextView, globalLayoutListener, titleWatcher, subTitleWatcher) + centerTitle(toolbar, isCenter) + } + } + + titleWatcher = object : TextWatcher { + override fun afterTextChanged(p0: Editable?) { + mTitleTextView.requestLayout() + removeAllListners(mTitleTextView, mSubtitleTextView, globalLayoutListener, titleWatcher, subTitleWatcher) + centerTitle(toolbar, isCenter) + } + + override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { + } + + override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { + + } + } + + subTitleWatcher = object : TextWatcher { + override fun afterTextChanged(p0: Editable?) { + mSubtitleTextView?.requestLayout() + removeAllListners(mTitleTextView, mSubtitleTextView, globalLayoutListener, titleWatcher, subTitleWatcher) + centerTitle(toolbar, isCenter) + } + + override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { + } + + override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { + + } + } + + //mesure all views mTitleTextView.measure(0, 0) mNavButtonView?.measure(0, 0) mSubtitleTextView?.measure(0, 0) @@ -63,7 +118,7 @@ object CenterTitle { // position title mTitleTextView.run { - if (textAlignment) left = leftSideMarginTitle + if (isCenter) left = leftSideMarginTitle else left = mNavButtonView?.measuredWidth.orZero() right = Math.min(toolbar.measuredWidth - leftSideMarginTitle, menuIconsMargin) layoutParams.width = Math.min(toolbar.measuredWidth - leftSideMarginTitle, menuIconsMargin) - leftSideMarginTitle @@ -72,25 +127,37 @@ object CenterTitle { // position sub title mSubtitleTextView?.run { - if (textAlignment) left = leftSideMarginSubTitle + if (isCenter) left = leftSideMarginSubTitle else left = mNavButtonView?.measuredWidth.orZero() right = Math.min(toolbar.measuredWidth - leftSideMarginSubTitle, menuIconsMargin) layoutParams.width = Math.min(toolbar.measuredWidth - leftSideMarginSubTitle, menuIconsMargin) - leftSideMarginSubTitle text = text } - val vto = mTitleTextView.getViewTreeObserver() + // add a view tree observer so that we can center the title every time view tree is updated - vto.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { - override fun onGlobalLayout() { - // remove listener to prevent recursive calls - mTitleTextView.getViewTreeObserver().removeOnGlobalLayoutListener(this) - centerTitle(toolbar, textAlignment) - } - }) + val vto = mTitleTextView.getViewTreeObserver() + vto.addOnGlobalLayoutListener(globalLayoutListener) + + // add text watcher for listen text change + mTitleTextView.addTextChangedListener(titleWatcher) + + // add text watcher for listen text change + mSubtitleTextView?.addTextChangedListener(subTitleWatcher) } } + + + private fun removeAllListners(titleView: TextView, + subTitleView: TextView?, + titleObserver: OnGlobalLayoutListener, + titleTextWatcher: TextWatcher, + subTitleTextWatcher: TextWatcher) { + titleView.getViewTreeObserver().removeOnGlobalLayoutListener(titleObserver) + titleView.removeTextChangedListener(titleTextWatcher) + subTitleView?.removeTextChangedListener(subTitleTextWatcher) + } } fun Int?.orZero(): Int = this ?: 0