0

I have a view-group (ZoomableViewGroup is my custom class extending ViewGroup) in my layout as parent, which inside contains a relative layout. The width and height of ViewGroup is by default 2286 height and 1600 width which is larger than device size. How to set the ViewGroup size to screen size ? My final expected result is, I am trying to zoom and pan the relative out, it moves out of screen due to the huge size of ViewGroup.

<com.example.pdoc.zoomablepdf.ZoomableViewGroup
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/zoomLayout"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:background="@drawable/samplebg"
        android:id="@+id/RelLayout">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:id="@+id/LinLayout">
        </LinearLayout>
    </RelativeLayout>
</com.example.pdoc.zoomablepdf.ZoomableViewGroup>

Java code

ZoomableViewGroup mZoomableViewGroup;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_mainnew);

    mZoomableViewGroup = (ZoomableViewGroup) findViewById(R.id.zoomLayout);

    LinearLayout ll = (LinearLayout)findViewById(R.id.LinLayout);
    //add edittext dynamically
            EditText myText = new EditText(MainnewActivity.this);
            myText.setText("Edit Me");
            LinearLayout.LayoutParams lp = new
                    LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);
            lp.gravity= Gravity.CENTER_HORIZONTAL;
            ll.addView(myText, lp);
    //add checkbox dynamically
            CheckBox myChk = new CheckBox(MainnewActivity.this);
            myChk.setText("Check me");
            LinearLayout.LayoutParams chklp = new
                    LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);
            chklp.gravity= Gravity.CENTER_HORIZONTAL;
            ll.addView(myChk, chklp);
    //add imageview dynamically
        ImageView myImg = new ImageView(MainnewActivity.this);
        myImg.setImageResource(R.drawable.apple);
        LinearLayout.LayoutParams imgLP = new
                LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT);
        imgLP.gravity= Gravity.CENTER_HORIZONTAL;
        ll.addView(myImg, imgLP);
    //add button dynamically
        Button mybtn1 = new Button(MainnewActivity.this);
        mybtn1.setText("Click me");
        LinearLayout.LayoutParams btnLP = new
                LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT);
        btnLP.gravity= Gravity.CENTER_HORIZONTAL;
        ll.addView(mybtn1, btnLP);

        mybtn1.setOnClickListener(new View.OnClickListener() {
           @Override
         public void onClick(View v) {
               Toast.makeText(MainnewActivity.this, "6--"+ mZoomableViewGroup.getHeight() + "_" + mZoomableViewGroup.getWidth(),Toast.LENGTH_SHORT).show();
        }
    });
}

ZoomableViewGroup class code

public class ZoomableViewGroup extends ViewGroup {

// States.
private static final byte NONE = 0;
private static final byte DRAG = 1;
private static final byte ZOOM = 2;
private static final byte DTAP = 3;

private byte mode = NONE;

// Matrices used to move and zoom image.
private Matrix matrix = new Matrix();
private Matrix matrixInverse = new Matrix();
private Matrix savedMatrix = new Matrix();

// Parameters for zooming.
private PointF start = new PointF();
private PointF mid = new PointF();
private float oldDist = 1f;
private float[] lastEvent = null;
private long lastDownTime = 0l;

private float[] mDispatchTouchEventWorkingArray = new float[2];
private float[] mOnTouchEventWorkingArray = new float[2];

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    mDispatchTouchEventWorkingArray[0] = ev.getX();
    mDispatchTouchEventWorkingArray[1] = ev.getY();
    mDispatchTouchEventWorkingArray = screenPointsToScaledPoints(mDispatchTouchEventWorkingArray);
    ev.setLocation(mDispatchTouchEventWorkingArray[0], mDispatchTouchEventWorkingArray[1]);
    return super.dispatchTouchEvent(ev);
}
public ZoomableViewGroup(Context context) {
    super(context);
    Toast.makeText(context, "c1-" + this.getHeight() + "_" + this.getWidth(), Toast.LENGTH_SHORT).show ();
    init(context);
}
public ZoomableViewGroup(Context context, AttributeSet attrs) {
    super(context, attrs);
    Toast.makeText(context, "c2-" + this.getHeight() + "_" + this.getWidth(), Toast.LENGTH_SHORT).show ();
    init(context);
}
public ZoomableViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    Toast.makeText(context, "c3-" + this.getHeight() + "_" + this.getWidth(), Toast.LENGTH_SHORT).show ();
    init(context);
}
private void init(Context context) {
}

