-
-
Save Frank-Zhu/2b814db8fd73bd8d31db to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
android:layout_width="match_parent" | |
android:layout_height="88dp" | |
android:layout_gravity="bottom" | |
android:orientation="vertical"> | |
<ImageButton | |
android:id="@+id/fab" | |
android:layout_width="@dimen/fab_size" | |
android:layout_height="@dimen/fab_size" | |
android:layout_gravity="bottom|right" | |
android:layout_marginBottom="16dp" | |
android:layout_marginRight="16dp" | |
android:background="@drawable/ripple" | |
android:elevation="8dp" | |
android:src="@drawable/ic_add" | |
android:stateListAnimator="@anim/fab_raise" | |
android:tint="@color/primary_dark" /> | |
<RelativeLayout | |
android:id="@+id/expanded_view" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:background="@color/accent" | |
android:orientation="horizontal" | |
android:padding="16dp" | |
android:visibility="invisible"> | |
<ImageButton | |
android:id="@+id/act_collapse" | |
android:layout_width="56dp" | |
android:layout_height="56dp" | |
android:layout_alignParentRight="true" | |
android:background="?attr/selectableItemBackgroundBorderless" | |
android:src="@drawable/ic_add" | |
android:tint="@color/primary_dark" /> | |
<LinearLayout | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:layout_toLeftOf="@+id/act_collapse" | |
android:orientation="horizontal"> | |
<ImageButton | |
android:id="@+id/btn_action_1" | |
android:layout_width="56dp" | |
android:layout_height="56dp" | |
android:background="?attr/selectableItemBackgroundBorderless" | |
android:src="@drawable/ic_action" | |
android:tint="@color/primary_dark" /> | |
<ImageButton | |
android:id="@+id/btn_action_2" | |
android:layout_width="56dp" | |
android:layout_height="56dp" | |
android:background="?attr/selectableItemBackgroundBorderless" | |
android:src="@drawable/ic_action" | |
android:tint="@color/primary_dark" /> | |
<ImageButton | |
android:id="@+id/btn_action_3" | |
android:layout_width="56dp" | |
android:layout_height="56dp" | |
android:background="?attr/selectableItemBackgroundBorderless" | |
android:src="@drawable/ic_action" | |
android:tint="@color/primary_dark" /> | |
<ImageButton | |
android:id="@+id/btn_action_4" | |
android:layout_width="56dp" | |
android:layout_height="56dp" | |
android:background="?attr/selectableItemBackgroundBorderless" | |
android:src="@drawable/ic_action" | |
android:tint="@color/primary_dark" /> | |
</LinearLayout> | |
</RelativeLayout> | |
</FrameLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:orientation="vertical"> | |
<include layout="@layout/fab_actions"/> | |
</FrameLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.materialdesign.chris.materialdesignexperimenting; | |
import android.animation.Animator; | |
import android.animation.AnimatorListenerAdapter; | |
import android.animation.ObjectAnimator; | |
import android.app.Activity; | |
import android.os.Bundle; | |
import android.os.Handler; | |
import android.view.View; | |
import android.view.ViewAnimationUtils; | |
import android.view.animation.Interpolator; | |
/** | |
* Created by Chris Basha on 14/12/2014. | |
*/ | |
public class UIActivity extends Activity { | |
public static final int FAB_STATE_COLLAPSED = 0; | |
public static final int FAB_STATE_EXPANDED = 1; | |
public static int FAB_CURRENT_STATE = FAB_STATE_COLLAPSED; | |
View mFab, mExpandedView, mCollapseFabButton; | |
View act1, act2, act3, act4; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.layout_main); | |
mFab = findViewById(R.id.fab); | |
mExpandedView = findViewById(R.id.expanded_view); | |
mCollapseFabButton = findViewById(R.id.act_collapse); | |
act1 = findViewById(R.id.btn_action_1); | |
act2 = findViewById(R.id.btn_action_2); | |
act3 = findViewById(R.id.btn_action_3); | |
act4 = findViewById(R.id.btn_action_4); | |
mFab.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View view) { | |
revealView(mExpandedView); | |
FAB_CURRENT_STATE = FAB_STATE_EXPANDED; | |
new Handler().postDelayed(new Runnable() { | |
@Override | |
public void run() { | |
mFab.setVisibility(View.GONE); | |
} | |
}, 50); | |
mCollapseFabButton.animate().rotationBy(135).setDuration(250).start(); | |
} | |
}); | |
mCollapseFabButton.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View view) { | |
hideView(mExpandedView); | |
FAB_CURRENT_STATE = FAB_STATE_COLLAPSED; | |
mCollapseFabButton.animate().rotationBy(-135).setDuration(200).start(); | |
} | |
}); | |
} | |
public void revealView(View myView) { | |
int cx = (mFab.getLeft() + mFab.getRight()) / 2; | |
int cy = (mFab.getTop() + mFab.getBottom()) / 2; | |
int finalRadius = Math.max(myView.getWidth(), myView.getHeight()); | |
Animator anim = | |
ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius); | |
anim.setDuration(300); | |
myView.setVisibility(View.VISIBLE); | |
slideView(act1); | |
slideView(act2); | |
slideView(act3); | |
slideView(act4); | |
anim.start(); | |
} | |
public void hideView(final View myView) { | |
int cx = (mFab.getLeft() + mFab.getRight()) / 2; | |
int cy = (mFab.getTop() + mFab.getBottom()) / 2; | |
int initialRadius = myView.getWidth(); | |
Animator anim = ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0); | |
anim.setDuration(300); | |
anim.setInterpolator(getLinearOutSlowInInterpolator()); | |
anim.addListener(new AnimatorListenerAdapter() { | |
@Override | |
public void onAnimationEnd(Animator animation) { | |
super.onAnimationEnd(animation); | |
myView.setVisibility(View.INVISIBLE); | |
} | |
}); | |
//Normally I would restore visibility when the hide animation has ended, but it doesn't look as good, so I'm doing it earlier. | |
new Handler().postDelayed(new Runnable() { | |
@Override | |
public void run() { | |
mFab.setVisibility(View.VISIBLE); | |
} | |
}, 200); | |
anim.start(); | |
} | |
//Animation to slide the action buttons | |
public void slideView(View view) { | |
ObjectAnimator slide = ObjectAnimator.ofFloat(view, View.TRANSLATION_X, 112, 0); | |
slide.setDuration(500); | |
slide.setInterpolator(getLinearOutSlowInInterpolator()); | |
slide.start(); | |
} | |
//Code for these: https://gist.github.com/chris95x8/4d74591bed75fd151799 | |
public static Interpolator getLinearOutSlowInInterpolator() { | |
//Decelerate Interpolator - For elements that enter the screen | |
return new CubicBezierInterpolator(0, 0, 0.2, 1); | |
} | |
public static Interpolator getFastInSlowOutInterpolator() { | |
//Ease In Out Interpolator - For elements that change position while staying in the screen | |
return new CubicBezierInterpolator(0.4, 0, 0.2, 1); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment