Skip to content

Instantly share code, notes, and snippets.

@Guilherme-HRamos
Last active July 10, 2018 23:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Guilherme-HRamos/52429a5ccb00fa44957c50d5565a5054 to your computer and use it in GitHub Desktop.
Save Guilherme-HRamos/52429a5ccb00fa44957c50d5565a5054 to your computer and use it in GitHub Desktop.
Material Design Utils
/** Copyright 2018, Guilherme Henrique Ramos da Silva
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
**
*/
public class MaterialCardTranslation extends MaterialCardView {
private boolean isElevated = false;
private int ANIM_DURATION = 250;
public MaterialCardTranslation(Context context) {
super(context);
}
public MaterialCardTranslation(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MaterialCardTranslation(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public boolean isElevated() {
return isElevated;
}
public void setDuration(final int duration) {
ANIM_DURATION = duration;
}
public void elevateCard(final boolean elevate, @Nullable final EndAction endAction) {
dispatchElevateAnim(elevate, endAction);
}
public void simulateClickElevation(@Nullable final EndAction endAction) {
dispatchElevateCompleteAnim(endAction);
}
private void dispatchElevateAnim(final boolean elevate, @Nullable final EndAction endAction) {
if (elevate) {
upAnim();
} else {
downAnim();
}
isElevated = elevate;
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
endAction.onEnd();
}
}, ANIM_DURATION);
}
private void dispatchElevateCompleteAnim(@Nullable final EndAction endAction) {
if (isElevated || isLessThan21())
return;
final float posZ = getZ();
animate().translationZ(posZ * 2).setDuration(ANIM_DURATION)
.setInterpolator(new FastOutSlowInInterpolator())
.withEndAction(new Runnable() {
@Override
public void run() {
downAnim();
}
});
if (endAction != null)
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
endAction.onEnd();
}
}, ANIM_DURATION * 2);
}
private void upAnim() {
if (isLessThan21())
return;
animate().translationZ(getZ() * 2).setDuration(ANIM_DURATION)
.setInterpolator(new FastOutSlowInInterpolator())
.start();
}
private void downAnim() {
if (isLessThan21())
return;
animate().translationZ(0).setDuration(ANIM_DURATION)
.setInterpolator(new FastOutSlowInInterpolator())
.start();
}
public interface EndAction {
void onEnd();
}
private boolean isLessThan21() {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP;
}
}
/** Copyright 2018, Guilherme Henrique Ramos da Silva
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
**
*/
public class MaterialRevealHelper {
private long ANIM_DURATION = 750;
private GRAVITY gravity = GRAVITY.CENTER;
public enum GRAVITY {
TOP_CENTER, TOP_LEFT, TOP_RIGHT,
CENTER, CENTER_LEFT, CENTER_RIGHT,
BOTTOM_CENTER, BOTTOM_LEFT, BOTTOM_RIGHT
}
public void setAnimDuration(long duration) {
ANIM_DURATION = duration;
}
public boolean isShow(View v) {
return v.getVisibility() == View.VISIBLE;
}
public void setGravity(GRAVITY gravity) {
this.gravity = gravity;
}
public void hide(final View toHide, final Action action) {
dispatchHideReveal(toHide, action);
}
public void show(final View toShow, final Action action) {
dispatchShowReveal(toShow, action);
}
private void dispatchHideReveal(final View toHide, final Action action) {
if (isLessThan21())
return;
int posX = (int) getX(toHide);
int posY = (int) getY(toHide);
final Animator circularReveal = ViewAnimationUtils.createCircularReveal(
toHide,
posX,
posY,
(float) Math.hypot(toHide.getWidth(), toHide.getHeight()),
0);
circularReveal.setInterpolator(new FastOutSlowInInterpolator());
circularReveal.setDuration(ANIM_DURATION);
circularReveal.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
if (action != null)
action.onStart();
}
@Override
public void onAnimationEnd(Animator animator) {
toHide.setVisibility(View.INVISIBLE);
if (action != null)
action.onEnd();
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
circularReveal.start();
}
private void dispatchShowReveal(final View toShow, final Action action) {
if (isLessThan21())
return;
int posX = (int) getX(toShow);
int posY = (int) getY(toShow);
final Animator circularReveal = ViewAnimationUtils.createCircularReveal(
toShow,
posX,
posY,
0,
(float) Math.hypot(toShow.getWidth(), toShow.getHeight()));
circularReveal.setInterpolator(new FastOutSlowInInterpolator());
circularReveal.setDuration(ANIM_DURATION);
circularReveal.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
toShow.setVisibility(View.VISIBLE);
if (action != null)
action.onStart();
}
@Override
public void onAnimationEnd(Animator animator) {
if (action != null)
action.onEnd();
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
circularReveal.start();
}
private float getX(View v) {
switch (gravity) {
case CENTER:
case TOP_CENTER:
case BOTTOM_CENTER:
return v.getWidth() / 2;
case TOP_LEFT:
case BOTTOM_LEFT:
case CENTER_LEFT:
return 0;
case TOP_RIGHT:
case BOTTOM_RIGHT:
case CENTER_RIGHT:
return v.getWidth();
default:
}
return 0;
}
private float getY(View v) {
switch (gravity) {
case CENTER:
case CENTER_LEFT:
case CENTER_RIGHT:
return v.getHeight() / 2;
case TOP_CENTER:
case TOP_LEFT:
case TOP_RIGHT:
return 0;
case BOTTOM_CENTER:
case BOTTOM_RIGHT:
case BOTTOM_LEFT:
return v.getHeight();
default:
}
return 0;
}
public interface Action {
void onStart();
void onEnd();
}
private boolean isLessThan21() {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment