【问题标题】:Custom Relative Layout scaling?自定义相对布局缩放?
【发布时间】:2012-03-19 06:18:34
【问题描述】:

我正在尝试制作可以缩放和滚动的自定义 RelativeLayout。现在我试图实现规模化。现在我已将自定义相对布局作为另一个相对布局的父布局,其中包含可触摸的 Imageview 作为其子布局。现在,当我缩放父级自定义相对布局时,子级也得到缩放,但 Imageview 的可点击区域翻译我不知道为什么?当 Imageview 或布局处于正常位置时,可点击区域位于 Imageview 上,但是一旦布局缩放,可点击区域就会移动?我不知道为什么我会面临可点击的奇怪位置位移

这里是代码

我的自定义相对布局

public class scaleLayout extends RelativeLayout {

    private float mScaleFactor=1.0f;
      private long lastTouchTime = -1;

    public scaleLayout(Context context)
    {
        super(context);

    //  setWillNotDraw(false);

    }

    public scaleLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        //setWillNotDraw(false);


        // TODO Auto-generated constructor stub
    }


/*  @Override 
    public boolean dispatchTouchEvent(MotionEvent event) { 
                return super.dispatchTouchEvent(event); 
       } */

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub

        return super.onTouchEvent(event);
    }


    @Override
      public boolean onInterceptTouchEvent(MotionEvent ev) {

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

          long thisTime = System.currentTimeMillis();
          if (thisTime - lastTouchTime < 250) {

            // Double tap
              mScaleFactor=1.5f;
              invalidate();
            lastTouchTime = -1;

          } else {

            // Too slow :)
            /*  mScaleFactor=1.0f;
              invalidate();*/
            lastTouchTime = thisTime;
          }
        }

        return super.onInterceptTouchEvent(ev);
      }




    @Override
    protected void dispatchDraw(Canvas canvas) {
        // TODO Auto-generated method stub

            canvas.save(Canvas.MATRIX_SAVE_FLAG);
            canvas.scale(mScaleFactor, mScaleFactor);
            super.dispatchDraw(canvas);
            canvas.restore();


    }


    @Override
    public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
        // TODO Auto-generated method stub
        return super.invalidateChildInParent(location, dirty);
    }

    protected void onLayout(boolean changed, int l, int t, int r, int b)
    {
        int count = getChildCount();
        for(int i=0;i<count;i++){
            View child = getChildAt(i); 
            if(child.getVisibility()!=GONE){
                RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)child.getLayoutParams();
                child.layout(
                    (int)(params.leftMargin * mScaleFactor), 
                    (int)(params.topMargin * mScaleFactor), 
                    (int)((params.leftMargin + child.getMeasuredWidth()) * mScaleFactor), 
                    (int)((params.topMargin + child.getMeasuredHeight()) * mScaleFactor) 
                    );
            }
        }
    }

这里是活动

public class LayoutZoomingActivity extends Activity implements OnTouchListener {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        ImageView img1 = (ImageView) findViewById(R.id.imageView1);
        img1.setOnTouchListener(this);
        ImageView img2 = (ImageView) findViewById(R.id.imageView2);
        img2.setOnTouchListener(this);

    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // TODO Auto-generated method stub

        ImageView iv= (ImageView) v;
        v.setVisibility(View.INVISIBLE);


        return false;
    }

这是 xml

<com.layoutzooming.scaleLayout  xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    >

 <RelativeLayout 
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/gm01"
    >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="jhkibnkij"
        android:layout_centerInParent="true"
        android:textColor="#FFFFFF"
        android:textSize="25dp" />

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView1"
        android:layout_marginLeft="500dp"
        android:layout_marginTop="250dp"
        android:background="#000"
        android:src="@drawable/dih01" />

     <ImageView
        android:id="@+id/imageView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView1"
        android:layout_marginLeft="350dp"
        android:layout_marginTop="250dp"
        android:background="#000"
        android:src="@drawable/dih02" />

 </RelativeLayout>
</com.layoutzooming.scaleLayout>

