Android實(shí)現(xiàn)懸浮圖片
更新時間:2020年09月17日 14:36:24 作者:Lingtao_dong
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)懸浮圖片,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文實(shí)例為大家分享了Android實(shí)現(xiàn)懸浮圖片的具體代碼,供大家參考,具體內(nèi)容如下
@SuppressLint("AppCompatCustomView")
public class MoveImageView extends ImageView {
//按下那一刻的坐標(biāo)和 控件上下左右距離
private float lastX;
private float lastY;
private int left;
private int top;
private int right;
private int bottom;
//如果是拖動事件就不用響應(yīng)點(diǎn)擊事件
boolean isMove = false;
boolean isAnimatoring = false;
//屏幕寬高
private int screenWidthPx;
private int screenHeightPx;
public MoveImageView(Context context) {
this(context, null);
}
public MoveImageView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public MoveImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
screenWidthPx = getScreenWidthPx(getContext());
screenHeightPx = getScreenHeightPx(getContext());
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//動畫執(zhí)行過程中,不響應(yīng)一切操作,
// 這里相當(dāng)于不讓其走后面的MotionEvent.ACTION_MOVE:與MotionEvent.ACTION_UP:
if (isAnimatoring) {
return false;
}
lastX = event.getRawX();
lastY = event.getRawY();
left = getLeft();
top = getTop();
right = getRight();
bottom = getBottom();
break;
case MotionEvent.ACTION_MOVE:
isMove = true;
float x = event.getRawX();
float y = event.getRawY();
int l = (int) (left + (x - lastX));
int t = (int) (top + (y - lastY));
int r = (int) (right + (x - lastX));
int b = (int) (bottom + (y - lastY));
layout(l, t, r, b);
break;
case MotionEvent.ACTION_UP:
if (isMove) {
//如果頂部拖出屏幕外面,回正
if (getTop() < 0) {
layout(getLeft(), 0, getRight(), getHeight());
}
//getBottom() 獲取到的是 控件底部到父容器頂部的距離,所以需要減去狀態(tài)欄的高度
int bottomHeight = screenHeightPx - getStatusBarHeight(getContext());
//如果底部拖出屏幕外面,回正
if (getBottom() > bottomHeight) {
layout(getLeft(), bottomHeight-getHeight(), getRight(), bottomHeight);
}
isMove = false;
startAnimation();
return true;
}
return super.onTouchEvent(event);
}
return super.onTouchEvent(event);
}
private void startAnimation() {
isAnimatoring = true;
//右邊距
int marinRight = DisplayUtils.dpToPx(20);
int endValue = screenWidthPx - marinRight;
ValueAnimator animator = ValueAnimator.ofInt(getRight(), endValue);
animator.setDuration(Math.abs(endValue - getRight()) > 1000 ? 1000 : Math.abs(endValue - getRight()));
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int curValue = (int) animation.getAnimatedValue();
layout(curValue - getWidth(), getTop(), curValue, getHeight() + getTop());
}
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
isAnimatoring = false;
animator.removeAllUpdateListeners();
animator.removeAllListeners();
}
});
animator.start();
}
/**
* 獲取狀態(tài)欄高度
*/
public static int getStatusBarHeight(Context context) {
int result = 24;
int resId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resId > 0) {
result = context.getResources().getDimensionPixelSize(resId);
} else {
result = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
result, Resources.getSystem().getDisplayMetrics());
}
return result;
}
public static int getScreenWidthPx(Context context) {
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dm = new DisplayMetrics();
if (windowManager != null) {
// windowManager.getDefaultDisplay().getMetrics(dm);
windowManager.getDefaultDisplay().getRealMetrics(dm);
return dm.widthPixels;
}
return 0;
}
public static int getScreenHeightPx(Context context) {
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dm = new DisplayMetrics();
if (windowManager != null) {
// windowManager.getDefaultDisplay().getMetrics(dm);
windowManager.getDefaultDisplay().getRealMetrics(dm);
return dm.heightPixels;
}
return 0;
}
}
應(yīng)用:
布局文件:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".TestActivity"> <com.lingtao.ltvideo.widgets.MoveImageView android:layout_width="50dp" android:id="@+id/MoveImageView" android:layout_height="50dp" android:layout_alignParentRight="true" android:layout_alignParentBottom="true" android:layout_marginBottom="100dp" android:layout_marginRight="20dp" android:src="#ff0000" /> </RelativeLayout>
Activity:
public class TestActivity extends AppCompatActivity {
private MoveImageView moveImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test2);
moveImageView = ((MoveImageView) findViewById(R.id.MoveImageView));
moveImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(TestActivity.this, "點(diǎn)擊事件", Toast.LENGTH_SHORT).show();
}
});
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android8.0適配前臺定位服務(wù)service的示例代碼
這篇文章主要介紹了Android8.0適配前臺定位服務(wù)service的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07
Android學(xué)習(xí)教程之圓形Menu菜單制作方法(1)
這篇文章主要為大家詳細(xì)介紹了Android學(xué)習(xí)教程之圓形Menu菜單操作代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-11-11
淺談Android app開發(fā)中Fragment的Transaction操作
這篇文章主要介紹了Android app開發(fā)中Fragment的Transaction操作,包括Transaction和Fragment的生命周期的聯(lián)系等內(nèi)容,需要的朋友可以參考下2016-02-02

