How to Size an Android View Based on Its Parent's Dimensions

Set width and height based on dimentions of parent's parent Android Studio

It is possible to change a dynamic view's dimensions by code. So I would bet you should change the ImageView's layout parameters in the for loop before adding it to your LinearLayout like this:

for(Object intObj : page.content) {
ImageView imageView = new ImageView(this.getContext());
Drawable myDrawable = getResources().getDrawable((int) intObj);
imageView.setImageDrawable(myDrawable);
//Changing height...
imageView.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
//...and width
imageView.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
scrollViewLayout.addView(imageView);
}

This will set the ImageView's width and height to the containing (parent) LinearLayout's width and height.

Resize child view based on parent width and height

Finally I did what i need for .. So i just scale the template view

     if (isScaleLayout) {

view.setScaleX(scaleX);/0-1
view.setScaleY(scaleY);/0-1
view.setPivotX(0f);
view.setPivotY(getWidth());
}
**XML**

<FrameLayout
android:layout_width="150dp" // Actually size for layout/ adapter view
android:layout_height="80dp"
android:padding="3dp">

<com..Template
android:id="@+id/template"
android:layout_width="@dimen/template_height"//205
android:layout_height="@dimen/template_height"//205 />

</FrameLayout>

Custom view's onMeasure: how to get width based on height

Update: Modified code to fix some things.

First, let me say that you asked a great question and laid out the problem very well (twice!) Here is my go at a solution:

It seems that there is a lot going on with onMeasure that, on the surface, doesn't make a lot of sense. Since that is the case, we will let onMeasure run as it will and at the end pass judgment on the View's bounds in onLayoutby setting mStickyWidth to the new minimum width we will accept. In onPreDraw, using a ViewTreeObserver.OnPreDrawListener, we will force another layout (requestLayout). From the documentation (emphasis added):

boolean onPreDraw ()

Callback method to be invoked when the view tree is about to be drawn. At this point, all views in the tree have been measured and
given a frame. Clients can use this to adjust their scroll bounds or
even to request a new layout before drawing occurs.

The new minimum width set in onLayout will now be enforced by onMeasure which is now smarter about what is possible.

I have tested this with your example code and it seems to work OK. It will need much more testing. There may be other ways to do this, but that is the gist of the approach.

CustomView.java

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;

public class CustomView extends View
implements ViewTreeObserver.OnPreDrawListener {
private int mStickyWidth = STICKY_WIDTH_UNDEFINED;

public CustomView(Context context) {
super(context);
}

public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
logMeasureSpecs(widthMeasureSpec, heightMeasureSpec);
int desiredHeight = 10000; // some value that is too high for the screen
int desiredWidth;

int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);

int width;
int height;

// Height
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
height = Math.min(desiredHeight, heightSize);
} else {
height = desiredHeight;
}

// Width
if (mStickyWidth != STICKY_WIDTH_UNDEFINED) {
// This is the second time through layout and we are trying renogitiate a greater
// width (mStickyWidth) without breaking the contract with the View.
desiredWidth = mStickyWidth;
} else if (height > BREAK_HEIGHT) { // a number between onMeasure's two final height requirements
desiredWidth = ARBITRARY_WIDTH_LESSER; // arbitrary number
} else {
desiredWidth = ARBITRARY_WIDTH_GREATER; // arbitrary number
}

if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
width = Math.min(desiredWidth, widthSize);
} else {
width = desiredWidth;
}

Log.d(TAG, "setMeasuredDimension(" + width + ", " + height + ")");
setMeasuredDimension(width, height);
}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int w = right - left;
int h = bottom - top;

super.onLayout(changed, left, top, right, bottom);
// Here we need to determine if the width has been unnecessarily constrained.
// We will try for a re-fit only once. If the sticky width is defined, we have
// already tried to re-fit once, so we are not going to have another go at it since it
// will (probably) have the same result.
if (h <= BREAK_HEIGHT && (w < ARBITRARY_WIDTH_GREATER)
&& (mStickyWidth == STICKY_WIDTH_UNDEFINED)) {
mStickyWidth = ARBITRARY_WIDTH_GREATER;
getViewTreeObserver().addOnPreDrawListener(this);
} else {
mStickyWidth = STICKY_WIDTH_UNDEFINED;
}
Log.d(TAG, ">>>>onLayout: w=" + w + " h=" + h + " mStickyWidth=" + mStickyWidth);
}

