From 8f3427af652bd0f0dfb382a8fcf2945f9a996e0f Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 11 Dec 2014 12:38:15 +0200 Subject: [PATCH] Added floating button --- .../plus/activities/MainMenuActivity.java | 29 ++- .../views/controls/FloatingActionButton.java | 193 ++++++++++++++++++ 2 files changed, 219 insertions(+), 3 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/views/controls/FloatingActionButton.java diff --git a/OsmAnd/src/net/osmand/plus/activities/MainMenuActivity.java b/OsmAnd/src/net/osmand/plus/activities/MainMenuActivity.java index 37eaf5f83d..f09786ecc6 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MainMenuActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MainMenuActivity.java @@ -6,6 +6,9 @@ import java.lang.ref.WeakReference; import java.util.List; import java.util.Random; +import android.graphics.Color; +import android.os.Build; +import android.view.Gravity; import net.osmand.access.AccessibleAlertBuilder; import net.osmand.plus.OsmAndAppCustomization; import net.osmand.plus.OsmAndLocationProvider; @@ -49,6 +52,7 @@ import android.widget.TextView; import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.MenuItem; +import net.osmand.plus.views.controls.FloatingActionButton; /** */ @@ -101,6 +105,21 @@ public class MainMenuActivity extends BaseDownloadActivity { boolean firstTime = initApp(this, getMyApplication()); addFragments(firstTime); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + FloatingActionButton fabButton = new FloatingActionButton.Builder(this) + .withDrawable(getResources().getDrawable(R.drawable.ic_ac_settings)) + .withButtonColor(Color.WHITE) + .withGravity(Gravity.BOTTOM | Gravity.RIGHT) + .withMargins(0, 0, 16, 16) + .create(); + fabButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + startMapActivity(); + } + }); + } } @Override @@ -248,8 +267,7 @@ public class MainMenuActivity extends BaseDownloadActivity { final OsmAndAppCustomization appCustomization = app.getAppCustomization(); // restore follow route mode if(app.getSettings().FOLLOW_THE_ROUTE.get() && !app.getRoutingHelper().isRouteCalculated()){ - final Intent mapIndent = new Intent(this, appCustomization.getMapActivity()); - startActivityForResult(mapIndent, 0); + startMapActivity(); return false; } boolean firstTime = false; @@ -290,7 +308,12 @@ public class MainMenuActivity extends BaseDownloadActivity { return firstTime; } - + + private void startMapActivity() { + final Intent mapIndent = new Intent(this, getMyApplication().getAppCustomization().getMapActivity()); + startActivityForResult(mapIndent, 0); + } + private void applicationInstalledFirstTime() { boolean netOsmandWasInstalled = false; try { diff --git a/OsmAnd/src/net/osmand/plus/views/controls/FloatingActionButton.java b/OsmAnd/src/net/osmand/plus/views/controls/FloatingActionButton.java new file mode 100644 index 0000000000..1fc45a8724 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/views/controls/FloatingActionButton.java @@ -0,0 +1,193 @@ +package net.osmand.plus.views.controls; + +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.app.Activity; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.view.Gravity; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.OvershootInterpolator; +import android.widget.FrameLayout; + +/* +* Created by John Hogan +* https://gist.github.com/Jogan/9def6110edf3247825c9 + */ + +public class FloatingActionButton extends View { + + final static OvershootInterpolator overshootInterpolator = new OvershootInterpolator(); + final static AccelerateInterpolator accelerateInterpolator = new AccelerateInterpolator(); + + Context context; + Paint mButtonPaint; + Paint mDrawablePaint; + Bitmap mBitmap; + boolean mHidden = false; + + public FloatingActionButton(Context context) { + super(context); + this.context = context; + init(Color.WHITE); + } + + public void setFloatingActionButtonColor(int FloatingActionButtonColor) { + init(FloatingActionButtonColor); + } + + public void setFloatingActionButtonDrawable(Drawable FloatingActionButtonDrawable) { + mBitmap = ((BitmapDrawable) FloatingActionButtonDrawable).getBitmap(); + invalidate(); + } + + public void init(int FloatingActionButtonColor) { + setWillNotDraw(false); + setLayerType(View.LAYER_TYPE_SOFTWARE, null); + + mButtonPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + mButtonPaint.setColor(FloatingActionButtonColor); + mButtonPaint.setStyle(Paint.Style.FILL); + mButtonPaint.setShadowLayer(10.0f, 0.0f, 3.5f, Color.argb(100, 0, 0, 0)); + mDrawablePaint = new Paint(Paint.ANTI_ALIAS_FLAG); + + invalidate(); + } + + @Override + protected void onDraw(Canvas canvas) { + setClickable(true); + canvas.drawCircle(getWidth() / 2, getHeight() / 2, (float) (getWidth() / 2.6), mButtonPaint); + canvas.drawBitmap(mBitmap, (getWidth() - mBitmap.getWidth()) / 2, + (getHeight() - mBitmap.getHeight()) / 2, mDrawablePaint); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_UP) { + setAlpha(1.0f); + } else if (event.getAction() == MotionEvent.ACTION_DOWN) { + setAlpha(0.6f); + } + return super.onTouchEvent(event); + } + + public void hideFloatingActionButton() { + if (!mHidden) { + ObjectAnimator scaleX = ObjectAnimator.ofFloat(this, "scaleX", 1, 0); + ObjectAnimator scaleY = ObjectAnimator.ofFloat(this, "scaleY", 1, 0); + AnimatorSet animSetXY = new AnimatorSet(); + animSetXY.playTogether(scaleX, scaleY); + animSetXY.setInterpolator(accelerateInterpolator); + animSetXY.setDuration(100); + animSetXY.start(); + mHidden = true; + } + } + + public void showFloatingActionButton() { + if (mHidden) { + ObjectAnimator scaleX = ObjectAnimator.ofFloat(this, "scaleX", 0, 1); + ObjectAnimator scaleY = ObjectAnimator.ofFloat(this, "scaleY", 0, 1); + AnimatorSet animSetXY = new AnimatorSet(); + animSetXY.playTogether(scaleX, scaleY); + animSetXY.setInterpolator(overshootInterpolator); + animSetXY.setDuration(200); + animSetXY.start(); + mHidden = false; + } + } + + public boolean isHidden() { + return mHidden; + } + + static public class Builder { + private FrameLayout.LayoutParams params; + private final Activity activity; + int gravity = Gravity.BOTTOM | Gravity.RIGHT; // default bottom right + Drawable drawable; + int color = Color.WHITE; + int size = 0; + float scale = 0; + + public Builder(Activity context) { + scale = context.getResources().getDisplayMetrics().density; + size = convertToPixels(72, scale); // default size is 72dp by 72dp + params = new FrameLayout.LayoutParams(size, size); + params.gravity = gravity; + + this.activity = context; + } + + /** + * Sets the gravity for the FAB + */ + public Builder withGravity(int gravity) { + this.gravity = gravity; + return this; + } + + /** + * Sets the margins for the FAB in dp + */ + public Builder withMargins(int left, int top, int right, int bottom) { + params.setMargins( + convertToPixels(left, scale), + convertToPixels(top, scale), + convertToPixels(right, scale), + convertToPixels(bottom, scale)); + return this; + } + + /** + * Sets the FAB drawable + */ + public Builder withDrawable(final Drawable drawable) { + this.drawable = drawable; + return this; + } + + /** + * Sets the FAB color + */ + public Builder withButtonColor(final int color) { + this.color = color; + return this; + } + + /** + * Sets the FAB size in dp + */ + public Builder withButtonSize(int size) { + size = convertToPixels(size, scale); + params = new FrameLayout.LayoutParams(size, size); + return this; + } + + public FloatingActionButton create() { + final FloatingActionButton button = new FloatingActionButton(activity); + button.setFloatingActionButtonColor(this.color); + button.setFloatingActionButtonDrawable(this.drawable); + params.gravity = this.gravity; + ViewGroup root = (ViewGroup) activity.findViewById(android.R.id.content); + root.addView(button, params); + return button; + } + + // The calculation (value * scale + 0.5f) is a widely used to convert to dps to pixel units + // based on density scale + // see developer.android.com (Supporting Multiple Screen Sizes) + private int convertToPixels(int dp, float scale){ + return (int) (dp * scale + 0.5f) ; + } + } +}