Skip to content

Instantly share code, notes, and snippets.

@zaki50
Last active August 29, 2015 14:03
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zaki50/ef19470980eb2be977f4 to your computer and use it in GitHub Desktop.
Save zaki50/ef19470980eb2be977f4 to your computer and use it in GitHub Desktop.
Material Design の FloatingActionButton のためのクラスを作ってみた
<!-- 使い方はこんな感じ -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin">
<com.uphyca.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:src="@drawable/ic_action_new"/>
</RelativeLayout>
/*
* Copyright (C) 2014 uPhyca Inc.
*
* 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.
*/
package com.uphyca.widget;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.StateListAnimator;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.Outline;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.RippleDrawable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.widget.ImageButton;
/**
* FloatingActionButton のための UI パーツです。
*
* 以下の様な感じで使います。
* <pre>
* &lt;com.uphyca.widget.FloatingActionButton
* android:id="@+id/fab"
* android:layout_width="56dp"
* android:layout_height="56dp"
* android:src="@drawable/ic_action_new"/&gt;
* </pre>
*/
public class FloatingActionButton extends ImageButton {
private static final int DEFAULT_ELEVATION_IN_DP = 2;
private static final int DEFAULT_PRESSED_ELEVATION_IN_DP = 4;
public FloatingActionButton(Context context) {
super(context);
init(context);
}
public FloatingActionButton(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public FloatingActionButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public FloatingActionButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
private void init(Context context) {
final DisplayMetrics dm = context.getResources().getDisplayMetrics();
final float scale = dm.density;
final int elevation = (int) (DEFAULT_ELEVATION_IN_DP * scale + .5f);
final int pressedElevation = (int) (DEFAULT_PRESSED_ELEVATION_IN_DP * scale + .5f);
final long duration = context.getResources().getInteger(android.R.integer.config_shortAnimTime);
setElevation(elevation);
initElevationAnimator(elevation, pressedElevation, duration);
final int colorAccentValue;
final int colorControlHighlightValue;
if (isInEditMode()) {
colorAccentValue = 0xff03a9f4;
colorControlHighlightValue = 0x20444444;
} else {
final Resources.Theme theme = context.getTheme();
final TypedValue outValue = new TypedValue();
theme.resolveAttribute(android.R.attr.colorAccent, outValue, true);
colorAccentValue = outValue.data;
theme.resolveAttribute(android.R.attr.colorControlHighlight, outValue, true);
colorControlHighlightValue = outValue.data;
}
final GradientDrawable ovalBackground = new GradientDrawable();
ovalBackground.setShape(GradientDrawable.OVAL);
ovalBackground.setColor(colorAccentValue);
final RippleDrawable rippleDrawable = new RippleDrawable(ovalBackground, ovalBackground);
final ColorStateList rippleColors = new ColorStateList(new int[][]{EMPTY_STATE_SET}, new int[]{colorControlHighlightValue});
rippleDrawable.setColor(rippleColors);
setBackground(rippleDrawable);
}
private void initElevationAnimator(float elevation, float pressedElevation, long duration) {
final Animator onPressedAnimator = ObjectAnimator.ofFloat(this, "translationZ",
elevation, pressedElevation);
onPressedAnimator.setStartDelay(0L);
onPressedAnimator.setDuration(duration);
final Animator defaultAnimator = ObjectAnimator.ofFloat(this, "translationZ",
pressedElevation, elevation);
defaultAnimator.setStartDelay(0L);
defaultAnimator.setDuration(duration);
final StateListAnimator slm = new StateListAnimator();
slm.addState(PRESSED_ENABLED_STATE_SET, onPressedAnimator);
slm.addState(EMPTY_STATE_SET, defaultAnimator);
setStateListAnimator(slm);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
final Outline outline = new Outline();
outline.setOval(0, 0, w, h);
setOutline(outline);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment