improved status fragment navbar style

This commit is contained in:
Mariotaku Lee 2017-06-26 14:48:05 +08:00
parent 6bf90e8dc5
commit 9058d19437
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
13 changed files with 172 additions and 31 deletions

View File

@ -28,6 +28,7 @@ import android.nfc.NfcAdapter
import android.os.Build
import android.os.Bundle
import android.support.annotation.StyleRes
import android.support.v4.app.Fragment
import android.support.v4.graphics.ColorUtils
import android.support.v4.view.OnApplyWindowInsetsListener
import android.support.v4.view.WindowInsetsCompat
@ -174,7 +175,7 @@ open class BaseActivity : ChameleonActivity(), IBaseActivity<BaseActivity>, IThe
var keyMetaState: Int = 0
private set
override fun getSystemWindowInsets(insets: Rect): Boolean {
override fun getSystemWindowInsets(caller: Fragment, insets: Rect): Boolean {
if (systemWindowsInsets == null) return false
insets.set(systemWindowsInsets)
return true

View File

@ -389,6 +389,19 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
return true
}
override fun getSystemWindowInsets(caller: Fragment, insets: Rect): Boolean {
if (caller === leftDrawerFragment) return super.getSystemWindowInsets(caller, insets)
if (mainTabs == null || homeContent == null) return false
val height = mainTabs.height
if (height != 0) {
insets.top = height
} else {
insets.top = ThemeUtils.getActionBarHeight(this)
}
insets.bottom = systemWindowsInsets?.bottom ?: 0
return true
}
override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat {
super.onApplyWindowInsets(v, insets)
val fragment = leftDrawerFragment

View File

@ -153,6 +153,7 @@ class LinkHandlerActivity : BaseActivity(), SystemWindowInsetsCallback, IControl
val f = currentVisibleFragment as? IFloatingActionButtonFragment
f?.onActionClick("link_handler")
}
contentView.applyWindowInsetsListener = this
contentFragmentId = R.id.contentFragment
}
@ -206,11 +207,13 @@ class LinkHandlerActivity : BaseActivity(), SystemWindowInsetsCallback, IControl
}
override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat {
return super.onApplyWindowInsets(v, insets)
val result = super.onApplyWindowInsets(v, insets)
val fragment = currentVisibleFragment
if (fragment is IBaseFragment<*>) {
fragment.requestApplyInsets()
}
return result.consumeSystemWindowInsets()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {

View File

@ -37,7 +37,8 @@ fun RecyclerView.LayoutManager.calculateSpaceItemHeight(child: View, spaceViewTy
}
}
if (heightBeforeSpace != 0) {
val spaceHeight = recyclerView.measuredHeight - heightBeforeSpace
val spaceHeight = recyclerView.measuredHeight - recyclerView.paddingTop -
recyclerView.paddingBottom - heightBeforeSpace
return Math.max(0, spaceHeight)
}
return -1

View File

@ -137,7 +137,7 @@ abstract class AbsToolbarTabPagesFragment : BaseFragment(), RefreshScrollTopInte
override fun onApplySystemWindowInsets(insets: Rect) {
}
override fun getSystemWindowInsets(insets: Rect): Boolean {
override fun getSystemWindowInsets(caller: Fragment, insets: Rect): Boolean {
if (toolbarTabs == null) return false
insets.set(0, toolbarContainer.height, 0, 0)
return true

View File

@ -454,6 +454,10 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
// No-op
}
override fun onApplySystemWindowInsets(insets: Rect) {
recyclerView.setPadding(insets.left, insets.top, insets.right, insets.bottom)
}
override val reachingEnd: Boolean
get() {
val lm = layoutManager

View File

@ -55,6 +55,7 @@ import android.support.v4.content.FixedAsyncTaskLoader
import android.support.v4.content.Loader
import android.support.v4.content.res.ResourcesCompat
import android.support.v4.graphics.ColorUtils
import android.support.v4.view.OnApplyWindowInsetsListener
import android.support.v4.view.ViewCompat
import android.support.v4.view.ViewPager.OnPageChangeListener
import android.support.v4.view.WindowCompat
@ -145,7 +146,6 @@ import org.mariotaku.twidere.util.support.ViewSupport
import org.mariotaku.twidere.util.support.WindowSupport
import org.mariotaku.twidere.view.HeaderDrawerLayout.DrawerCallback
import org.mariotaku.twidere.view.TabPagerIndicator
import org.mariotaku.twidere.view.TintedStatusFrameLayout
import org.mariotaku.twidere.view.iface.IExtendedView.OnSizeChangedListener
import java.lang.ref.WeakReference
import java.util.*
@ -554,7 +554,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
return false
}
override fun getSystemWindowInsets(insets: Rect): Boolean {
override fun getSystemWindowInsets(caller: Fragment, insets: Rect): Boolean {
return false
}
@ -674,8 +674,8 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
})
userFragmentView.windowInsetsListener = object : TintedStatusFrameLayout.WindowInsetsListener {
override fun onApplyWindowInsets(left: Int, top: Int, right: Int, bottom: Int) {
userFragmentView.windowInsetsListener = OnApplyWindowInsetsListener listener@ { _, insets ->
val top = insets.systemWindowInsetTop
profileContentContainer.setPadding(0, top, 0, 0)
profileBannerSpace.statusBarHeight = top
@ -686,7 +686,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
}
profileBannerSpace.toolbarHeight = toolbarHeight
}
}
return@listener insets
}
profileContentContainer.onSizeChangedListener = object : OnSizeChangedListener {

View File

@ -52,7 +52,7 @@ interface IBaseFragment<out F : Fragment> {
return
}
val insets = Rect()
if (callback.getSystemWindowInsets(insets)) {
if (callback.getSystemWindowInsets(fragment, insets)) {
onApplySystemWindowInsets(insets)
}
}
@ -63,7 +63,7 @@ interface IBaseFragment<out F : Fragment> {
}
interface SystemWindowInsetsCallback {
fun getSystemWindowInsets(insets: Rect): Boolean
fun getSystemWindowInsets(caller: Fragment, insets: Rect): Boolean
}
fun executeAfterFragmentResumed(useHandler: Boolean = false, action: (F) -> Unit): Promise<Unit, Exception>

View File

@ -23,7 +23,6 @@ import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.os.Build
import android.support.v4.view.ViewCompat
import android.util.AttributeSet
@ -34,6 +33,7 @@ import org.mariotaku.chameleon.ChameleonUtils
import org.mariotaku.chameleon.ChameleonView
import org.mariotaku.chameleon.internal.SupportMethods
import org.mariotaku.twidere.R
import android.support.v4.view.OnApplyWindowInsetsListener as OnApplyWindowInsetsListenerCompat
/**
* Created by mariotaku on 14/11/26.
@ -46,19 +46,17 @@ class TintedStatusFrameLayout(context: Context, attrs: AttributeSet? = null) :
private val colorPaint: Paint
private var statusBarHeight: Int = 0
private val systemWindowsInsets: Rect
var windowInsetsListener: WindowInsetsListener? = null
var windowInsetsListener: OnApplyWindowInsetsListenerCompat? = null
init {
val a = context.obtainStyledAttributes(attrs, R.styleable.TintedStatusLayout)
setPaddingEnabled = a.getBoolean(R.styleable.TintedStatusLayout_setPadding, false)
a.recycle()
colorPaint = Paint(Paint.ANTI_ALIAS_FLAG)
systemWindowsInsets = Rect()
setWillNotDraw(false)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
ViewCompat.setOnApplyWindowInsetsListener(this) { _, insets ->
ViewCompat.setOnApplyWindowInsetsListener(this) { view, insets ->
val top = insets.systemWindowInsetTop
val left = insets.systemWindowInsetLeft
val right = insets.systemWindowInsetRight
@ -67,9 +65,7 @@ class TintedStatusFrameLayout(context: Context, attrs: AttributeSet? = null) :
setPadding(left, top, right, bottom)
}
setStatusBarHeight(top)
if (windowInsetsListener != null) {
windowInsetsListener!!.onApplyWindowInsets(left, top, right, bottom)
}
windowInsetsListener?.onApplyWindowInsets(view, insets)
insets.consumeSystemWindowInsets()
}
}
@ -92,11 +88,6 @@ class TintedStatusFrameLayout(context: Context, attrs: AttributeSet? = null) :
canvas.drawRect(0f, 0f, canvas.width.toFloat(), statusBarHeight.toFloat(), colorPaint)
}
override fun fitSystemWindows(insets: Rect): Boolean {
systemWindowsInsets.set(insets)
return true
}
override fun isPostApplyTheme(): Boolean {
return false
}
@ -131,7 +122,4 @@ class TintedStatusFrameLayout(context: Context, attrs: AttributeSet? = null) :
var lightStatusBarMode: Int = 0
}
interface WindowInsetsListener {
fun onApplyWindowInsets(left: Int, top: Int, right: Int, bottom: Int)
}
}

View File

@ -29,4 +29,8 @@ interface TintedStatusLayout : IExtendedView {
var setPaddingEnabled: Boolean
interface WindowInsetsListener {
fun onApplyWindowInsets(left: Int, top: Int, right: Int, bottom: Int)
}
}

View File

@ -0,0 +1,125 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.view
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.os.Build
import android.support.v4.view.ViewCompat
import android.util.AttributeSet
import android.view.View
import org.mariotaku.chameleon.Chameleon
import org.mariotaku.chameleon.Chameleon.Theme.LightStatusBarMode
import org.mariotaku.chameleon.ChameleonUtils
import org.mariotaku.chameleon.ChameleonView
import org.mariotaku.chameleon.internal.SupportMethods
import org.mariotaku.twidere.R
import android.support.v4.view.OnApplyWindowInsetsListener as OnApplyWindowInsetsListenerCompat
/**
* Created by mariotaku on 14/11/26.
*/
class TintedStatusRelativeLayout(context: Context, attrs: AttributeSet? = null) :
ExtendedRelativeLayout(context, attrs), TintedStatusLayout, ChameleonView,
ChameleonView.StatusBarThemeable {
override var setPaddingEnabled: Boolean = false
private val colorPaint: Paint
private var statusBarHeight: Int = 0
var applyWindowInsetsListener: OnApplyWindowInsetsListenerCompat? = null
init {
val a = context.obtainStyledAttributes(attrs, R.styleable.TintedStatusLayout)
setPaddingEnabled = a.getBoolean(R.styleable.TintedStatusLayout_setPadding, false)
a.recycle()
colorPaint = Paint(Paint.ANTI_ALIAS_FLAG)
setWillNotDraw(false)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
ViewCompat.setOnApplyWindowInsetsListener(this) { view, insets ->
val top = insets.systemWindowInsetTop
val left = insets.systemWindowInsetLeft
val right = insets.systemWindowInsetRight
val bottom = insets.systemWindowInsetBottom
if (setPaddingEnabled) {
setPadding(left, top, right, bottom)
}
setStatusBarHeight(top)
applyWindowInsetsListener?.onApplyWindowInsets(view, insets)
insets.consumeSystemWindowInsets()
}
}
}
override fun setStatusBarColor(color: Int) {
colorPaint.color = 0xFF000000.toInt() or color
colorPaint.alpha = Color.alpha(color)
invalidate()
}
fun setStatusBarHeight(height: Int) {
statusBarHeight = height
invalidate()
}
override fun dispatchDraw(canvas: Canvas) {
super.dispatchDraw(canvas)
canvas.drawRect(0f, 0f, canvas.width.toFloat(), statusBarHeight.toFloat(), colorPaint)
}
override fun isPostApplyTheme(): Boolean {
return false
}
override fun createAppearance(context: Context, attributeSet: AttributeSet, theme: Chameleon.Theme): Appearance? {
val appearance = Appearance()
appearance.statusBarColor = theme.statusBarColor
appearance.lightStatusBarMode = theme.lightStatusBarMode
return appearance
}
override fun applyAppearance(appearance: ChameleonView.Appearance) {
val a = appearance as Appearance
val statusBarColor = a.statusBarColor
setStatusBarColor(statusBarColor)
val activity = ChameleonUtils.getActivity(context)
if (activity != null) {
val window = activity.window
SupportMethods.setStatusBarColor(window, Color.TRANSPARENT)
ChameleonUtils.applyLightStatusBar(window, statusBarColor, a.lightStatusBarMode)
}
}
override fun isStatusBarColorHandled(): Boolean {
return true
}
class Appearance : ChameleonView.Appearance {
var statusBarColor: Int = 0
@LightStatusBarMode
@get:LightStatusBarMode
var lightStatusBarMode: Int = 0
}
}

View File

@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
<org.mariotaku.twidere.view.TintedStatusRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/contentView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
@ -44,4 +45,4 @@
android:layout_below="@+id/toolbar"
android:background="?android:windowContentOverlay"/>
</RelativeLayout>
</org.mariotaku.twidere.view.TintedStatusRelativeLayout>

View File

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
<org.mariotaku.twidere.view.TintedStatusRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/contentView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
@ -24,4 +25,4 @@
app:backgroundTint="?colorToolbar"
app:elevation="6dp"
app:pressedTranslationZ="12dp"/>
</RelativeLayout>
</org.mariotaku.twidere.view.TintedStatusRelativeLayout>