缩放中旬左右在Android的两个手指点缩放、中旬、两个、Android

2023-09-07 01:53:00 作者:眼眸的颓废

我里面有它 Horizo​​ntalScrollView ,其中有多个视图。我已实施捏缩放手势在多个视图,这是我的两个手指之间,缩放。

I have a HorizontalScrollView in which there are multiple views inside it. I have implemented pinch zoom gesture in which multiple views, which are between my two fingers, are scaled.

但我面对的毛刺。当我做双指缩放,中点捏变焦的移动,但对于用户体验我想这点是保持固定,同时扩展其他的事情应该调整自己,这样中点保持不变。

But I am facing one glitch. When I am doing pinch zoom, the mid point of pinch zoom is moving but for user experience I want this point to be remain fixed and other things should adjust itself while scaling so that mid point remains static.

谁能告诉我该怎么做。

的onDraw()自定义视图的方法是

                Rect r =new Rect(0, 0, 700, 40);

    public void onDraw(Canvas canvas) {

        float kk=mScaleFactor;    //this variable will be set by pinch zoom event and represent how much to scale
        sf*=kk;                   // this view must scale according to previous scaling  


        canvas.save();
        canvas.scale(sf , 1);
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.BLUE); 
        canvas.drawRect(r, paint);
        width=sf*700;
        canvas.restore();
        requestLayout();                               //this will change view width to fit the expanded rectangle 
        }

onMeasure方法被调用的requestLayout

onMeasure method is called on requestLayout

        @Override protected void onMeasure(int widthMeasureSpec,
              int heightMeasureSpec) {
            setMeasuredDimension((int)width, 340);
          }

上面的自定义视图是由 Horizo​​ntalScrollView 的子类,称为12倍。所以有 Horizo​​ntalScrollview 12子视图。

The above custom view is called 12 times by a subclass of HorizontalScrollView. So there are 12 child views of HorizontalScrollview.

在这个类我做下面的事情

In this class I am doing the following things

检测到触摸坐标两个手指。

Detecting the touch coordinates of two fingers.

在计算其第一手指触摸子视图索引。

Calculating the index of child view on which first finger is touched.

在计算其第二个手指触摸子视图索引。

Calculating the index of child view on which second finger is touched.

传递比例因子开始和最后之间的所有子视图。这两个指数在previous两步计算。

Passing scale factor of pinch zoom to all the child views between start and last. These two indices are calculated in previous two step.

和最后无效()调用子视图。所以,孩子可以根据父视图通过比例系数扩展本身。

And finally invalidate() is called on the child view. So child can scale itself according to scale factor passed by parent view.

但这里存在一个问题。中间点的两个手指应保持静态和其他的东西应该缩放过程中进行调整。但我的中点与缩放移动。

But there is one problem here. The mid point of two finger should remain static and other things should adjust during scaling. But my mid point is moving with scaling.

有人可以帮助我在做这个。请告诉我,如果code的任何部分需要。

Can someone help me in doing this. Please tell me if any part of code is require.

$ C $ Horizo​​ntalScrollview 的姿态监听c是

Code of gesture listener of HorizontalScrollview is

      private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
        @Override
        public boolean onScale(ScaleGestureDetector detector) {
               mScaleFactor *= detector.getScaleFactor();
            mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f));

            ViewGroup pp=takeparent(); //give object of this class

            for(int i=start;i<=last;i++)
            {
                LinearLayout ll=(LinearLayout)pp.getChildAt(i);
                DrawView view=(DrawView)ll.findViewById(R.id.drawview);
                view.mScaleFactor=mScaleFactor;
                view.invalidate();
                view.donesf=true;
            }

样我的应用

Sample app of mine

