0

シンプルなアプリで画面上のオブジェクトを操作する方法を調査しています:

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 の負の値を返します。

4

1 に答える 1

0

CA と CB の間の角度を見つけています。角度が 180 度を通過すると、三角形 ABC は直線 CA の反対側になります。したがって、角度が再びゼロになる CA=CB に戻るまで、角度は再び減少し始めます。

タッチ入力に対して三角形をどのように回転させたいのか正確に理解できないため、別の方法を実際に提案することはできません。

于 2012-10-04T12:28:21.520 に答える