Android 제스처 슬라이딩 멀 티 터치 크기 조정 그림 효과 구현(2)
13807 단어 Android손짓 으로 미끄러지다.멀 티 터치확대/축소
우선 확대 후의 이동 을 넣는다.
1.자 유 롭 게 이동
저 희 는 onTouchEvent 에 이동 코드 를 추가 합 니 다.물론 화면 보다 길 거나 넓 어야 이동 할 수 있 습 니 다~~
@Override
public boolean onTouch(View v, MotionEvent event)
{
mScaleGestureDetector.onTouchEvent(event);
float x = 0, y = 0;
//
final int pointerCount = event.getPointerCount();
// x y
for (int i = 0; i < pointerCount; i++)
{
x += event.getX(i);
y += event.getY(i);
}
x = x / pointerCount;
y = y / pointerCount;
/**
* , mLasX , mLastY
*/
if (pointerCount != lastPointerCount)
{
isCanDrag = false;
mLastX = x;
mLastY = y;
}
lastPointerCount = pointerCount;
switch (event.getAction())
{
case MotionEvent.ACTION_MOVE:
Log.e(TAG, "ACTION_MOVE");
float dx = x - mLastX;
float dy = y - mLastY;
if (!isCanDrag)
{
isCanDrag = isCanDrag(dx, dy);
}
if (isCanDrag)
{
RectF rectF = getMatrixRectF();
if (getDrawable() != null)
{
isCheckLeftAndRight = isCheckTopAndBottom = true;
// ,
if (rectF.width() < getWidth())
{
dx = 0;
isCheckLeftAndRight = false;
}
// ,
if (rectF.height() < getHeight())
{
dy = 0;
isCheckTopAndBottom = false;
}
mScaleMatrix.postTranslate(dx, dy);
checkMatrixBounds();
setImageMatrix(mScaleMatrix);
}
}
mLastX = x;
mLastY = y;
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
Log.e(TAG, "ACTION_UP");
lastPointerCount = 0;
break;
}
return true;
}
먼저 우 리 는 터치 점 의 수량 을 얻 은 다음 에 여러 개의 터치 점 의 평균 값 을 구하 고 우리 에 게 mLastX,mLastY 를 설정 한 다음 에 이동 할 때 dx,dy 를 받 아 범위 검 사 를 한 후에 mScale Matrix.post Translate 를 호출 하여 오프셋 을 설정 해 야 합 니 다.물론 설정 이 완 료 된 후에 다시 한 번 확인 해 야 합 니 다.그림 을 화면 경계 와 흰색 으로 이동 할 수 없습니다.검사 가 완료 되면 setImageMatrix 를 호출 합 니 다.여기:주의해 야 합 니 다.저 희 는 ACTION 을 복사 하지 않 았 습 니 다.DOWM,왜냐하면,ACTIONDOWN 은 다 중 터치 가 있 는 상태 에서 한 손가락 만 누 른 상태 라면 다른 손가락 을 누 르 면 다시 ACTION 을 터치 하지 않 습 니 다.DOWN,하지만 여러 손가락 이후 터치 포인트 의 평균 값 이 크게 달라 질 수 있 기 때문에 우 리 는 ACTION 을 사용 하지 않 았 습 니 다.DOWN。터치 포인트 의 수량 이 변 할 때마다 우 리 는 새로운 현재 mLastX,mLasty 와 함께 합 니 다.
다음은 위 에서 사용 하 는 두 가지 개인 적 인 방법 입 니 다.하 나 는 경 계 를 검사 하 는 데 사용 되 고 하 나 는 드래그 여 부 를 판단 하 는 데 사 용 됩 니 다.
/**
* , ,
*/
private void checkMatrixBounds()
{
RectF rect = getMatrixRectF();
float deltaX = 0, deltaY = 0;
final float viewWidth = getWidth();
final float viewHeight = getHeight();
// ,
if (rect.top > 0 && isCheckTopAndBottom)
{
deltaY = -rect.top;
}
if (rect.bottom < viewHeight && isCheckTopAndBottom)
{
deltaY = viewHeight - rect.bottom;
}
if (rect.left > 0 && isCheckLeftAndRight)
{
deltaX = -rect.left;
}
if (rect.right < viewWidth && isCheckLeftAndRight)
{
deltaX = viewWidth - rect.right;
}
mScaleMatrix.postTranslate(deltaX, deltaY);
}
/**
*
*
* @param dx
* @param dy
* @return
*/
private boolean isCanDrag(float dx, float dy)
{
return Math.sqrt((dx * dx) + (dy * dy)) >= mTouchSlop;
}
이렇게 하면 우 리 는 즐겁게 확대 하고 축소 하 며 이동 할 수 있다.효과 도:이번에 남자 로 바 뀐 사진,우리 탈옥 의 주인공 중 한 명,TBug~
우리 의 크기 조정+이동 이 완료 되 었 습 니 다.
2.더 블 클릭 확대 와 축소
더 블 클릭 사건 에 대해 서 는 저희 Gesture Detector 가 드디어 등장 합 니 다.이 친구 가 더 블 클릭 사건 을 잡 을 수 있 습 니 다~~
1)、Gesture Detector 의 사용
Gesture Detector 가 감청 기 를 설정 하면 방법 이 한 줄 씩 있 습 니 다.우 리 는 onDoubleTap 이라는 리 셋 만 필요 하기 때문에 내부 클래스 인 Simple OnGesture Listener 를 사용 하여 인터페이스의 다른 방법 을 실현 하려 고 합 니 다.
그러나 몇 가지 문 제 를 토론 해 야 우리 의 코드 를 시작 할 수 있 습 니 다.
우리 더 블 클릭 사 이 즈 는 어떻게 변화 합 니까?
저 는 이 렇 습 니 다.현재 크기 에 따라 2 보다 작 으 면 원 그림 의 2 배 까지 두 번 누 르 십시오.만약 2,4 사이 의 것 이 라면,우 리 는 두 번 눌 러 서 바로 원 그림 의 4 배 이다.다른 상 태 는 4 배,더 블 클릭 후 최초 사이즈 로 복원 한다.
만약 네가 이렇게 하 는 것 이 적합 하지 않다 고 생각한다 면,자신의 취미 에 따라 조정 할 수 있다.
우 리 는 두 번 눌 러 서 변 화 를 하려 면 애니메이션 이 필요 합 니 다.예 를 들 어 우리 가 예 를 들 어 프 리 젠 테 이 션 그림 이 매우 크 고 전체 화면 이 표 시 될 때 initScale=0.5 왼쪽 이후 에 두 번 눌 러 서 2,즉 순간 이 네 배 커 졌 습 니 다.과도 효과 가 없 으 면 사용자 에 게 매우 나 쁜 느낌 을 줄 수 있 습 니 다.그래서 저 희 는 potDelay 를 사용 하여 Runnable 을 실행 하려 고 합 니 다.Runnable 에서 다시 당연한 크기 조정 값 에 따라 계속 실행 하려 고 합 니 다.
우선,저 희 는 구조 방법 에서 Gesture Detector 에 대한 초기 화 와 onDoubleTap 감청 설정 을 완 료 했 습 니 다.
public ZoomImageView(Context context, AttributeSet attrs)
{
super(context, attrs);
mScaleGestureDetector = new ScaleGestureDetector(context, this);
mGestureDetector = new GestureDetector(context,
new SimpleOnGestureListener()
{
@Override
public boolean onDoubleTap(MotionEvent e)
{
if (isAutoScale == true)
return true;
float x = e.getX();
float y = e.getY();
Log.e("DoubleTap", getScale() + " , " + initScale);
if (getScale() < SCALE_MID)
{
ZoomImageView.this.postDelayed(
new AutoScaleRunnable(SCALE_MID, x, y), 16);
isAutoScale = true;
} else if (getScale() >= SCALE_MID
&& getScale() < SCALE_MAX)
{
ZoomImageView.this.postDelayed(
new AutoScaleRunnable(SCALE_MAX, x, y), 16);
isAutoScale = true;
} else
{
ZoomImageView.this.postDelayed(
new AutoScaleRunnable(initScale, x, y), 16);
isAutoScale = true;
}
return true;
}
});
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
super.setScaleType(ScaleType.MATRIX);
this.setOnTouchListener(this);
}
/**
*
*
* @author zhy
*
*/
private class AutoScaleRunnable implements Runnable
{
static final float BIGGER = 1.07f;
static final float SMALLER = 0.93f;
private float mTargetScale;
private float tmpScale;
/**
*
*/
private float x;
private float y;
/**
* , ,
*
* @param targetScale
*/
public AutoScaleRunnable(float targetScale, float x, float y)
{
this.mTargetScale = targetScale;
this.x = x;
this.y = y;
if (getScale() < mTargetScale)
{
tmpScale = BIGGER;
} else
{
tmpScale = SMALLER;
}
}
@Override
public void run()
{
//
mScaleMatrix.postScale(tmpScale, tmpScale, x, y);
checkBorderAndCenterWhenScale();
setImageMatrix(mScaleMatrix);
final float currentScale = getScale();
// ,
if (((tmpScale > 1f) && (currentScale < mTargetScale))
|| ((tmpScale < 1f) && (mTargetScale < currentScale)))
{
ZoomImageView.this.postDelayed(this, 16);
} else//
{
final float deltaScale = mTargetScale / currentScale;
mScaleMatrix.postScale(deltaScale, deltaScale, x, y);
checkBorderAndCenterWhenScale();
setImageMatrix(mScaleMatrix);
isAutoScale = false;
}
}
}
코드 를 다 썼 습 니 다.우 리 는 여전히 우리 의 이 벤트 를 그것 에 게 전달 해 야 합 니 다.여전히 onTouch 방법 입 니 다.
@Override
public boolean onTouch(View v, MotionEvent event)
{
if (mGestureDetector.onTouchEvent(event))
return true;
자,확대 와 축소 기능 을 더 블 클릭 하면 됩 니 다.3.ViewPager 와 의 충돌 처리
우리 의 그림 을 ViewPager 의 Item 으로 직접 사용 하 는 것 은 분명 충돌 이 있 을 것 입 니 다~~
1)레이아웃 파일
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent">
</android.support.v4.view.viewpager>
</relativelayout>
2),Activity 코드
package com.zhy.zhy_scalegesturedetector02;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.zhy.view.ZoomImageView;
public class MainActivity extends Activity
{
private ViewPager mViewPager;
private int[] mImgs = new int[] { R.drawable.tbug, R.drawable.a,
R.drawable.xx };
private ImageView[] mImageViews = new ImageView[mImgs.length];
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.vp);
mViewPager = (ViewPager) findViewById(R.id.id_viewpager);
mViewPager.setAdapter(new PagerAdapter()
{
@Override
public Object instantiateItem(ViewGroup container, int position)
{
ZoomImageView imageView = new ZoomImageView(
getApplicationContext());
imageView.setImageResource(mImgs[position]);
container.addView(imageView);
mImageViews[position] = imageView;
return imageView;
}
@Override
public void destroyItem(ViewGroup container, int position,
Object object)
{
container.removeView(mImageViews[position]);
}
@Override
public boolean isViewFromObject(View arg0, Object arg1)
{
return arg0 == arg1;
}
@Override
public int getCount()
{
return mImgs.length;
}
});
}
}
지금 바로 실행 중 입 니 다.ViewPager 가 괜 찮 은 것 을 발 견 했 습 니 다.하지만 우리 의 그림 이 확대 되면 서 이동 과 ViewPager 가 충돌 하여 이동 할 수 없습니다~.닦 아,닦 아.3)、충돌 처리
지금 우 리 는 신속하게 생각해 보 겠 습 니 다.이전에 사건 배포 체 제 를 배 웠 던 것 을 기억 합 니 다.우리 의 ZoomImageView 는 ViewPager 에서 우리 가 차단 되 고 싶 지 않다 면 어떻게 합 니까?
우선 차단 되 고 싶 지 않 은 조건 은 우리 의 너비 나 높이 가 화면 너비 나 높이 보다 클 때 이동 할 수 있 기 때문에 차단 되 고 싶 지 않다 는 것 이다.다음은 차단 되 고 싶 지 않 습 니 다.
getParent().requestDisallowInterceptTouchEvent(true);
한 줄 의 코드 가 충분 합 니 다.만약 에 사건 배포 에서 차단 되 지 않 고 명확 하지 않 으 면 참고 할 수 있 습 니 다.어떻게 차단 되 지 않 습 니까?
함께 놓 으 면 우리 의 코드 는:
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
if (rectF.width() > getWidth() || rectF.height() > getHeight())
{
getParent().requestDisallowInterceptTouchEvent(true);
}
break;
case MotionEvent.ACTION_MOVE:
if (rectF.width() > getWidth() || rectF.height() > getHeight())
{
getParent().requestDisallowInterceptTouchEvent(true);
}
화면 너비 나 높이 보다 크 거나 넓 을 때 드래그 효 과 는 그림 을 이동 하 는 것 으로 간주 하고,반대로 ViewPager 에 게 처리 하도록 합 니 다.현재 효과:
ok,이제 ViewPager 와 의 충돌 이 해결 되 었 습 니 다.
4、경계 에 도달 한 사건 은 ViewPager 에 게 처리
일부 사용자 들 은 그림 이 경계 에 도 착 했 을 때 더 이상 끌 수 없 을 때 ViewPager 에 이 벤트 를 줄 수 있 기 를 바 랄 수도 있 습 니 다.
그럼 ACTION 에서MOVE 에서 현재 경계 에 도 달 했 고 끌 고 있 을 때 이 벤트 를 ViewPager 에 게 전달 합 니 다.
if (isCanDrag)
{
if (getDrawable() != null)
{
if (getMatrixRectF().left == 0 && dx > 0)
{
getParent().requestDisallowInterceptTouchEvent(false);
}
if (getMatrixRectF().right == getWidth() && dx < 0)
{
getParent().requestDisallowInterceptTouchEvent(false);
}
현재 효과:이 쯤 에서,우리 안 드 로 이 드 제스처 검 측 실전 만 들 기 크기 조정 을 지원 하 는 그림 미리보기 효과 가 끝 났 습 니 다~~!
더 블 클릭 을 4 배로 확대 하고 If 를 주석 하 는 것 을 권장 합 니 다.
// else if (getScale() >= SCALE_MID
// && getScale() < SCALE_MAX)
// {
// ZoomImageView.this.postDelayed(
// new AutoScaleRunnable(SCALE_MAX, x, y), 16);
// isAutoScale = true;
// }
이상 은 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 기 를 바 랍 니 다.여러분 도 안 드 로 이 드 를 실천 하여 제스처 슬라이딩 다 중 터치 확대 와 그림 이동 효 과 를 실현 할 수 있 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.