编辑所建议的意见:

        private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
        @Override
        public boolean onScale(ScaleGestureDetector detector) {
               mScaleFactor *= detector.getScaleFactor();
            mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f));

            ViewGroup pp=takeparent(); pp contains all the custom child views

            //start and last are indices of range of child for which we have to apply gesture
            for(int i=start;i<=last;i++)
            {
                LinearLayout ll=(LinearLayout)pp.getChildAt(i);
                DrawView view=(DrawView)ll.findViewById(R.id.drawview);

                view.mScaleFactor=mScaleFactor;
                view.pivotx=detector.getFocusX()+view.getLeft();
                view.pivoty=detector.getFocusY()+view.getTop();
                view.invalidate();
            }




            return true;
        } 

这是自定义的视图的onDraw方法

This is custom view onDraw method

       public void onDraw(Canvas canvas) {

        sf=mScaleFactor  //this scale factor is set by parent view    
        width=sf*700;  //this width will be use to rescale the view's width in requestLayout()

        canvas.save();

        canvas.scale(sf,1,pivotx,pivoty);  //pivotX and pivotY are also set by parent's onScale method of gestureListener
        canvas.drawRect(r, paint);
        requestLayout();
        canvas.restore();

        } 

推荐答案

有关你缩放,您可以设置不变一点,不应该使用移动视图 setPivotX() setPivotY()。当我使用一个 ScaleGestureDetector ,我用的是焦点点这一点。例如:

For a view you are scaling, you can set the "invariant" point that should not move using setPivotX() and setPivotY(). When I use a ScaleGestureDetector, I use the focus point for this. For example:

    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector)
    {
        ...
        mScaledView.setPivotX(detector.getFocusX());
        mScaledView.setPivotY(detector.getFocusY());
        ...

我不知道,如果你想与所有的孩子,或者只是父视图要做到这一点,你的情况,但通常你只需要做到这一点,以一个单一的父母的观点,它会正常工作该视图的孩子。

I'm not sure if you want to do this with all of the children, or just the parent view, in your case, but usually you just need to do this to a single "parent" view and it will work properly for the children of that view.

与此相关的,我不明白为什么你缩放父视图将扩大其所有的孩子太路过时缩放系数下降到每一个孩子。也许你只需要添加一个的FrameLayout (或其他的ViewGroup 后代)到 Horizo​​ntalScrollView 托管孩子,然后就扩展了(适当设置它的支点之后)?

Related to this, I didn't quite understand why you're passing the scaling factor down to each child when scaling the parent view will scale all of its children too. Maybe you just need to add a single FrameLayout (or some other ViewGroup descendent) into your HorizontalScrollView that hosts the children and then just scale that (after setting its pivot appropriately)?

更新再评论

既然你只需要在规模手指之间的挤压区的意见,我相信你有几个选择,具体取决于您的应用程序:

Given that you only want to scale the views in the pinched region between the fingers, I believe you have a couple options, depending on your app:

1)动态只是那些意见添加到中间的FrameLayout 这被缩放,并拥有透视集,留下不可伸缩的意见作为 Horizo​​ntalScrollView ;或

1) Dynamically add just those views to an intermediate FrameLayout which gets scaled and has its pivot set, leaving the non-scaled views as direct children of the HorizontalScrollView; or

2)的焦点传递到每个缩放子视图后的第一次调整对孩子的位置。例如,假设你的 DrawView 直接或间接地从 android.view.View ,我会强烈建议继承,那么你可以这样做:

2) Passing down the focus point to each scaled child view after first adjusting for the child's position. For example, assuming your DrawView either directly or indirectly inherits from android.view.View, which I would strongly recommend, then you can do something like:

    for (int i = start; i <= last; i++) {
        LinearLayout ll = (LinearLayout)pp.getChildAt(i);
        DrawView view = (DrawView)ll.findViewById(R.id.drawview);

        view.setScaleX(mScaleFactor);
        view.setScaleY(mScaleFactor);
        view.setPivotX(detector.getFocusX() - view.getLeft());    // Note: minus, not plus...
        view.setPivotY(detector.getFocusY() - view.getTop());
        view.invalidate();
    }
 
精彩推荐
图片推荐