如何扩大在Android中使用手柄的看法? [英] How to scale a view in android using a handle?

查看:168
本文介绍了如何扩大在Android中使用手柄的看法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现一个手柄规模在android系统视图。而不是使用像多点触控的我希望能够只用一个手指来调整图像。

I'm trying to implement a handle to scale a view in android. Instead of using something like multitouch I want to be able to resize an image with just one finger.

下面是我的活动code。我感觉好像我很接近有五件事情不正常工作。

Here is my activity code. I feel as though I am very close there are a five things that don't work properly.


  1. 的比例是关闭的。它生长在一个更快的速度比它应该。 解决感谢@Salauyou

  2. 的观点只会增加,而不是缩小。 解决感谢@Salauyou

  3. 手柄视图不与图像移动。 解决感谢@Salauyou

  4. 缩放开始极小的解决感谢@Salauyou

  5. 手柄不跟随你的手指正好。

  1. The scaling is off. It grows at a much faster rate than it should. Solved Thanks @Salauyou
  2. The view will only grow, and not shrink. Solved Thanks @Salauyou
  3. The handle view doesn't move with the image. Solved Thanks @Salauyou
  4. The scaling starts extremely small Solved Thanks @Salauyou
  5. The handle doesn't follow your finger exactly.

我在寻找能实现这样的功能,任何帮助。无论是图书馆还是有人可以用我的code,我已经有了帮助。我发现一个库,与图像的多点触摸缩放帮助( https://github.com/brk3 / Android的多点触控控制器),但唯一的指向我可以拿起就是如何去实现规模的增加。这必须通过使用两个点,并发现它们之间的距离来进行。

I am looking for any help that could implement such a feature. Whether it's a library or someone can help with my code that I already have. I have found a library that helps with multi touch scaling of images (https://github.com/brk3/android-multitouch-controller) but the only pointer I could pick up was how to go about implementing the increase in scale. And this has to be done through using two points, and finding the distance between them.

我的Java活动:

public class MainActivity extends Activity {
    ImageView imageView;
    ImageView dragHandle;
    RelativeLayout layout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = (ImageView) findViewById(R.id.imageView1);
        imageView.setBackgroundColor(Color.MAGENTA);
        dragHandle = (ImageView) findViewById(R.id.imageView2);
        dragHandle.setBackgroundColor(Color.CYAN);
        layout = (RelativeLayout) findViewById(R.id.relativeLayout2);
        layout.setBackgroundColor(Color.YELLOW);
        setUpResize();

    }

    public void setUpResize() {
        dragHandle.setOnTouchListener(new View.OnTouchListener() {

            int[] touchPoint = new int[2];
            int[] centerOfImage = new int[2];

            double originalDistance = 0;
            double modifiedDistance = 0;

            float originalScale = 0;
            float modifiedScale = 0;

            public boolean onTouch(View v, MotionEvent motionEvent) {

                if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {

                    centerOfImage[0] = (int) (imageView.getX() + imageView.getWidth() / 2);
                    centerOfImage[1] = (int) (imageView.getY() + imageView.getHeight() / 2);

                    touchPoint[0] = (int) motionEvent.getRawX();
                    touchPoint[1] = (int) motionEvent.getRawY();

                    int[] p = new int[2];
                    p[0] = touchPoint[0] - centerOfImage[0];
                    p[1] = touchPoint[1] - centerOfImage[1];

                    originalDistance = (float) Math.sqrt(p[0] * p[0] + p[1] * p[1]);
                    originalScale = imageView.getScaleX();

                } else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {
                    touchPoint[0] = (int) motionEvent.getRawX();
                    touchPoint[1] = (int) motionEvent.getRawY();

                    int[] p = new int[2];
                    p[0] = (touchPoint[0] + p[0] - centerOfImage[0]);
                    p[1] = (touchPoint[1] + p[1] - centerOfImage[1]);
                    modifiedDistance = Math.hypot(touchPoint[0] - centerOfImage[0], touchPoint[1] - centerOfImage[1]);

                    Log.e("resize", "original " + imageView.getWidth() + " modified: " + imageView.getHeight());
                    modifiedScale = (float) (modifiedDistance / originalDistance * originalScale);

                    imageView.setScaleX(modifiedScale);
                    imageView.setScaleY(modifiedScale);

                    dragHandle.setX(centerOfImage[0] + imageView.getWidth()/2 * modifiedScale);
                    dragHandle.setY(centerOfImage[1] + imageView.getHeight()/2 * modifiedScale);

                } else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {

                }
                return true;
            }
        });
    }
}

我的XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <RelativeLayout
        android:id="@+id/relativeLayout2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerInParent="true" >

        <ImageView
            android:id="@+id/imageView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:src="@drawable/ic_launcher" />

        <ImageView
            android:id="@+id/imageView2"
            android:layout_width="20dp"
            android:layout_height="20dp"
            android:layout_below="@+id/imageView1"
            android:layout_toRightOf="@+id/imageView1"
            android:src="@drawable/dragArrow" />

    </RelativeLayout>

</RelativeLayout>

推荐答案

所以... ...的主要问题是, getRawX() getRawY () MotionEvent 的方法提供的绝对的屏幕坐标的,而的getX()的getY()提供的布局坐标的。这样的坐标进度栏和状态栏,因此获得触摸坐标的时候,我们应该重新计算其相对于布局的高度不同。

So... The main problem is that getRawX() and getRawY() methods of MotionEvent provide absolute screen coordinates, while getX() and getY() provide layout coordinates. Coordinates thus differ on heights of progress bar and status bar, so when obtaining touch coordinates, we should recalculate them relatively to layout.

dragHandle.setOnTouchListener(new View.OnTouchListener() {

    float centerX, centerY, startR, startScale, startX, startY;

    public boolean onTouch(View v, MotionEvent e) {

        if (e.getAction() == MotionEvent.ACTION_DOWN) {

            // calculate center of image
            centerX = (imageView.getLeft() + imageView.getRight()) / 2f;
            centerY = (imageView.getTop() + imageView.getBottom()) / 2f;

            // recalculate coordinates of starting point
            startX = e.getRawX() - dragHandle.getX() + centerX;
            startY = e.getRawY() - dragHandle.getY() + centerY; 

            // get starting distance and scale
            startR = (float) Math.hypot(e.getRawX() - startX, e.getRawY() - startY);
            startScale = imageView.getScaleX();

        } else if (e.getAction() == MotionEvent.ACTION_MOVE) {

            // calculate new distance
            float newR = (float) Math.hypot(e.getRawX() - startX, e.getRawY() - startY);

            // set new scale
            float newScale = newR / startR * startScale;
            imageView.setScaleX(newScale);
            imageView.setScaleY(newScale);

            // move handler image
            dragHandle.setX(centerX + imageView.getWidth()/2f * newScale);
            dragHandle.setY(centerY + imageView.getHeight()/2f * newScale);

        } else if (e.getAction() == MotionEvent.ACTION_UP) {

        }
        return true;
    }
});

另外,我换成了库法计算斜边,并宣布所有的坐标为float以避免不必要的铸造。

Also, I replaced hypothenuse calculation by library method and declared all coordinates as float to avoid unnecessary casting.

这篇关于如何扩大在Android中使用手柄的看法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