parent
0b4a19b2d0
commit
7d2e5a0e52
@ -1,81 +0,0 @@ |
||||
package com.frank.ffmpeg.floating; |
||||
|
||||
import android.app.Activity; |
||||
import android.content.Context; |
||||
import android.content.Intent; |
||||
import android.net.Uri; |
||||
import android.os.Build; |
||||
import android.os.Bundle; |
||||
import android.support.annotation.RequiresApi; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 用于在内部自动申请权限 |
||||
* https://github.com/yhaolpz
|
||||
*/ |
||||
|
||||
public class FloatActivity extends Activity { |
||||
|
||||
private static List<PermissionListener> mPermissionListenerList; |
||||
|
||||
@Override |
||||
protected void onCreate(Bundle savedInstanceState) { |
||||
super.onCreate(savedInstanceState); |
||||
if (Build.VERSION.SDK_INT >= 23){ |
||||
requestAlertWindowPermission(); |
||||
} |
||||
} |
||||
|
||||
@RequiresApi(api = 23) |
||||
private void requestAlertWindowPermission() { |
||||
Intent intent = new Intent("android.settings.action.MANAGE_OVERLAY_PERMISSION"); |
||||
intent.setData(Uri.parse("package:" + getPackageName())); |
||||
startActivityForResult(intent, 123); |
||||
} |
||||
|
||||
|
||||
@RequiresApi(api = 23) |
||||
@Override |
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) { |
||||
super.onActivityResult(requestCode, resultCode, data); |
||||
if (Build.VERSION.SDK_INT >= 23){ |
||||
//todo 用23以上编译即可出现canDrawOverlays
|
||||
if (Util.hasPermission(this)) { |
||||
mPermissionListener.onSuccess(); |
||||
} else { |
||||
mPermissionListener.onFail(); |
||||
} |
||||
} |
||||
finish(); |
||||
} |
||||
|
||||
static synchronized void request(Context context, PermissionListener permissionListener) { |
||||
if (mPermissionListenerList == null) { |
||||
mPermissionListenerList = new ArrayList<>(); |
||||
mPermissionListener = new PermissionListener() { |
||||
@Override |
||||
public void onSuccess() { |
||||
for (PermissionListener listener : mPermissionListenerList) { |
||||
listener.onSuccess(); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void onFail() { |
||||
for (PermissionListener listener : mPermissionListenerList) { |
||||
listener.onFail(); |
||||
} |
||||
} |
||||
}; |
||||
Intent intent = new Intent(context, FloatActivity.class); |
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
||||
context.startActivity(intent); |
||||
} |
||||
mPermissionListenerList.add(permissionListener); |
||||
} |
||||
|
||||
|
||||
private static PermissionListener mPermissionListener; |
||||
} |
@ -1,114 +0,0 @@ |
||||
package com.frank.ffmpeg.floating; |
||||
|
||||
import android.app.Activity; |
||||
import android.app.Application; |
||||
import android.content.BroadcastReceiver; |
||||
import android.content.Context; |
||||
import android.content.Intent; |
||||
import android.content.IntentFilter; |
||||
import android.os.Bundle; |
||||
import android.os.Handler; |
||||
|
||||
/** |
||||
* Created by yhao on 17-12-1. |
||||
* 用于控制悬浮窗显示周期 |
||||
* 使用了三种方法针对返回桌面时隐藏悬浮按钮 |
||||
* 1.startCount计数,针对back到桌面可以及时隐藏 |
||||
* 2.监听home键,从而及时隐藏 |
||||
* 3.resumeCount计时,针对一些只执行onPause不执行onStop的奇葩情况 |
||||
*/ |
||||
|
||||
class FloatLifecycle extends BroadcastReceiver implements Application.ActivityLifecycleCallbacks { |
||||
|
||||
private static final long delay = 300; |
||||
private Handler mHandler; |
||||
private Class[] activities; |
||||
private boolean showFlag; |
||||
private int resumeCount; |
||||
private boolean appBackground; |
||||
private LifecycleListener mLifecycleListener; |
||||
|
||||
|
||||
FloatLifecycle(Context applicationContext, boolean showFlag, Class[] activities, LifecycleListener lifecycleListener) { |
||||
this.showFlag = showFlag; |
||||
this.activities = activities; |
||||
mLifecycleListener = lifecycleListener; |
||||
mHandler = new Handler(); |
||||
((Application) applicationContext).registerActivityLifecycleCallbacks(this); |
||||
applicationContext.registerReceiver(this, new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); |
||||
} |
||||
|
||||
|
||||
private boolean needShow(Activity activity) { |
||||
if (activities == null) { |
||||
return true; |
||||
} |
||||
for (Class a : activities) { |
||||
if (a.isInstance(activity)) { |
||||
return showFlag; |
||||
} |
||||
} |
||||
return !showFlag; |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void onActivityResumed(Activity activity) { |
||||
resumeCount++; |
||||
if (needShow(activity)) { |
||||
mLifecycleListener.onShow(); |
||||
} |
||||
|
||||
if (appBackground) { |
||||
appBackground = false; |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void onActivityPaused(Activity activity) { |
||||
resumeCount--; |
||||
mHandler.postDelayed(new Runnable() { |
||||
@Override |
||||
public void run() { |
||||
if (resumeCount == 0) { |
||||
appBackground = true; |
||||
//mLifecycleListener.onPostHide();
|
||||
} |
||||
} |
||||
}, delay); |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void onActivityStarted(Activity activity) { |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void onActivityStopped(Activity activity) { |
||||
} |
||||
|
||||
@Override |
||||
public void onReceive(Context context, Intent intent) { |
||||
|
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void onActivityCreated(Activity activity, Bundle savedInstanceState) { |
||||
|
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void onActivitySaveInstanceState(Activity activity, Bundle outState) { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void onActivityDestroyed(Activity activity) { |
||||
|
||||
} |
||||
|
||||
|
||||
} |
@ -1,111 +0,0 @@ |
||||
package com.frank.ffmpeg.floating; |
||||
|
||||
import android.content.Context; |
||||
import android.graphics.PixelFormat; |
||||
import android.os.Build; |
||||
import android.view.View; |
||||
import android.view.WindowManager; |
||||
|
||||
/** |
||||
* Created by yhao on 17-11-14. |
||||
* 7.1及以上需申请权限 |
||||
*/ |
||||
|
||||
class FloatPhone extends FloatView { |
||||
|
||||
private final Context mContext; |
||||
|
||||
private final WindowManager mWindowManager; |
||||
private final WindowManager.LayoutParams mLayoutParams; |
||||
private View mView; |
||||
private int mX, mY; |
||||
|
||||
FloatPhone(Context applicationContext) { |
||||
mContext = applicationContext; |
||||
mWindowManager = (WindowManager) applicationContext.getSystemService(Context.WINDOW_SERVICE); |
||||
mLayoutParams = new WindowManager.LayoutParams(); |
||||
} |
||||
|
||||
@Override |
||||
public void setSize(int width, int height) { |
||||
mLayoutParams.width = width; |
||||
mLayoutParams.height = height; |
||||
} |
||||
|
||||
@Override |
||||
public void setView(View view) { |
||||
int layout_type; |
||||
layout_type = WindowManager.LayoutParams.TYPE_PHONE; |
||||
mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
||||
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; |
||||
mLayoutParams.type = layout_type; |
||||
mLayoutParams.windowAnimations = 0; |
||||
mView = view; |
||||
} |
||||
|
||||
@Override |
||||
public void setGravity(int gravity, int xOffset, int yOffset) { |
||||
mLayoutParams.gravity = gravity; |
||||
mLayoutParams.x = mX = xOffset; |
||||
mLayoutParams.y = mY = yOffset; |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void init() { |
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { |
||||
if (Util.hasPermission(mContext)) { |
||||
mLayoutParams.format = PixelFormat.RGBA_8888; |
||||
mWindowManager.addView(mView, mLayoutParams); |
||||
} else { |
||||
FloatActivity.request(mContext, new PermissionListener() { |
||||
@Override |
||||
public void onSuccess() { |
||||
mLayoutParams.format = PixelFormat.RGBA_8888; |
||||
mWindowManager.addView(mView, mLayoutParams); |
||||
} |
||||
|
||||
@Override |
||||
public void onFail() { |
||||
|
||||
} |
||||
}); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void dismiss() { |
||||
mWindowManager.removeView(mView); |
||||
} |
||||
|
||||
@Override |
||||
public void updateXY(int x, int y) { |
||||
mLayoutParams.x = mX = x; |
||||
mLayoutParams.y = mY = y; |
||||
mWindowManager.updateViewLayout(mView, mLayoutParams); |
||||
} |
||||
|
||||
@Override |
||||
void updateX(int x) { |
||||
mLayoutParams.x = mX = x; |
||||
mWindowManager.updateViewLayout(mView, mLayoutParams); |
||||
|
||||
} |
||||
|
||||
@Override |
||||
void updateY(int y) { |
||||
mLayoutParams.y = mY = y; |
||||
mWindowManager.updateViewLayout(mView, mLayoutParams); |
||||
} |
||||
|
||||
@Override |
||||
int getX() { |
||||
return mX; |
||||
} |
||||
|
||||
@Override |
||||
int getY() { |
||||
return mY; |
||||
} |
||||
} |
@ -1,64 +0,0 @@ |
||||
package com.frank.ffmpeg.floating; |
||||
|
||||
import android.content.Context; |
||||
import android.util.AttributeSet; |
||||
import android.view.Gravity; |
||||
import android.view.ViewGroup; |
||||
import android.widget.FrameLayout; |
||||
import android.widget.VideoView; |
||||
|
||||
|
||||
public class FloatPlayerView extends FrameLayout { |
||||
|
||||
private final static String VIDEO_PATH = "rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov"; |
||||
// private final static String VIDEO_PATH = "storage/emulated/0/beyond.mp4";
|
||||
|
||||
private VideoView mPlayer; |
||||
|
||||
public FloatPlayerView(Context context) { |
||||
super(context); |
||||
init(context); |
||||
} |
||||
|
||||
public FloatPlayerView(Context context, AttributeSet attrs) { |
||||
super(context, attrs); |
||||
init(context); |
||||
} |
||||
|
||||
public FloatPlayerView(Context context, AttributeSet attrs, int defStyleAttr) { |
||||
super(context, attrs, defStyleAttr); |
||||
init(context); |
||||
} |
||||
|
||||
private void init(Context context) { |
||||
mPlayer = new VideoView(context); |
||||
|
||||
LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); |
||||
layoutParams.gravity = Gravity.CENTER; |
||||
addView(mPlayer, layoutParams); |
||||
|
||||
mPlayer.setVideoPath(VIDEO_PATH); |
||||
mPlayer.requestFocus(); |
||||
mPlayer.start(); |
||||
} |
||||
|
||||
|
||||
public void onPause() { |
||||
if (mPlayer != null){ |
||||
mPlayer.pause(); |
||||
} |
||||
} |
||||
|
||||
public void onResume() { |
||||
if (mPlayer != null){ |
||||
mPlayer.resume(); |
||||
} |
||||
} |
||||
|
||||
public void onDestroy(){ |
||||
if (mPlayer != null){ |
||||
mPlayer.stopPlayback(); |
||||
mPlayer = null; |
||||
} |
||||
} |
||||
} |
@ -1,96 +0,0 @@ |
||||
package com.frank.ffmpeg.floating; |
||||
|
||||
import android.content.Context; |
||||
import android.view.View; |
||||
import android.view.WindowManager; |
||||
import android.widget.Toast; |
||||
|
||||
import java.lang.reflect.Field; |
||||
import java.lang.reflect.Method; |
||||
|
||||
/** |
||||
* 自定义 toast 方式,无需申请权限 |
||||
*/ |
||||
|
||||
class FloatToast extends FloatView { |
||||
|
||||
|
||||
private Toast toast; |
||||
|
||||
private Object mTN; |
||||
private Method show; |
||||
private Method hide; |
||||
|
||||
private int mWidth; |
||||
private int mHeight; |
||||
|
||||
|
||||
FloatToast(Context applicationContext) { |
||||
toast = new Toast(applicationContext); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void setSize(int width, int height) { |
||||
mWidth = width; |
||||
mHeight = height; |
||||
} |
||||
|
||||
@Override |
||||
public void setView(View view) { |
||||
toast.setView(view); |
||||
initTN(); |
||||
} |
||||
|
||||
@Override |
||||
public void setGravity(int gravity, int xOffset, int yOffset) { |
||||
toast.setGravity(gravity, xOffset, yOffset); |
||||
} |
||||
|
||||
@Override |
||||
public void init() { |
||||
try { |
||||
show.invoke(mTN); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void dismiss() { |
||||
try { |
||||
hide.invoke(mTN); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
|
||||
|
||||
private void initTN() { |
||||
try { |
||||
//todo android P test
|
||||
Field tnField = toast.getClass().getDeclaredField("mTN"); |
||||
tnField.setAccessible(true); |
||||
mTN = tnField.get(toast); |
||||
show = mTN.getClass().getMethod("show"); |
||||
hide = mTN.getClass().getMethod("hide"); |
||||
|
||||
Field tnParamsField = mTN.getClass().getDeclaredField("mParams"); |
||||
tnParamsField.setAccessible(true); |
||||
WindowManager.LayoutParams params = (WindowManager.LayoutParams) tnParamsField.get(mTN); |
||||
params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
||||
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; |
||||
params.width = mWidth; |
||||
params.height = mHeight; |
||||
params.windowAnimations = 0; |
||||
Field tnNextViewField = mTN.getClass().getDeclaredField("mNextView"); |
||||
tnNextViewField.setAccessible(true); |
||||
tnNextViewField.set(mTN, toast.getView()); |
||||
|
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
|
||||
|
||||
} |
@ -1,38 +0,0 @@ |
||||
package com.frank.ffmpeg.floating; |
||||
|
||||
import android.view.View; |
||||
|
||||
/** |
||||
* Created by yhao on 17-11-14. |
||||
* https://github.com/yhaolpz
|
||||
*/ |
||||
|
||||
abstract class FloatView { |
||||
|
||||
abstract void setSize(int width, int height); |
||||
|
||||
abstract void setView(View view); |
||||
|
||||
abstract void setGravity(int gravity, int xOffset, int yOffset); |
||||
|
||||
abstract void init(); |
||||
|
||||
abstract void dismiss(); |
||||
|
||||
void updateXY(int x, int y) { |
||||
} |
||||
|
||||
void updateX(int x) { |
||||
} |
||||
|
||||
void updateY(int y) { |
||||
} |
||||
|
||||
int getX() { |
||||
return 0; |
||||
} |
||||
|
||||
int getY() { |
||||
return 0; |
||||
} |
||||
} |
@ -1,30 +0,0 @@ |
||||
package com.frank.ffmpeg.floating; |
||||
|
||||
import android.view.View; |
||||
|
||||
/** |
||||
* Created by yhao on 2017/12/22. |
||||
* https://github.com/yhaolpz
|
||||
*/ |
||||
|
||||
public abstract class IFloatWindow { |
||||
public abstract void show(); |
||||
|
||||
public abstract void hide(); |
||||
|
||||
public abstract int getX(); |
||||
|
||||
public abstract int getY(); |
||||
|
||||
public abstract void updateX(int x); |
||||
|
||||
public abstract void updateX(@Screen.screenType int screenType,float ratio); |
||||
|
||||
public abstract void updateY(int y); |
||||
|
||||
public abstract void updateY(@Screen.screenType int screenType,float ratio); |
||||
|
||||
public abstract View getView(); |
||||
|
||||
abstract void dismiss(); |
||||
} |
@ -1,248 +0,0 @@ |
||||
package com.frank.ffmpeg.floating; |
||||
|
||||
import android.animation.Animator; |
||||
import android.animation.AnimatorListenerAdapter; |
||||
import android.animation.ObjectAnimator; |
||||
import android.animation.PropertyValuesHolder; |
||||
import android.animation.TimeInterpolator; |
||||
import android.animation.ValueAnimator; |
||||
import android.os.Build; |
||||
import android.view.MotionEvent; |
||||
import android.view.View; |
||||
import android.view.animation.DecelerateInterpolator; |
||||
|
||||
/** |
||||
* Created by yhao on 2017/12/22. |
||||
* https://github.com/yhaolpz
|
||||
*/ |
||||
|
||||
public class IFloatWindowImpl extends IFloatWindow { |
||||
|
||||
|
||||
private FloatWindow.WindowBuilder mB; |
||||
private FloatView mFloatView; |
||||
private boolean isShow; |
||||
private boolean once = true; |
||||
private ValueAnimator mAnimator; |
||||
private TimeInterpolator mDecelerateInterpolator; |
||||
|
||||
IFloatWindowImpl(FloatWindow.WindowBuilder b) { |
||||
mB = b; |
||||
if (mB.mMoveType == MoveType.fixed) { |
||||
if (Build.VERSION.SDK_INT >=25) { |
||||
mFloatView = new FloatPhone(b.mApplicationContext); |
||||
} else { |
||||
mFloatView = new FloatToast(b.mApplicationContext); |
||||
} |
||||
} else { |
||||
mFloatView = new FloatPhone(b.mApplicationContext); |
||||
initTouchEvent(); |
||||
} |
||||
mFloatView.setSize(mB.mWidth, mB.mHeight); |
||||
mFloatView.setGravity(mB.gravity, mB.xOffset, mB.yOffset); |
||||
mFloatView.setView(mB.mView); |
||||
new FloatLifecycle(mB.mApplicationContext, mB.mShow, mB.mActivities, new LifecycleListener() { |
||||
@Override |
||||
public void onShow() { |
||||
show(); |
||||
} |
||||
|
||||
@Override |
||||
public void onHide() { |
||||
hide(); |
||||
} |
||||
|
||||
@Override |
||||
public void onPostHide() { |
||||
postHide(); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
@Override |
||||
public void show() { |
||||
if (once) { |
||||
mFloatView.init(); |
||||
once = false; |
||||
isShow = true; |
||||
} else { |
||||
if (isShow) return; |
||||
getView().setVisibility(View.VISIBLE); |
||||
isShow = true; |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void hide() { |
||||
if (once || !isShow) return; |
||||
getView().setVisibility(View.INVISIBLE); |
||||
isShow = false; |
||||
} |
||||
|
||||
@Override |
||||
void dismiss() { |
||||
mFloatView.dismiss(); |
||||
isShow = false; |
||||
} |
||||
|
||||
@Override |
||||
public void updateX(int x) { |
||||
checkMoveType(); |
||||
mB.xOffset = x; |
||||
mFloatView.updateX(x); |
||||
} |
||||
|
||||
@Override |
||||
public void updateY(int y) { |
||||
checkMoveType(); |
||||
mB.yOffset = y; |
||||
mFloatView.updateY(y); |
||||
} |
||||
|
||||
@Override |
||||
public void updateX(int screenType, float ratio) { |
||||
checkMoveType(); |
||||
mB.xOffset = (int) ((screenType == Screen.width ? |
||||
Util.getScreenWidth(mB.mApplicationContext) : |
||||
Util.getScreenHeight(mB.mApplicationContext)) * ratio); |
||||
mFloatView.updateX(mB.xOffset); |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void updateY(int screenType, float ratio) { |
||||
checkMoveType(); |
||||
mB.yOffset = (int) ((screenType == Screen.width ? |
||||
Util.getScreenWidth(mB.mApplicationContext) : |
||||
Util.getScreenHeight(mB.mApplicationContext)) * ratio); |
||||
mFloatView.updateY(mB.yOffset); |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public int getX() { |
||||
return mFloatView.getX(); |
||||
} |
||||
|
||||
@Override |
||||
public int getY() { |
||||
return mFloatView.getY(); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public View getView() { |
||||
return mB.mView; |
||||
} |
||||
|
||||
void postHide() { |
||||
if (once || !isShow) return; |
||||
getView().post(new Runnable() { |
||||
@Override |
||||
public void run() { |
||||
getView().setVisibility(View.INVISIBLE); |
||||
} |
||||
}); |
||||
isShow = false; |
||||
} |
||||
|
||||
private void checkMoveType() { |
||||
if (mB.mMoveType == MoveType.fixed) { |
||||
throw new IllegalArgumentException("FloatWindow of this tag is not allowed to move!"); |
||||
} |
||||
} |
||||
|
||||
private void initTouchEvent() { |
||||
switch (mB.mMoveType) { |
||||
case MoveType.free: |
||||
break; |
||||
default: |
||||
getView().setOnTouchListener(new View.OnTouchListener() { |
||||
float lastX, lastY, changeX, changeY; |
||||
int newX, newY; |
||||
|
||||
@Override |
||||
public boolean onTouch(View v, MotionEvent event) { |
||||
|
||||
switch (event.getAction()) { |
||||
case MotionEvent.ACTION_DOWN: |
||||
lastX = event.getRawX(); |
||||
lastY = event.getRawY(); |
||||
cancelAnimator(); |
||||
break; |
||||
case MotionEvent.ACTION_MOVE: |
||||
changeX = event.getRawX() - lastX; |
||||
changeY = event.getRawY() - lastY; |
||||
newX = (int) (mFloatView.getX() + changeX); |
||||
newY = (int) (mFloatView.getY() + changeY); |
||||
mFloatView.updateXY(newX, newY); |
||||
lastX = event.getRawX(); |
||||
lastY = event.getRawY(); |
||||
break; |
||||
case MotionEvent.ACTION_UP: |
||||
switch (mB.mMoveType) { |
||||
case MoveType.slide: |
||||
int startX = mFloatView.getX(); |
||||
int endX = (startX * 2 + v.getWidth() > |
||||
Util.getScreenWidth(mB.mApplicationContext)) ? |
||||
Util.getScreenWidth(mB.mApplicationContext) - v.getWidth() : 0; |
||||
mAnimator = ObjectAnimator.ofInt(startX, endX); |
||||
mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { |
||||
@Override |
||||
public void onAnimationUpdate(ValueAnimator animation) { |
||||
int x = (int) animation.getAnimatedValue(); |
||||
mFloatView.updateX(x); |
||||
} |
||||
}); |
||||
startAnimator(); |
||||
break; |
||||
case MoveType.back: |
||||
PropertyValuesHolder pvhX = PropertyValuesHolder.ofInt("x", mFloatView.getX(), mB.xOffset); |
||||
PropertyValuesHolder pvhY = PropertyValuesHolder.ofInt("y", mFloatView.getY(), mB.yOffset); |
||||
mAnimator = ObjectAnimator.ofPropertyValuesHolder(pvhX, pvhY); |
||||
mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { |
||||
@Override |
||||
public void onAnimationUpdate(ValueAnimator animation) { |
||||
int x = (int) animation.getAnimatedValue("x"); |
||||
int y = (int) animation.getAnimatedValue("y"); |
||||
mFloatView.updateXY(x, y); |
||||
} |
||||
}); |
||||
startAnimator(); |
||||
break; |
||||
} |
||||
break; |
||||
|
||||
} |
||||
return false; |
||||
} |
||||
}); |
||||
} |
||||
} |
||||
|
||||
private void startAnimator() { |
||||
if (mB.mInterpolator == null) { |
||||
if (mDecelerateInterpolator == null) { |
||||
mDecelerateInterpolator = new DecelerateInterpolator(); |
||||
} |
||||
mB.mInterpolator = mDecelerateInterpolator; |
||||
} |
||||
mAnimator.setInterpolator(mB.mInterpolator); |
||||
mAnimator.addListener(new AnimatorListenerAdapter() { |
||||
@Override |
||||
public void onAnimationEnd(Animator animation) { |
||||
mAnimator.removeAllUpdateListeners(); |
||||
mAnimator.removeAllListeners(); |
||||
mAnimator = null; |
||||
} |
||||
}); |
||||
mAnimator.setDuration(mB.mDuration).start(); |
||||
} |
||||
|
||||
private void cancelAnimator() { |
||||
if (mAnimator != null && mAnimator.isRunning()) { |
||||
mAnimator.cancel(); |
||||
} |
||||
} |
||||
|
||||
} |
@ -1,15 +0,0 @@ |
||||
package com.frank.ffmpeg.floating; |
||||
|
||||
/** |
||||
* Created by yhao on 2017/12/22. |
||||
* https://github.com/yhaolpz
|
||||
*/ |
||||
|
||||
interface LifecycleListener { |
||||
|
||||
void onShow(); |
||||
|
||||
void onHide(); |
||||
|
||||
void onPostHide(); |
||||
} |
@ -1,24 +0,0 @@ |
||||
package com.frank.ffmpeg.floating; |
||||
|
||||
import android.support.annotation.IntDef; |
||||
|
||||
import java.lang.annotation.Retention; |
||||
import java.lang.annotation.RetentionPolicy; |
||||
|
||||
/** |
||||
* Created by yhao on 2017/12/22. |
||||
* https://github.com/yhaolpz
|
||||
*/ |
||||
|
||||
public class MoveType { |
||||
static final int fixed = 0; |
||||
public static final int free = 1; |
||||
public static final int active = 2; |
||||
public static final int slide = 3; |
||||
public static final int back = 4; |
||||
|
||||
@IntDef({fixed, free, active, slide, back}) |
||||
@Retention(RetentionPolicy.SOURCE) |
||||
@interface MOVE_TYPE { |
||||
} |
||||
} |
@ -1,11 +0,0 @@ |
||||
package com.frank.ffmpeg.floating; |
||||
|
||||
/** |
||||
* Created by yhao on 2017/11/14. |
||||
* https://github.com/yhaolpz
|
||||
*/ |
||||
interface PermissionListener { |
||||
void onSuccess(); |
||||
|
||||
void onFail(); |
||||
} |
@ -1,21 +0,0 @@ |
||||
package com.frank.ffmpeg.floating; |
||||
|
||||
import android.support.annotation.IntDef; |
||||
|
||||
import java.lang.annotation.Retention; |
||||
import java.lang.annotation.RetentionPolicy; |
||||
|
||||
/** |
||||
* Created by yhao on 2017/12/23. |
||||
* https://github.com/yhaolpz
|
||||
*/ |
||||
|
||||
public class Screen { |
||||
public static final int width = 0; |
||||
public static final int height = 1; |
||||
|
||||
@IntDef({width, height}) |
||||
@Retention(RetentionPolicy.SOURCE) |
||||
@interface screenType { |
||||
} |
||||
} |
@ -1,50 +0,0 @@ |
||||
package com.frank.ffmpeg.floating; |
||||
|
||||
import android.content.Context; |
||||
import android.graphics.Point; |
||||
import android.os.Build; |
||||
import android.provider.Settings; |
||||
import android.support.annotation.RequiresApi; |
||||
import android.view.LayoutInflater; |
||||
import android.view.View; |
||||
import android.view.WindowManager; |
||||
|
||||
/** |
||||
* Created by yhao on 2017/12/22. |
||||
* https://github.com/yhaolpz
|
||||
*/ |
||||
|
||||
public class Util { |
||||
|
||||
|
||||
static View inflate(Context applicationContext, int layoutId) { |
||||
LayoutInflater inflate = (LayoutInflater) applicationContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); |
||||
return inflate.inflate(layoutId, null); |
||||
} |
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.M) |
||||
public static boolean hasPermission(Context context) { |
||||
return Settings.canDrawOverlays(context); |
||||
} |
||||
|
||||
|
||||
private static Point sPoint; |
||||
|
||||
static int getScreenWidth(Context context) { |
||||
if (sPoint == null) { |
||||
sPoint = new Point(); |
||||
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); |
||||
wm.getDefaultDisplay().getSize(sPoint); |
||||
} |
||||
return sPoint.x; |
||||
} |
||||
|
||||
static int getScreenHeight(Context context) { |
||||
if (sPoint == null) { |
||||
sPoint = new Point(); |
||||
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); |
||||
wm.getDefaultDisplay().getSize(sPoint); |
||||
} |
||||
return sPoint.y; |
||||
} |
||||
} |
Loading…
Reference in new issue