@Override
public boolean onPreDraw() {
getViewTreeObserver().removeOnPreDrawListener(this);
if (mStickyWidth == STICKY_WIDTH_UNDEFINED) { // Happy with the selected width.
return true;
}

Log.d(TAG, ">>>>onPreDraw() requesting new layout");
requestLayout();
return false;
}

protected void logMeasureSpecs(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
String measureSpecHeight;
String measureSpecWidth;

if (heightMode == MeasureSpec.EXACTLY) {
measureSpecHeight = "EXACTLY";
} else if (heightMode == MeasureSpec.AT_MOST) {
measureSpecHeight = "AT_MOST";
} else {
measureSpecHeight = "UNSPECIFIED";
}

if (widthMode == MeasureSpec.EXACTLY) {
measureSpecWidth = "EXACTLY";
} else if (widthMode == MeasureSpec.AT_MOST) {
measureSpecWidth = "AT_MOST";
} else {
measureSpecWidth = "UNSPECIFIED";
}

Log.d(TAG, "Width: " + measureSpecWidth + ", " + widthSize + " Height: "
+ measureSpecHeight + ", " + heightSize);
}

private static final String TAG = "CustomView";
private static final int STICKY_WIDTH_UNDEFINED = -1;
private static final int BREAK_HEIGHT = 1950;
private static final int ARBITRARY_WIDTH_LESSER = 200;
private static final int ARBITRARY_WIDTH_GREATER = 800;
}

Get parent Width and Height

try this

ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
viewWidth = view.getParent().getWidth();
viewHeight = view.getParent().getHeight();
}
});
}

View half of its parent's height and width

Some fake layouts and and Layout Weight must do the trick..

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >

<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#FFFFFF"
android:orientation="vertical" >
</LinearLayout>

<LinearLayout
android:id="@+id/dummy"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:visibility="invisible" >
</LinearLayout>
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >

<LinearLayout
android:id="@+id/dummy"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:visibility="invisible" >
</LinearLayout>

<LinearLayout
android:id="@+id/dummy"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:visibility="invisible" >
</LinearLayout>
</LinearLayout>

</LinearLayout>

Change child views to fit parent's width when added dynamically

Change the width to match_parent, i think you need to keep the weight. Pass the parent layout to the inflater.

layout = (LinearLayout) inflater.inflate(R.layout.segmented_control, this); 
TextView item = (TextView) inflater.inflate(R.layout.segmented_control_item, layout, false);
layout.addChild(item);

I'm not sure if that works right away, you might need to experiment a little with the layout paramters.

defining ImageView width relative to parent view's width?

I think that there is no way you can re-size your image in half of the parent's width and hieght in relativeLayout but in linearlayout you can do it easily by layout weight.

If you want to do it in relativelayout you can create your own CustomImageView class that extends ImageView and override the onMeasure method of the ImageView from there you can then set your width that you desire which is 50%

example:

    public class ImageViewHalfWidth extends ImageView {

public ImageViewPefectSquare(Context context) {
super(context);
}

public ImageViewPefectSquare(Context context, AttributeSet attrs) {
super(context, attrs);
}

public ImageViewPefectSquare(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int measuredWidthHalf = getDefaultSize(getSuggestedMinimumWidth(),
widthMeasureSpec) / 2; //50% of the width of its parent
int measuredHeightHalf = getDefaultSize(getSuggestedMinimumHeight(),
heightMeasureSpec) / 2; //50% of the Height of its parent
setMeasuredDimension(measuredWidthHalf, measuredHeightHalf);
}

}

To use it in xml

 <com.yourpackage.ImageViewHalfWidth
android:id="@+id/imageView_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:src="@drawable/ic_computer" />

Android Sizing Views in XML Based On Parent View Size

As far as I know there is no way to achieve this through XML layout. You can add the following code in your activity in order to change the height of child view. Note that the size of the view is known once android has fininished activity layout. So you may add a listener to know when layout is ready and all sizes are known. I agree with Syed Zahid Ali that you can not fit larger child in smaller parent but as far as ScrollView is concerned this code should work:

final ViewGroup parentView = findViewById(R.id.parentView);
final View childView = parentView.findViewById(R.id.childView);

parentView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
float parentHeight = parentView.getHeight();

ViewGroup.LayoutParams params = childView.getLayoutParams();
params.height = (int)(parentHeight * 5);

childView.setLayoutParams(params);
//We want the listener to be called only the first time(in case it is initialized in onCreate())
parentView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});

Let child views determine size of parent view in android

I would think you would be able to set the layout_height for the parent to wrap_content. This way, it sets its view to be the size it needs to be depending on the sizes of the children inside it.



Related Topics



Leave a reply



Submit