Commit 806f4e13 authored by Mygod's avatar Mygod

Prevent snackbar overlapping with bottom bar

parent 2ca8d50e
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent" android:layout_height="match_parent"
tools:ignore="UnknownIdInLayout" android:clipChildren="false">
<android.support.design.widget.CoordinatorLayout 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="match_parent"
android:clipChildren="false">
<FrameLayout android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/stat"/>
app:layout_anchor="@+id/stat"
app:layout_behavior="com.github.shadowsocks.widget.BottomAwareBehavior"/>
<LinearLayout android:id="@+id/stat"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:elevation="4dp"
android:paddingStart="16dip"
android:paddingEnd="16dip"
......@@ -19,7 +22,7 @@
android:background="@drawable/background_stat"
android:orientation="vertical"
android:nextFocusRight="@+id/fab"
android:layout_alignParentBottom="true">
app:layout_behavior="com.github.shadowsocks.widget.BottomBehavior">
<TextView android:id="@+id/status"
android:textSize="16sp"
android:textColor="?android:attr/textColorPrimary"
......@@ -71,14 +74,15 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:elevation="6dp"
android:layout_alignTop="@+id/stat"
android:layout_alignParentEnd="true"
app:layout_anchorGravity="end"
android:layout_marginEnd="16dp"
android:layout_marginTop="@dimen/fab_margin_top">
android:layout_marginBottom="@dimen/fab_margin_bottom"
app:layout_behavior="com.github.shadowsocks.widget.BottomBehavior"
app:layout_anchor="@+id/stat">
<android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:backgroundTint="@color/material_blue_grey_700"
app:srcCompat="@drawable/ic_start_idle"
app:pressedTranslationZ="6dp" app:borderWidth="0dp" />
</com.github.jorgecastilloprz.FABProgressCircle>
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="fab_margin_top">-28dp</dimen>
<dimen name="fab_margin_bottom">-28dp</dimen>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- TODO: Remove when this issue is fixed: https://github.com/JorgeCastilloPrz/FABProgressCircle/issues/19 -->
<dimen name="fab_margin_top">-44dp</dimen>
<dimen name="fab_margin_bottom">-44dp</dimen>
</resources>
......@@ -26,7 +26,7 @@ class GlobalConfigFragment extends PreferenceFragment {
val value = v.asInstanceOf[Boolean]
val result = TcpFastOpen.enabled(value)
if (result != null && result != "Success.")
Snackbar.make(getActivity.findViewById(android.R.id.content), result, Snackbar.LENGTH_LONG).show()
Snackbar.make(getActivity.findViewById(R.id.content), result, Snackbar.LENGTH_LONG).show()
value == TcpFastOpen.sendEnabled
})
if (!TcpFastOpen.supported) {
......
......@@ -105,7 +105,7 @@ class MainActivity extends Activity with ServiceBoundContext with Drawer.OnDrawe
fab.setEnabled(true)
changeSwitch(checked = false)
if (m != null) {
val snackbar = Snackbar.make(findViewById(android.R.id.content),
val snackbar = Snackbar.make(findViewById(R.id.content),
getString(R.string.vpn_error).formatLocal(Locale.ENGLISH, m), Snackbar.LENGTH_LONG)
if (m == getString(R.string.nat_no_root)) addDisableNatToSnackbar(snackbar)
snackbar.show()
......@@ -276,7 +276,7 @@ class MainActivity extends Activity with ServiceBoundContext with Drawer.OnDrawe
synchronized(if (serviceStarted && testCount == id && app.isVpnEnabled) handler.post(() =>
if (success) statusText.setText(result) else {
statusText.setText(R.string.connection_test_fail)
Snackbar.make(findViewById(android.R.id.content), result, Snackbar.LENGTH_LONG).show()
Snackbar.make(findViewById(R.id.content), result, Snackbar.LENGTH_LONG).show()
}))
}
}
......
package com.github.shadowsocks.widget
import android.content.Context
import android.support.design.widget.CoordinatorLayout
import android.util.AttributeSet
import android.view.View
/**
* Behavior for content area that's aware of bottom bars.
*
* @author Mygod
*/
class BottomAwareBehavior(context: Context, attrs: AttributeSet)
extends CoordinatorLayout.Behavior[View](context, attrs) {
override def onDependentViewChanged(parent: CoordinatorLayout, child: View, dependency: View): Boolean = {
val params = child.getLayoutParams.asInstanceOf[CoordinatorLayout.LayoutParams]
val margin = parent.getHeight - dependency.getTop - dependency.getTranslationY.toInt
if (params.bottomMargin != margin) {
params.bottomMargin = margin
true
} else false
}
}
package com.github.shadowsocks.widget
import android.animation.ValueAnimator
import android.content.Context
import android.support.design.widget.CoordinatorLayout
import android.support.design.widget.Snackbar.SnackbarLayout
import android.support.v4.view.animation.FastOutSlowInInterpolator
import android.util.AttributeSet
import android.view.View
import scala.collection.JavaConverters._
/**
* A SnackbarLayout-aware behavior.
*
* TODO: What happened to the animations?
*
* @author Mygod
*/
class BottomBehavior(context: Context, attrs: AttributeSet) extends CoordinatorLayout.Behavior[View](context, attrs) {
private var translationYAnimator: ValueAnimator = _
private var translationY: Float = _
override def layoutDependsOn(parent: CoordinatorLayout, child: View, dependency: View): Boolean = dependency match {
case _: SnackbarLayout => true
case _ => super.layoutDependsOn(parent, child, dependency)
}
override def onDependentViewChanged(parent: CoordinatorLayout, child: View, dependency: View): Boolean = {
dependency match {
case _: SnackbarLayout =>
var targetTransY = parent.getDependencies(child).asScala
.filter(view => view.isInstanceOf[SnackbarLayout] && parent.doViewsOverlap(child, view))
.map(view => view.getTranslationY - view.getHeight).reduceOption(_ min _).getOrElse(0F)
if (targetTransY > 0) targetTransY = 0
if (translationY != targetTransY) {
val currentTransY = child.getTranslationY
if (translationYAnimator != null && translationYAnimator.isRunning) translationYAnimator.cancel()
if (child.isShown && Math.abs(currentTransY - targetTransY) > child.getHeight * 0.667F) {
if (translationYAnimator == null) {
translationYAnimator = new ValueAnimator
translationYAnimator.setInterpolator(new FastOutSlowInInterpolator())
translationYAnimator.addUpdateListener(animation =>
child.setTranslationY(animation.getAnimatedValue.asInstanceOf[Float]))
}
translationYAnimator.setFloatValues(currentTransY, targetTransY)
translationYAnimator.start()
} else child.setTranslationY(targetTransY)
translationY = targetTransY
}
true
case _ => super.onDependentViewChanged(parent, child, dependency)
}
}
override def onDependentViewRemoved(parent: CoordinatorLayout, child: View, dependency: View): Unit = {
dependency match {
case _: SnackbarLayout =>
if (translationY != 0) {
val currentTransY = child.getTranslationY
if (translationYAnimator != null && translationYAnimator.isRunning) translationYAnimator.cancel()
if (child.isShown && Math.abs(currentTransY) > child.getHeight * 0.667F) {
if (translationYAnimator == null) {
translationYAnimator = new ValueAnimator
translationYAnimator.setInterpolator(new FastOutSlowInInterpolator())
translationYAnimator.addUpdateListener(animation =>
child.setTranslationY(animation.getAnimatedValue.asInstanceOf[Float]))
}
translationYAnimator.setFloatValues(currentTransY, 0)
translationYAnimator.start()
} else child.setTranslationY(0)
translationY = 0
}
parent.dispatchDependentViewsChanged(child)
}
super.onDependentViewRemoved(parent, child, dependency)
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment