Android實(shí)現(xiàn)view拖動(dòng)到任意位置
本文實(shí)現(xiàn):將圖片任意拖動(dòng),如果拖動(dòng)到正確位置則成功,若抬起手時(shí)時(shí)錯(cuò)誤位置則自動(dòng)回到原位。
定義
private ImageView img;
private ImageView imageView;
//容器的寬高,需要在屏幕繪制好之后才能獲取
private int containerWidth;
private int containerHeight;
private float lastX, lastY;
//獲取需要拖動(dòng)到的正確位置
private int[] imgPosition = new int[2];
private int height;
private int width;
在屏幕繪制好之后獲取寬高和位置
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
// 這里來獲取容器的寬和高
if (hasFocus) {
containerHeight = sunPage.getHeight();
containerWidth = sunPage.getWidth();
}
//獲取需要拖動(dòng)到的正確位置,img處
img.getLocationInWindow(imgPosition);
height = img.getMeasuredHeight();
width = img.getMeasuredWidth();
}
手勢事件
imageView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
//手指在屏幕位置getRawX() getRawY()
lastX = event.getRawX();
lastY = event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
// 不要直接用getX和getY,這兩個(gè)獲取的數(shù)據(jù)已經(jīng)是經(jīng)過處理的,容易出現(xiàn)圖片抖動(dòng)的情況
float distanceX = xx - event.getRawX();
float distanceY = yy - event.getRawY();
float nextY = imageView.getY() - distanceY;
float nextX = imageView.getX() - distanceX;
// 不能移出屏幕
if (nextY < 0) {
nextY = 0;
} else if (nextY > containerHeight - imageView.getHeight()) {
nextY = containerHeight - imageView.getHeight();
}
if (nextX < 0)
nextX = 0;
else if (nextX > containerWidth - imageView.getWidth())
nextX = containerWidth - imageView.getWidth();
// 屬性動(dòng)畫移動(dòng)
ObjectAnimator y = ObjectAnimator.ofFloat(imageView, "y", imageView.getY(), nextY);
ObjectAnimator x = ObjectAnimator.ofFloat(imageView, "x", imageView.getX(), nextX);
animatorSet.playTogether(x, y);
animatorSet.setDuration(0);
animatorSet.start();
lastX = event.getRawX();
lastY = event.getRawY();
if (correct(lastX, lastY, imgPosition, m)) {
//正確后的事情
}
break;
case MotionEvent.ACTION_UP:
//抬起手后自動(dòng)彈回原處,監(jiān)聽animatorSet
animatorSet.cancel();
break;
}
return true;
}
});
判斷拖動(dòng)是否正確,m是img的半徑,拖動(dòng)結(jié)合的難易可以自己調(diào)劑算法
//判斷拖動(dòng)是否正確,m是img的半徑,拖動(dòng)結(jié)合的難易可以自己調(diào)劑算法
private boolean correct(float x, float y, int[] a, int m) {
float s = (float) Math.sqrt((x - a[0]) * (x - a[0]) + (y - a[1]) * (y - a[1]) - (x - a[0]) * (y - a[1]));
if (s <= ActivityUtils.dip2px(HomeGameActivity.this, m)) {
return true;
}
return false;
}
監(jiān)聽animatorSet,cancle時(shí)imageview返回原處
animatorSet.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
imageView.setTranslationY(0);
imageView.setTranslationX(0);
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android自定義View實(shí)現(xiàn)隨機(jī)驗(yàn)證碼
這篇文章主要介紹了Android自定義View實(shí)現(xiàn)隨機(jī)驗(yàn)證碼的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-07-07
詳解Android Service 使用時(shí)的注意事項(xiàng)
這篇文章主要介紹了詳解Android Service 使用時(shí)的注意事項(xiàng),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10
flutter Toast實(shí)現(xiàn)消息提示框
這篇文章主要為大家詳細(xì)介紹了flutter Toast實(shí)現(xiàn)消息提示框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07
2013年 移動(dòng)App設(shè)計(jì)13項(xiàng)注意細(xì)節(jié)總結(jié)
在過去的一年里,移動(dòng)成主流也讓眾多的移動(dòng)應(yīng)用如雨后春筍般層出不窮,在眾多開發(fā)者從中獲利的同時(shí)競爭也愈演愈烈,如何才能保證自己立于不敗之地接下來介紹移動(dòng)App設(shè)計(jì)的13大精髓感興趣的朋友可以了解下啊2013-01-01
Android開發(fā)框架MVC-MVP-MVVM-MVI的演變Demo
這篇文章主要為大家介紹了Android開發(fā)框架MVC-MVP-MVVM-MVI的演變Demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
android RecycleView實(shí)現(xiàn)下拉刷新和上拉加載
這篇文章主要為大家詳細(xì)介紹了android RecycleView實(shí)現(xiàn)下拉刷新和上拉加載,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06
Android使用Handler實(shí)現(xiàn)View彈性滑動(dòng)
這篇文章主要介紹了Android使用Handler實(shí)現(xiàn)View彈性滑動(dòng),介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-08-08