//Determine the space between the first two fingers
private float spacing(MotionEvent event) {
    float x = event.getX(0) - event.getX(1);
    float y = event.getY(0) - event.getY(1);
    return (float) Math.sqrt(x * x + y * y);
}

//Calculate the mid point of the first two fingers
private void midPoint(PointF point, MotionEvent event) {
    float x = event.getX(0) + event.getX(1);
    float y = event.getY(0) + event.getY(1);
    point.set(x / 2, y / 2);
}

private float[] scaledPointsToScreenPoints(float[] a) {
    matrix.mapPoints(a);
    return a;
}

private float[] screenPointsToScaledPoints(float[] a) {
    matrixInverse.mapPoints(a);
    return a;
}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    //super.onLayout(changed, left, top, right, bottom);
    int childCount = getChildCount();
    for (int i = 0; i < childCount; i++) {
        View child = getChildAt(i);
        if (child.getVisibility() != GONE) {
            child.layout(child.getLeft(), child.getTop(), child.getLeft()+child.getMeasuredWidth(), child.getTop()+child.getMeasuredHeight());
        }
    }
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    //measure(widthMeasureSpec, heightMeasureSpec);
    int childCount = getChildCount();
    for (int i = 0; i < childCount; i++) {
        View child = getChildAt(i);
        if (child.getVisibility() != GONE) {
            measureChild(child, widthMeasureSpec, heightMeasureSpec);
        }
    }
    //measure(widthMeasureSpec, heightMeasureSpec);
}

