0

我正在研究如何使用一个简单的应用程序与屏幕上的对象进行交互:

我有一个ImageView可以用一个指针移动并使用第二个指针旋转。当视图被触摸时,它的大小会略微增加,并在释放时恢复到原始大小。我对这个应用程序有 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) =第二个指针首先被放下的地方
  • p2 =(x2,y2) =第二个指针的当前位置

如果第二个指针位于第一个指针的右侧,getDegrees() 返回角度 c ,当位于其左侧时c 的负值。

4

1 回答 1

0

您正在寻找 CA 和 CB 之间的角度。当角度经过 180 度时,三角形 ABC 将位于线 CA 的另一侧。因此,角度将再次开始减小,直到您回到角度再次为零的 CA=CB。

恐怕我不能真正建议另一种方法,因为我不完全了解您希望三角形如何相对于触摸输入旋转。

于 2012-10-04T12:28:21.520 回答