Merge pull request #137 from NoodleMage/fab_improvement
FAB animation update
@ -19,10 +19,19 @@ import android.content.Context;
|
|||||||
import android.support.design.widget.CoordinatorLayout;
|
import android.support.design.widget.CoordinatorLayout;
|
||||||
import android.support.design.widget.FloatingActionButton;
|
import android.support.design.widget.FloatingActionButton;
|
||||||
import android.support.v4.view.ViewCompat;
|
import android.support.v4.view.ViewCompat;
|
||||||
|
import android.support.v4.view.animation.FastOutSlowInInterpolator;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.animation.Animation;
|
||||||
|
import android.view.animation.AnimationUtils;
|
||||||
|
import android.view.animation.Interpolator;
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.R;
|
||||||
|
|
||||||
public class ScrollAwareFABBehavior extends FloatingActionButton.Behavior {
|
public class ScrollAwareFABBehavior extends FloatingActionButton.Behavior {
|
||||||
|
private static final Interpolator INTERPOLATOR = new FastOutSlowInInterpolator();
|
||||||
|
private boolean mIsAnimatingOut = false;
|
||||||
|
|
||||||
public ScrollAwareFABBehavior(Context context, AttributeSet attrs) {
|
public ScrollAwareFABBehavior(Context context, AttributeSet attrs) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
@ -40,12 +49,43 @@ public class ScrollAwareFABBehavior extends FloatingActionButton.Behavior {
|
|||||||
final View target, final int dxConsumed, final int dyConsumed,
|
final View target, final int dxConsumed, final int dyConsumed,
|
||||||
final int dxUnconsumed, final int dyUnconsumed) {
|
final int dxUnconsumed, final int dyUnconsumed) {
|
||||||
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
|
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
|
||||||
if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) {
|
if (dyConsumed > 0 && !this.mIsAnimatingOut && child.getVisibility() == View.VISIBLE) {
|
||||||
// User scrolled down and the FAB is currently visible -> hide the FAB
|
// User scrolled down and the FAB is currently visible -> hide the FAB
|
||||||
child.hide();
|
animateOut(child);
|
||||||
} else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) {
|
} else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) {
|
||||||
// User scrolled up and the FAB is currently not visible -> show the FAB
|
// User scrolled up and the FAB is currently not visible -> show the FAB
|
||||||
child.show();
|
animateIn(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Same animation that FloatingActionButton.Behavior uses to hide the FAB when the AppBarLayout exits
|
||||||
|
private void animateOut(final FloatingActionButton button) {
|
||||||
|
Animation anim = AnimationUtils.loadAnimation(button.getContext(), R.anim.fab_hide_to_bottom);
|
||||||
|
anim.setInterpolator(INTERPOLATOR);
|
||||||
|
anim.setDuration(200L);
|
||||||
|
anim.setAnimationListener(new Animation.AnimationListener() {
|
||||||
|
public void onAnimationStart(Animation animation) {
|
||||||
|
ScrollAwareFABBehavior.this.mIsAnimatingOut = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onAnimationEnd(Animation animation) {
|
||||||
|
ScrollAwareFABBehavior.this.mIsAnimatingOut = false;
|
||||||
|
button.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationRepeat(final Animation animation) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
button.startAnimation(anim);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Same animation that FloatingActionButton.Behavior uses to show the FAB when the AppBarLayout enters
|
||||||
|
private void animateIn(FloatingActionButton button) {
|
||||||
|
button.setVisibility(View.VISIBLE);
|
||||||
|
Animation anim = AnimationUtils.loadAnimation(button.getContext(), R.anim.fab_show_from_bottom);
|
||||||
|
anim.setDuration(200L);
|
||||||
|
anim.setInterpolator(INTERPOLATOR);
|
||||||
|
button.startAnimation(anim);
|
||||||
|
}
|
||||||
}
|
}
|
@ -65,15 +65,6 @@ public class MangaInfoFragment extends BaseRxFragment<MangaInfoPresenter> {
|
|||||||
View view = inflater.inflate(R.layout.fragment_manga_info, container, false);
|
View view = inflater.inflate(R.layout.fragment_manga_info, container, false);
|
||||||
ButterKnife.bind(this, view);
|
ButterKnife.bind(this, view);
|
||||||
|
|
||||||
//Create edit drawable with size 24dp (google guidelines)
|
|
||||||
IconicsDrawable edit = new IconicsDrawable(this.getContext())
|
|
||||||
.icon(GoogleMaterial.Icon.gmd_edit)
|
|
||||||
.color(ContextCompat.getColor(this.getContext(), R.color.white))
|
|
||||||
.sizeDp(24);
|
|
||||||
|
|
||||||
// Update image of fab button
|
|
||||||
fabEdit.setImageDrawable(edit);
|
|
||||||
|
|
||||||
// Set listener.
|
// Set listener.
|
||||||
fabEdit.setOnClickListener(v -> selectImage());
|
fabEdit.setOnClickListener(v -> selectImage());
|
||||||
|
|
||||||
|
6
app/src/main/res/anim/fab_hide_to_bottom.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<translate xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:interpolator="@android:interpolator/accelerate_quint"
|
||||||
|
android:fromYDelta="0"
|
||||||
|
android:toYDelta="30%p"
|
||||||
|
android:duration="200" />
|
6
app/src/main/res/anim/fab_show_from_bottom.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<translate xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:interpolator="@android:interpolator/accelerate_cubic"
|
||||||
|
android:fromYDelta="30%p"
|
||||||
|
android:toYDelta="0"
|
||||||
|
android:duration="300" />
|
Before Width: | Height: | Size: 134 B |
BIN
app/src/main/res/drawable-hdpi/ic_add_white_24dp.png
Normal file
After Width: | Height: | Size: 127 B |
BIN
app/src/main/res/drawable-hdpi/ic_mode_edit_white_24dp.png
Normal file
After Width: | Height: | Size: 219 B |
Before Width: | Height: | Size: 119 B |
Before Width: | Height: | Size: 116 B |
BIN
app/src/main/res/drawable-mdpi/ic_add_white_24dp.png
Normal file
After Width: | Height: | Size: 88 B |
BIN
app/src/main/res/drawable-mdpi/ic_mode_edit_white_24dp.png
Normal file
After Width: | Height: | Size: 165 B |
Before Width: | Height: | Size: 168 B |
BIN
app/src/main/res/drawable-xhdpi/ic_add_white_24dp.png
Normal file
After Width: | Height: | Size: 97 B |
BIN
app/src/main/res/drawable-xhdpi/ic_mode_edit_white_24dp.png
Normal file
After Width: | Height: | Size: 239 B |
Before Width: | Height: | Size: 242 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_add_white_24dp.png
Normal file
After Width: | Height: | Size: 97 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_mode_edit_white_24dp.png
Normal file
After Width: | Height: | Size: 302 B |
Before Width: | Height: | Size: 500 B |
BIN
app/src/main/res/drawable-xxxhdpi/ic_add_white_24dp.png
Normal file
After Width: | Height: | Size: 102 B |
BIN
app/src/main/res/drawable-xxxhdpi/ic_mode_edit_white_24dp.png
Normal file
After Width: | Height: | Size: 355 B |
@ -18,11 +18,12 @@
|
|||||||
|
|
||||||
<android.support.design.widget.FloatingActionButton
|
<android.support.design.widget.FloatingActionButton
|
||||||
android:id="@+id/fab"
|
android:id="@+id/fab"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="@dimen/fab_size"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="@dimen/fab_size"
|
||||||
android:layout_gravity="bottom|right"
|
android:layout_gravity="bottom|end"
|
||||||
android:layout_margin="@dimen/fab_margin"
|
android:layout_margin="@dimen/fab_margin"
|
||||||
android:src="@drawable/ic_action_add_18dp"
|
android:scaleType="fitCenter"
|
||||||
|
android:src="@drawable/ic_add_white_24dp"
|
||||||
app:backgroundTint="@color/colorPrimary"
|
app:backgroundTint="@color/colorPrimary"
|
||||||
app:layout_anchor="@id/categories_list"
|
app:layout_anchor="@id/categories_list"
|
||||||
app:layout_anchorGravity="bottom|right|end"
|
app:layout_anchorGravity="bottom|right|end"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<android.support.design.widget.CoordinatorLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -20,7 +21,8 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<ScrollView
|
<android.support.v4.widget.NestedScrollView
|
||||||
|
android:id="@+id/manga_info_scroll_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
@ -254,28 +256,25 @@
|
|||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</ScrollView>
|
|
||||||
|
</android.support.v4.widget.NestedScrollView>
|
||||||
|
|
||||||
</android.support.v4.widget.SwipeRefreshLayout>
|
</android.support.v4.widget.SwipeRefreshLayout>
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentBottom="true"
|
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_margin="10dp"
|
|
||||||
android:gravity="bottom">
|
|
||||||
|
|
||||||
<android.support.design.widget.FloatingActionButton
|
<android.support.design.widget.FloatingActionButton
|
||||||
android:id="@+id/fab_edit"
|
android:id="@+id/fab_edit"
|
||||||
android:layout_width="wrap_content"
|
android:layout_height="@dimen/fab_size"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="@dimen/fab_size"
|
||||||
android:layout_gravity="bottom|right"
|
android:layout_gravity="bottom|end"
|
||||||
android:layout_margin="@dimen/fab_margin"
|
android:layout_margin="@dimen/fab_margin"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
android:src="@drawable/ic_mode_edit_white_24dp"
|
||||||
app:backgroundTint="@color/colorPrimary"
|
app:backgroundTint="@color/colorPrimary"
|
||||||
|
app:layout_anchor="@id/manga_info_scroll_view"
|
||||||
|
app:layout_anchorGravity="bottom|right|end"
|
||||||
app:layout_behavior="eu.kanade.tachiyomi.ui.base.fab.ScrollAwareFABBehavior"/>
|
app:layout_behavior="eu.kanade.tachiyomi.ui.base.fab.ScrollAwareFABBehavior"/>
|
||||||
|
</android.support.design.widget.CoordinatorLayout>
|
||||||
</LinearLayout>
|
|
||||||
</RelativeLayout>
|
|
@ -7,6 +7,7 @@
|
|||||||
<dimen name="margin_left">16dp</dimen>
|
<dimen name="margin_left">16dp</dimen>
|
||||||
<dimen name="margin_right">16dp</dimen>
|
<dimen name="margin_right">16dp</dimen>
|
||||||
<dimen name="fab_margin">16dp</dimen>
|
<dimen name="fab_margin">16dp</dimen>
|
||||||
|
<dimen name="fab_size">56dp</dimen>
|
||||||
|
|
||||||
<dimen name="dialog_content_padding">24dp</dimen>
|
<dimen name="dialog_content_padding">24dp</dimen>
|
||||||
<dimen name="dialog_margin_top_content">20dp</dimen>
|
<dimen name="dialog_margin_top_content">20dp</dimen>
|
||||||
|