/* * Copyright 2014 Oguz Bilgener */ package com.marshalchen.common.uimodule.circularfloatingactionmenu; import android.app.Activity; import android.content.Context; import android.graphics.drawable.Drawable; import android.os.Build; import android.util.AttributeSet; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import com.marshalchen.common.uimodule.R; /** * An alternative Floating Action Button implementation that can be independently placed in * one of 8 different places on the screen. */ public class FloatingActionButton extends FrameLayout { public static final int THEME_LIGHT = 0; public static final int THEME_DARK = 1; public static final int POSITION_TOP_CENTER = 1; public static final int POSITION_TOP_RIGHT = 2; public static final int POSITION_RIGHT_CENTER = 3; public static final int POSITION_BOTTOM_RIGHT = 4; public static final int POSITION_BOTTOM_CENTER = 5; public static final int POSITION_BOTTOM_LEFT = 6; public static final int POSITION_LEFT_CENTER = 7; public static final int POSITION_TOP_LEFT = 8; private View contentView; /** * Constructor that takes parameters collected using {@link FloatingActionMenu.Builder} * @param activity a reference to the activity that will * @param layoutParams * @param theme * @param backgroundDrawable * @param position * @param contentView * @param contentParams */ public FloatingActionButton(Activity activity, LayoutParams layoutParams, int theme, Drawable backgroundDrawable, int position, View contentView, FrameLayout.LayoutParams contentParams) { super(activity); setPosition(position, layoutParams); // If no custom backgroundDrawable is specified, use the background drawable of the theme. if(backgroundDrawable == null) { if(theme == THEME_LIGHT) backgroundDrawable = activity.getResources().getDrawable(R.drawable.floating_menu_button_action_selector); else backgroundDrawable = activity.getResources().getDrawable(R.drawable.floating_menu_button_action_dark_selector); } setBackgroundResource(backgroundDrawable); if(contentView != null) { setContentView(contentView, contentParams); } setClickable(true); attach(layoutParams); } /** * Sets the position of the button by calculating its Gravity from the position parameter * @param position one of 8 specified positions. * @param layoutParams */ public void setPosition(int position, FrameLayout.LayoutParams layoutParams) { int gravity; switch(position) { case POSITION_TOP_CENTER: gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL; break; case POSITION_TOP_RIGHT: gravity = Gravity.TOP | Gravity.RIGHT; break; case POSITION_RIGHT_CENTER: gravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL; break; case POSITION_BOTTOM_CENTER: gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; break; case POSITION_BOTTOM_LEFT: gravity = Gravity.BOTTOM | Gravity.LEFT; break; case POSITION_LEFT_CENTER: gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL; break; case POSITION_TOP_LEFT: gravity = Gravity.TOP | Gravity.LEFT; break; case POSITION_BOTTOM_RIGHT: default: gravity = Gravity.BOTTOM | Gravity.RIGHT; break; } layoutParams.gravity = gravity; setLayoutParams(layoutParams); } /** * Sets a content view that will be displayed inside this FloatingActionButton. * @param contentView */ public void setContentView(View contentView, FrameLayout.LayoutParams contentParams) { this.contentView = contentView; FrameLayout.LayoutParams params; if(contentParams == null ){ params =new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, Gravity.CENTER); final int margin = getResources().getDimensionPixelSize(R.dimen.action_button_content_margin); params.setMargins(margin, margin, margin, margin); } else { params = contentParams; } params.gravity = Gravity.CENTER; contentView.setClickable(false); this.addView(contentView, params); } /** * Attaches it to the Activity content view with specified LayoutParams. * @param layoutParams */ public void attach(FrameLayout.LayoutParams layoutParams) { ((ViewGroup)getActivityContentView()).addView(this, layoutParams); } /** * Detaches it from the Activity content view. */ public void detach() { ((ViewGroup)getActivityContentView()).removeView(this); } /** * Finds and returns the main content view from the Activity context. * @return the main content view */ public View getActivityContentView() { return ((Activity)getContext()).getWindow().getDecorView().findViewById(android.R.id.content); } private void setBackgroundResource(Drawable drawable) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { setBackground(drawable); } else { setBackgroundDrawable(drawable); } } /** * A builder for {@link com.marshalchen.common.uimodule.circularfloatingactionmenu.FloatingActionButton} in conventional Java Builder format */ public static class Builder { private Activity activity; private LayoutParams layoutParams; private int theme; private Drawable backgroundDrawable; private int position; private View contentView; private LayoutParams contentParams; public Builder(Activity activity) { this.activity = activity; // Default FloatingActionButton settings int size = activity.getResources().getDimensionPixelSize(R.dimen.action_button_size); int margin = activity.getResources().getDimensionPixelSize(R.dimen.action_button_margin); LayoutParams layoutParams = new LayoutParams(size, size, Gravity.BOTTOM | Gravity.RIGHT); layoutParams.setMargins(margin, margin, margin, margin); setLayoutParams(layoutParams); setTheme(FloatingActionButton.THEME_LIGHT); setPosition(FloatingActionButton.POSITION_BOTTOM_RIGHT); } public Builder setLayoutParams(LayoutParams params) { this.layoutParams = params; return this; } public Builder setTheme(int theme) { this.theme = theme; return this; } public Builder setBackgroundDrawable(Drawable backgroundDrawable) { this.backgroundDrawable = backgroundDrawable; return this; } public Builder setBackgroundDrawable(int drawableId) { return setBackgroundDrawable(activity.getResources().getDrawable(drawableId)); } public Builder setPosition(int position) { this.position = position; return this; } public Builder setContentView(View contentView) { return setContentView(contentView, null); } public Builder setContentView(View contentView, LayoutParams contentParams) { this.contentView = contentView; this.contentParams = contentParams; return this; } public FloatingActionButton build() { return new FloatingActionButton(activity, layoutParams, theme, backgroundDrawable, position, contentView, contentParams); } } /** * An alias for the FrameLayout.LayoutParams, which is intended to be used * while setting Layout parameters to the contentView */ public static class LayoutParams extends FrameLayout.LayoutParams { public LayoutParams(Context c, AttributeSet attrs) { super(c, attrs); } public LayoutParams(int width, int height) { super(width, height); } public LayoutParams(int width, int height, int gravity) { super(width, height, gravity); } public LayoutParams(ViewGroup.LayoutParams source) { super(source); } public LayoutParams(MarginLayoutParams source) { super(source); } } }