@Override
protected void dispatchDraw(Canvas canvas) {
    float[] values = new float[9];
    matrix.getValues(values);
    canvas.save();
    canvas.translate(values[Matrix.MTRANS_X], values[Matrix.MTRANS_Y]);
    canvas.scale(values[Matrix.MSCALE_X], values[Matrix.MSCALE_Y]);
    super.dispatchDraw(canvas);
    canvas.restore();
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    // handle touch events here
    mOnTouchEventWorkingArray[0] = event.getX();
    mOnTouchEventWorkingArray[1] = event.getY();
    mOnTouchEventWorkingArray = scaledPointsToScreenPoints(mOnTouchEventWorkingArray);
    event.setLocation(mOnTouchEventWorkingArray[0], mOnTouchEventWorkingArray[1]);

    switch (event.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            savedMatrix.set(matrix);
            mode = DRAG;
            lastEvent = null;
            long downTime = event.getDownTime();
            if (downTime - lastDownTime < 300l) {
                float density = getResources().getDisplayMetrics().density;
                if (Math.max(Math.abs(start.x - event.getX()), Math.abs(start.y - event.getY())) < 20.f * density) {
                    savedMatrix.set(matrix);
                    mid.set(event.getX(), event.getY());
                    mode = ZOOM;
                    lastEvent = new float[4];
                    lastEvent[0] = lastEvent[1] = event.getX();
                    lastEvent[2] = lastEvent[3] = event.getY();
                }
                lastDownTime = 0l;
            } else {
                lastDownTime = downTime;
            }
            start.set(event.getX(), event.getY());
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            oldDist = spacing(event);
            if (oldDist > 10f) {
                savedMatrix.set(matrix);
                midPoint(mid, event);
                mode = ZOOM;
            }
            lastEvent = new float[4];
            lastEvent[0] = event.getX(0);
            lastEvent[1] = event.getX(1);
            lastEvent[2] = event.getY(0);
            lastEvent[3] = event.getY(1);
            break;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_POINTER_UP:
            mode = NONE;
            lastEvent = null;
            break;
        case MotionEvent.ACTION_MOVE:
            final float density = getResources().getDisplayMetrics().density;
            if (mode == DRAG) {
                matrix.set(savedMatrix);
                float dx = event.getX() - start.x;
                float dy = event.getY() - start.y;

                RelativeLayout Rel = (RelativeLayout)findViewById(R.id.RelLayout);
                //getGlobalVisibleRect(Rel);
                ZoomableViewGroup ZVG = (ZoomableViewGroup) findViewById(R.id.zoomLayout);
                Rel.getTop();
                Rel.getY();
                //if(dx > 0) dx=0;
                //if(dy > 0) dy=0;
               //Toast.makeText(getContext(), dx + "_" + dy + "REL=" + Rel.getTop()+"_"+ Rel.getLeft(), Toast.LENGTH_SHORT).show ();
                //Toast.makeText(getContext(), ZVG.getHeight() + "-" + ZVG.getWidth(), Toast.LENGTH_SHORT).show ();
                matrix.postTranslate(dx, dy);
                matrix.invert(matrixInverse);
                if (Math.max(Math.abs(start.x - event.getX()), Math.abs(start.y - event.getY())) > 20.f * density) {
                    lastDownTime = 0l;
                }
            } else if (mode == ZOOM) {
                if (event.getPointerCount() > 1) {
                    float newDist = spacing(event);
                    if (newDist > 10f * density) {
                        matrix.set(savedMatrix);
                        float scale = (newDist / oldDist);

                        //to restrict the min zoom not tobe less than screen size
                        float[] values = new float[9];
                        matrix.getValues(values);
                        if(scale*values[matrix.MSCALE_X] <= 1)
                        { scale = 1/values[matrix.MSCALE_X]; }
                        //till here
                        //condition to check maximum zoom scale to 10
                        if(scale * values[matrix.MSCALE_X] <10)
                        matrix.postScale(scale, scale, mid.x, mid.y);
                        matrix.invert(matrixInverse);
                    }
                } else {
                    matrix.set(savedMatrix);
                    float scale = event.getY() / start.y;

                    //to restrict the min zoom to 1 or not less than screen size
                    float[] values = new float[9];
                    matrix.getValues(values);
                    if(scale*values[matrix.MSCALE_Y] <= 1)
                    { scale = 1/values[matrix.MSCALE_Y]; }
                    //till here
                    //condition to check maximum zoom scale to 10
                    if(scale * values[matrix.MSCALE_Y] <10)
                    matrix.postScale(scale, scale, mid.x, mid.y);
                    matrix.invert(matrixInverse);
                }
            }
            break;

    }

    invalidate();
    return true;
}

}

dev_P
  • 73
  • 10

1 Answers1

0

Hope this helps . Try to Set the height and width of viewgroup dynamically.

Display display = getWindowManager().getDefaultDisplay();
ZoomableViewGroup layout= (ZoomableViewGroup) findViewById(R.id.zoomLayout);
int width=display.getWidth();
int height=display.getHeight();
FrameLayout.LayoutParams parms = new FrameLayout.LayoutParams(width,height);
layout.setLayoutParams(parms);
Dipali Shah
  • 3,742
  • 32
  • 47
  • I just want it to be the size of screen only...say equivalent to size of relativelayout which is in viewgroup.. – dev_P Aug 19 '16 at 07:24
  • Adjust width and height according to relativelayout width and height. Get height and width of relativelayout and set it to your main layout.[http://stackoverflow.com/questions/12068945/get-layout-height-and-width-at-run-time-android] – Dipali Shah Aug 19 '16 at 09:32
  • Even the size of relativelayout is same as in layout it's height and width are set to matchparent.. – dev_P Aug 22 '16 at 04:52