シンプルなアプリで画面上のオブジェクトを操作する方法を調査しています:
1ImageView
つのポインターで移動し、2 つ目のポインターを使用して回転できるものがあります。ビューに触れるとサイズがわずかに大きくなり、離すと元のサイズに戻ります。このアプリには 2 つの問題があります。
- 回転すると、0° と 180° をまたいで正しく動作しません。
- リリースされた後、画像がトリミングされます。
これが簡単に解決できるかどうか、またはアプローチを完全に変更する必要があるかどうかはわかりませんが、ヘルプ/ヒントは大歓迎です。
ここに私のコードがあります:
main.xml は空の RelativeLayout です。
public class MainActivity extends Activity{
ImageView image;
ViewGroup group;
int oldX, oldY;
static float x1,y1, degrees, width,height;
RelativeLayout.LayoutParams startLayoutParams;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
group = (ViewGroup)findViewById(R.id.root);
image = new ImageView(this);
image.setImageResource(R.drawable.androids);//set image(80x80px)
image.setOnTouchListener(touch);
startLayoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
startLayoutParams.leftMargin = 50;
startLayoutParams.topMargin = 50;
startLayoutParams.bottomMargin = -250;
startLayoutParams.rightMargin = -250;
image.setLayoutParams(startLayoutParams);
group.addView(image);
}//end onCreate
public OnTouchListener touch = new OnTouchListener() {
RelativeLayout.LayoutParams downParams, upParams, moveParams;
@Override
public boolean onTouch(View view, MotionEvent event) {
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
((ImageView)view).setImageResource(R.drawable.android);//set slightly larger image(100x100px)
downParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
downParams.leftMargin = downParams.leftMargin-10;//adjust margin to compensate for larger image
downParams.topMargin = downParams.topMargin-10;
downParams.bottomMargin = -250;
downParams.rightMargin = -250;
view.setLayoutParams(downParams);
oldX = X - downParams.leftMargin;//get starting position
oldY = Y - downParams.topMargin;
break;
case MotionEvent.ACTION_UP:
((ImageView)view).setImageResource(R.drawable.androids);//Reset smaller image
upParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
upParams.leftMargin += 10;//re-adjust margin
upParams.topMargin += 10;
upParams.bottomMargin = -250;
upParams.rightMargin = -250;
view.setLayoutParams(upParams);
break;
case MotionEvent.ACTION_POINTER_2_DOWN:
x1=event.getX(1);// get starting coordinates for calculating degrees to rotate
y1=event.getY(1);
break;
case MotionEvent.ACTION_MOVE:
int pointer = event.getPointerId(0);
int pointerCount = event.getPointerCount();
moveParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
moveParams.leftMargin = X - oldX;//get new position
moveParams.topMargin = Y - oldY;
moveParams.rightMargin = -250;
moveParams.bottomMargin = -250;
if (pointerCount == 1) {//move image
view.setLayoutParams(moveParams);
}else if(pointerCount == 2){//move and rotate image
for(int i = 0 ; i<pointerCount;i++){
if(event.getPointerId(i)==pointer){
view.setLayoutParams(moveParams);//move
}//end if
}//end for
degrees = getDegrees(event);
width = ((ImageView)view).getDrawable().getBounds().width();
height = ((ImageView)view).getDrawable().getBounds().height();
Matrix matrix=new Matrix();
((ImageView)view).setScaleType(ScaleType.MATRIX); //required
matrix.postRotate(degrees, width/2, height/2);//rotate
((ImageView)view).setImageMatrix(matrix);
}//end if-else if
break;
}//end switch-case
group.invalidate();
return true;
}//end onTouch
};//end OnTouchListener touch
public static float getDegrees(MotionEvent event){
float x0,y0, x2,y2, A,B,C, angle,cosa;
x0 = event.getX(0);
y0 = event.getY(0);
x2 = event.getX(1);
y2 = event.getY(1);
A = FloatMath.sqrt(sq(x0-x1) + sq(y0-y1));
B = FloatMath.sqrt(sq(x0-x2) + sq(y0-y2));
C = FloatMath.sqrt(sq(x2-x1) + sq(y2-y1));
cosa = (sq(A)+sq(B)-sq(C))/(2*A*B);
angle = (float) Math.toDegrees(Math.acos(cosa));
return (x0<=x2) ? angle : opposite(angle);
}//end getDegrees
private static float sq(float input){
return (float) Math.pow(input, 2);
}//end square
private static float opposite(float value){
return value-(2*value);
}//end opposite
}//end MainActivity
この件に関して多くの質問があることを認識しており、何十もの質問を読んでいくつか試してみましたが、問題が解決しないか、他の問題が発生したため、この質問を投稿することにしました。
getDegrees() に関する情報:
画像を投稿できないので確認してください: http://i50.tinypic.com/vsjl28.jpg
- p0 =(x0,y0) =最初のポインタの現在位置
- p1 =(x1,y1) = 2 番目のポインターが最初に置かれる場所
- p2 =(x2,y2) = 2 番目のポインターの現在の位置
getDegrees() は、2 番目のポインターが最初のポインターの右側にある場合は角度 cを返し、左側にある場合は c の負の値を返します。