android - 移动和旋转ImageView的问题

时间:2012-10-04 11:13:08

标签: java android android-imageview

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

我有一个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 位于其左侧。< / p>

1 个答案:

答案 0 :(得分:0)

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

我担心我无法提出另一种方法,因为我不确切地知道你想要如何根据触摸输入旋转三角形。