【问题讨论】:

  • 缩放后不调用onLayout。
  • 即使 Child 循环也没有调用,因为只有一个子项是 RelativeLayout。
  • @Pavandroid:如果我将自定义 relativeLayout 作为所有 imageViews 的父级而不是相对布局,为什么我的背景不会缩放
  • @Pavandroid : 相对布局会缩放,这意味着它的子元素也会得到缩放仪式的调用?

标签: android view viewgroup


【解决方案1】:

我如何通过在 LayoutZoomingActivity 中添加以下代码来解决此问题。

 public class LayoutZoomingActivity extends Activity implements OnTouchListener {

    ImageView img1;     ImageView img2;     /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        img1 = (ImageView) findViewById(R.id.imageView1);
        img1.setOnTouchListener(this);
        img2 = (ImageView) findViewById(R.id.imageView2);
        img2.setOnTouchListener(this);

    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // TODO Auto-generated method stub
        Log.d("b","b");
        if(isViewContains(img1, (int)event.getX(), (int)event.getY()))      {
            img1.setVisibility(View.GONE);      }
        if(isViewContains(img2, (int)event.getX(), (int)event.getY()))      {
            img2.setVisibility(View.GONE);      }

        return false;
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        Log.d("onTouchEvent c","c"+(int)event.getX()+","+(int)event.getY());
        if(isViewContains(img1, (int)event.getX(), (int)event.getY()))      {
            img1.setVisibility(View.GONE);
            img1.invalidate();      }
        if(isViewContains(img2, (int)(event.getX()/scaleLayout.mScaleFactor), (int)(event.getY()/scaleLayout.mScaleFactor)))        {
            img2.setVisibility(View.GONE);
            img2.invalidate();      }
        return super.onTouchEvent(event);
    }
    private boolean isViewContains(View view, int rx, int ry) {
        int[] l = new int[2];
        view.getLocationOnScreen(l);
        int x = l[0];
        int y = l[1];
        int w = view.getWidth();
        int h = view.getHeight();
        Log.d("isViewContains::"+x+"::"+y+"::"+w+"::"+h,rx+"::"+ry);
        if (rx < x || rx > x + w || ry < y || ry > y + h) {
            return false;
        }
        return true;
    } }

您可以试试这个并根据您的要求进行定制。

【讨论】:

  • scaleLayout中不需要onLayout方法
  • 感谢它的工作,但我没有得到它背后的逻辑?它怎么会不调用 onLayout ,因为 Parent 总是会向孩子询问孩子仪式的 onLayout ?能否请我解释一下上述逻辑.. 我很想学习这个缩放的东西
  • 其实onLayout只在创建Object的时候调用一次。在上面的逻辑中,我在 onTouchEvent() 中手动检查视图是否存在。这里的问题是我们可以缩放画布,因此当前视图的位置发生了变化,而不是根据之前的 X、Y 坐标。所以根据Android,它不知道新的翻译坐标,但它只知道过去的坐标。所以仍然在你的代码中为过去的坐标工作。
  • 根据我的代码,即使我没有使用每次用户触摸屏幕时都不会调用的 onTouch 方法。所以,我使用了 onTouchEvent。在这里,我得到了原始 X 和 Y 坐标。我正在检查 onTouchEvent 中的点是否存在于视图中,如果它存在,我正在做我想做的事情。
  • 我在 if(isViewContains(img2, (int)(event.getX()/scaleLayout.mScaleFactor), (int)(event.getY( )/scaleLayout.mScaleFactor)))
【解决方案2】:

父布局的实际范围(可缩放的相对布局)增加了,因此这个相对布局和图像视图都尝试将自己调整到与增加之前相同的位置。在缩放之前,它们相对于屏幕和现在缩放后,他们尝试调整到相同的位置。尝试使用线性布局进行缩放

【讨论】:

  • 所以你的意思是尝试自定义 LinearLayout 作为父布局?在RelativeLayout 和imageviews 里面? ..
猜你喜欢
  • 2016-11-05
  • 1970-01-01
  • 2012-09-08
  • 2012-02-29
  • 2013-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-05
相关资源
最近更新 更多