Created
April 10, 2016 12:07
-
-
Save vedhavyas/b6a97eed865433abb8e982bf865f9f15 to your computer and use it in GitHub Desktop.
Android Floating label
This file contains hidden or 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.instamojo.mink.services; | |
import android.animation.ValueAnimator; | |
import android.app.Service; | |
import android.content.Context; | |
import android.content.Intent; | |
import android.graphics.PixelFormat; | |
import android.graphics.Point; | |
import android.os.IBinder; | |
import android.view.Gravity; | |
import android.view.MotionEvent; | |
import android.view.View; | |
import android.view.WindowManager; | |
import android.widget.ImageView; | |
import com.instamojo.mink.R; | |
import com.instamojo.mink.helpers.Logger; | |
public class FloatingService extends Service { | |
WindowManager.LayoutParams params; | |
private WindowManager windowManager; | |
private ImageView floatingView; | |
private Point defaultSize; | |
public FloatingService() { | |
} | |
public static void startService(Context context) { | |
Intent intent = new Intent(context, FloatingService.class); | |
context.startService(intent); | |
} | |
@Override | |
public void onCreate() { | |
super.onCreate(); | |
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); | |
defaultSize = new Point(); | |
windowManager.getDefaultDisplay().getSize(defaultSize); | |
floatingView = new ImageView(this); | |
floatingView.setImageResource(R.drawable.ic_mink_icon); | |
params = new WindowManager.LayoutParams( | |
WindowManager.LayoutParams.WRAP_CONTENT, | |
WindowManager.LayoutParams.WRAP_CONTENT, | |
WindowManager.LayoutParams.TYPE_PRIORITY_PHONE, | |
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, | |
PixelFormat.TRANSLUCENT); | |
params.gravity = Gravity.START; | |
params.x = defaultSize.x - floatingView.getWidth(); | |
params.y = 0; | |
floatingView.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
Logger.log("clicked"); | |
} | |
}); | |
floatingView.setOnTouchListener(new View.OnTouchListener() { | |
private int initialX; | |
private int initialY; | |
private float initialTouchX; | |
private float initialTouchY; | |
private long dropTime; | |
@Override | |
public boolean onTouch(View v, MotionEvent event) { | |
switch (event.getAction()) { | |
case MotionEvent.ACTION_DOWN: | |
dropTime = System.currentTimeMillis(); | |
initialX = params.x; | |
initialY = params.y; | |
if (params.x > defaultSize.x - floatingView.getWidth()) { | |
initialX = defaultSize.x - floatingView.getWidth(); | |
} | |
if (params.x < 0) { | |
initialX = 0; | |
} | |
if (params.y > defaultSize.y / 2 - floatingView.getHeight() / 2) { | |
initialY = defaultSize.y / 2 - floatingView.getHeight() / 2; | |
} | |
if (params.y < -defaultSize.y / 2 + floatingView.getHeight() / 2) { | |
initialY = -defaultSize.y / 2 + floatingView.getHeight() / 2; | |
} | |
initialTouchX = event.getRawX(); | |
initialTouchY = event.getRawY(); | |
return true; | |
case MotionEvent.ACTION_UP: | |
if (System.currentTimeMillis() - dropTime < 200) { | |
floatingView.performClick(); | |
} | |
int finalX; | |
if (params.x + floatingView.getWidth() / 2 >= defaultSize.x / 2) { | |
finalX = defaultSize.x - floatingView.getWidth(); | |
} else { | |
finalX = 0; | |
} | |
overlayAnimation(floatingView, params.x, finalX); | |
return true; | |
case MotionEvent.ACTION_MOVE: | |
params.x = initialX | |
+ (int) (event.getRawX() - initialTouchX); | |
params.y = initialY | |
+ (int) (event.getRawY() - initialTouchY); | |
windowManager.updateViewLayout(floatingView, params); | |
return true; | |
} | |
return false; | |
} | |
}); | |
windowManager.addView(floatingView, params); | |
} | |
private void overlayAnimation(final View view2animate, int viewX, int endX) { | |
ValueAnimator translateLeft = ValueAnimator.ofInt(viewX, endX); | |
translateLeft.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { | |
@Override | |
public void onAnimationUpdate(ValueAnimator valueAnimator) { | |
params.x = (Integer) valueAnimator.getAnimatedValue(); | |
windowManager.updateViewLayout(view2animate, params); | |
} | |
}); | |
translateLeft.setDuration(200); | |
translateLeft.start(); | |
} | |
@Override | |
public void onDestroy() { | |
if (floatingView != null) { | |
windowManager.removeView(floatingView); | |
} | |
super.onDestroy(); | |
} | |
@Override | |
public IBinder onBind(Intent intent) { | |
return null; | |
} | |
} | |
//Permissions in Manifest | |
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment