由于在網(wǎng)上找到的教程中雙指旋轉(zhuǎn)需要通過獲取手指落點相對于父控件的坐標(biāo)點來計算,所以采用重寫RelativeLayout的方法,如果有其他的方法不需要重寫RelativeLayout,希望可以和我聯(lián)系
MyRelativeLayout.java
/**
* Created by nan on 2017/5/27.
*/
public class MyRelativeLayout extends RelativeLayout {
private TextView mytextview;
private static LinearLayout textCustomLayout;
private float startx;// down事件發(fā)生時,手指相對于view左上角x軸的距離
private float starty;// down事件發(fā)生時,手指相對于view左上角y軸的距離
private float endx; // move事件發(fā)生時,手指相對于view左上角x軸的距離
private float endy; // move事件發(fā)生時,手指相對于view左上角y軸的距離
private float left; // DragTV左邊緣相對于父控件的距離
private float top; // DragTV上邊緣相對于父控件的距離
private int right; // DragTV右邊緣相對于父控件的距離
private int bottom; // DragTV底邊緣相對于父控件的距離
private float hor; // 觸摸情況下,手指在x軸方向移動的距離
private float ver; // 觸摸情況下,手指在y軸方向移動的距離
private float mfX, mfY, msX, msY;
private boolean isMove = true;
private float mAngle;
private int ptrID1 = INVALID_POINTER_ID, ptrID2 = INVALID_POINTER_ID;
private float oldDist = 0;
private float textSize = 0;
private float scale;
private static final int INVALID_POINTER_ID = -1;
private MotionEvent mEvent;
private boolean onefingure;
public MyRelativeLayout(Context context) {
super(context);
}
public MyRelativeLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public MyRelativeLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public textClick getTextClick() {
return mytextClick;
}
public void setTextClick(textClick mytextClick) {
this.mytextClick = mytextClick;
}
private textClick mytextClick;
@Override
public boolean onTouchEvent(MotionEvent event) {
mEvent = event;
mytextview = (TextView) findViewById(R.id.poemtext);
mytextview.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
mytextview = (TextView) v;
if (textSize == 0) {
textSize = mytextview.getTextSize();
}
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
onefingure = true;
//手指落點相對于TextView的坐標(biāo)
startx = event.getX();
starty = event.getY();
Log.d("HHHH", "onTouch: ACTION_DOWM " + startx);
ptrID1 = event.getPointerId(event.getActionIndex());
break;
case MotionEvent.ACTION_POINTER_DOWN:
isMove = false;
onefingure = false;
ptrID2 = event.getPointerId(event.getActionIndex());
//手指落點相對于RelativeLayout的坐標(biāo)
msX = mEvent.getX(event.findPointerIndex(ptrID2));
msY = mEvent.getY(event.findPointerIndex(ptrID2));
mfX = mEvent.getX(event.findPointerIndex(ptrID1));
mfY = mEvent.getY(event.findPointerIndex(ptrID1));
oldDist = spacing(event);
break;
case MotionEvent.ACTION_MOVE:
Log.d("HHHH", "onTouch: ACTION_MOVE ");
left = mytextview.getX();
top = mytextview.getY();
if (isMove) {
endx = event.getX();
endy = event.getY();
hor = (endx - startx);
ver = (endy - starty);
mytextview.setX(left + hor);
mytextview.setY(top + ver);
}
else {
//處理旋轉(zhuǎn)模塊
float nfX, nfY, nsX, nsY, test;
test = event.getX(event.findPointerIndex(ptrID1));
nsX = mEvent.getX(event.findPointerIndex(ptrID2));
nsY = mEvent.getY(event.findPointerIndex(ptrID2));
nfX = mEvent.getX(event.findPointerIndex(ptrID1));
nfY = mEvent.getY(event.findPointerIndex(ptrID1));
mAngle = angleBetweenLines(mfX, mfY, msX, msY, nfX, nfY, nsX, nsY);
mytextview.setRotation(mAngle);
//縮放
float newDist = spacing(event);
if (newDist > oldDist + 1) {
zoom(newDist / oldDist);
oldDist = newDist;
}
if (newDist < oldDist - 1) {
zoom(newDist / oldDist);
oldDist = newDist;
}
}
break;
case MotionEvent.ACTION_UP:
Log.d("HHHH", "onTouch: ACTION_UP");
if (onefingure) {
//監(jiān)聽事件,在MainActivity中實現(xiàn),否則不能調(diào)用MainActivity中的對象
mytextClick.onTextClick();
}
break;
case MotionEvent.ACTION_POINTER_UP:
Log.d("HHHH", "onTouch: ACTION_POINTER_UP");
isMove = true;
break;
}
return true;
}
});
return true;
}
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float) Math.sqrt(x * x + y * y);
}
private void zoom(float f) {
mytextview.setTextSize(textSize *= f);
}
/**
* 計算剛開始觸摸的兩個點構(gòu)成的直線和滑動過程中兩個點構(gòu)成直線的角度
*
* @param fX 初始點一號x坐標(biāo)
* @param fY 初始點一號y坐標(biāo)
* @param sX 初始點二號x坐標(biāo)
* @param sY 初始點二號y坐標(biāo)
* @param nfX 終點一號x坐標(biāo)
* @param nfY 終點一號y坐標(biāo)
* @param nsX 終點二號x坐標(biāo)
* @param nsY 終點二號y坐標(biāo)
* @return 構(gòu)成的角度值
*/
private float angleBetweenLines(float fX, float fY, float sX, float sY, float nfX, float nfY, float nsX, float nsY) {
float angle1 = (float) Math.atan2((fY - sY), (fX - sX));
float angle2 = (float) Math.atan2((nfY - nsY), (nfX - nsX));
float angle = ((float) Math.toDegrees(angle1 - angle2)) % 360;
if (angle < -180.f) angle += 360.0f;
if (angle > 180.f) angle -= 360.0f;
return -angle;
}
public interface textClick {
void onTextClick();
}
}
如果想要監(jiān)聽其中TextView的點擊事件,可以設(shè)置接口
public textClick getTextClick() {
return mytextClick;
}
public void setTextClick(textClick mytextClick) {
this.mytextClick = mytextClick;
}
private textClick mytextClick;
public interface textClick {
void onTextClick();
}
在MainActivity.java中實現(xiàn)如下
@Override
public void onTextClick() {
mPoemLayout.setVisibility(View.INVISIBLE);
textCustom();
textCustomLayout.setVisibility(View.VISIBLE);
Toast.makeText(this, "hahaha", Toast.LENGTH_LONG).show();
}