I need to get the height and width of the View before adding into layout or its is display. I have tried with using MeasuredHeight and MeasuredWidth of the view but its retursn as 0. Could you please help me out to resolve this?
Below code snippet I have tried out:
int height = Column.MeasuredHeight;
int width = Column.MeasuredWidth;
You need to use a Layout change event to not receive 0 as the height.
If you ask it too soon, the layout isn't drawn yet. Use the ViewTreeObserver of the layout that you want to measure.
LinearLayout linearLayout = FindViewById<LinearLayout>(Resource.Id.linearLayout);
ViewTreeObserver vto = linearLayout.ViewTreeObserver;
vto.GlobalLayout += (sender, args) => {
System.Console.WriteLine (linearLayout.Height);
};
Try view.getWidth() and view.getHeight()
View view= LayoutInflater.from(this).inflate(R.layout.activity_main, null, false);
setContentView(view);
int viewWidth = view.getWidth();
int viewHeight = view.getHeight();
Related
I am using CardView as a item of Recycler Adapter.
At first, all items will not show the whole content, (I cut it and put the '... ...' instead)
but after click it, the clicked item will scale its height to fit the content height. ( Here I set the text to the whole content and hope the card can scale to fit it )
looks like:
I know how to animate the height to the specific target height..
but in this case, I don't know how to measure the height needed to show the whole content, each item should have different target height.
How can I do it?
What you can do is ask the View to measure itself giving no constraint on its height. Please note the call to view.getWidth(), you can do that only after the View had been laid out, since you're calling it in onClick() it should be fine.
int widthSpec = View.MeasureSpec.makeMeasureSpec(view.getWidth(), View.MeasureSpec.EXACTLY);
int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
view.measure(widthSpec, heightSpec);
int targetHeight = view.getMeasuredHeight();
Assuming that your View is a TextView with these attributes set:
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
the full example would be
// this is the height measured with maxLines 1 and height
// to wrap_content
final int startHeight = view.getHeight();
// you want to measure the TextView with all text lines
view.setMaxLines(Integer.MAX_VALUE);
int widthSpec = View.MeasureSpec.makeMeasureSpec(view.getWidth(), View.MeasureSpec.EXACTLY);
int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
view.measure(widthSpec, heightSpec);
// final height of the TextView
int targetHeight = view.getMeasuredHeight();
// this is the value that will be animated from 0% to 100%
final int heightSpan = targetHeight-startHeight;
// remove that wrap_content and set the starting point
view.getLayoutParams().height = startHeight;
view.setLayoutParams(view.getLayoutParams());
Animation animation = new Animation(){
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
view.getLayoutParams().height = (int) (startHeight + heightSpan*interpolatedTime);
view.setLayoutParams(view.getLayoutParams());
}
};
animation.setDuration(1000);
view.startAnimation(animation);
you can do it very simple.
when set a text to TextView for the first time, write this:
int minLineNumber = 2;
textView.setMaxLines(minLineNumber); // 2 is your number of line for the first time
and when click on that:
textView.setMaxLines(Integer.MAX_VALUE); // set the height like wrap_content
if you want the animation, you have sth like this:
ObjectAnimator animation = ObjectAnimator.ofInt(
textView,
"maxLines",
textView.getLineCount());
int duration = (textView.getLineCount() - minLineNumber) * 50;
animation.setDuration(duration);
animation.start();
if the text in your TextView to too much, it's better to use a fixed duration, not depend on height.
I am trying to set the layout width programatically .
ViewTreeObserver vtoRecyclerView = mMainLayout.getViewTreeObserver();
vtoRecyclerView.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
mMainLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
ViewGroup.LayoutParams lpView = mMainLayout.getLayoutParams();
lpView.width = ViewGroup.LayoutParams.MATCH_PARENT-20;
mMainLayout.requestLayout();
}
});
but mMainLayout.getLayoutParams() is returning width as -1 .so when I set width as match_parent - 20 it becomes -21. I want to set the width as match_parent - 20.
What is wrong with the approach.
The root problem with your code here, is because you set the width with:
lpView.width = ViewGroup.LayoutParams.MATCH_PARENT-20;
while ViewGroup.LayoutParams.MATCH_PARENT is a constant.
You can find the constant on ViewGroup class
public static final int MATCH_PARENT = -1;
So that is obvious, because -1 - 20 is -21
What you can do here is, you can change the line to
lpView.width = mMainLayout.getWidth()-20;
try this.
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels;
ViewTreeObserver vtoRecyclerView = mMainLayout.getViewTreeObserver();
vtoRecyclerView.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
mMainLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
ViewGroup.LayoutParams lpView = mMainLayout.getLayoutParams();
lpView.width = width -20;
mMainLayout.requestLayout();
}
});
Try this.
ViewTreeObserver vtoRecyclerView = mMainLayout.getViewTreeObserver();
vtoRecyclerView.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if(mMainLayout.getWidth > 10 && mMainLayout.getHeight() > 10) // you can modify this value.
{
mMainLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
ViewGroup.LayoutParams lpView = mMainLayout.getLayoutParams();
lpView.width = ViewGroup.LayoutParams.MATCH_PARENT-20; // This seems to be wrong;
ViewParent parent = mMainLayout.getParent();
if(parent != null) {
lpView.width = (View)parent.getWidth();
}
mMainLayout.requestLayout();
}
}
});
I had the same problem while setting width as match_parent, I had resolved this by getting the phone screen width as follows:
Display display = ((Activity) context).getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int ActualWidth=width-(`margin you set for view`);
Hope it will help :)
As ViewGroup.LayoutParams.MATCH_PARENT constant predefined numeric value is -1 so you are getting -21 as result. and what you want can be achieved by defining margin to a layout rather than using that approach.
I have nested LinearLayouts where Parent height is 90 but the child view may have different heights according to the text set inside it and may overflow its parent. I Want to animate Parent to final Height of child but both methods of getHeight() on child and getMeasuredHeight() on parent, return 90 not 400.
parent.measure(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
targetHeight = parent.getMeasuredHeight();
//returns 90
and also
View child=((ViewGroup) parent).getChildAt(0);
int targetHeight=child.getHeight();
//returns 90
Try this code. Hope it'll work.
ViewGroup.LayoutParams params = yourView.getLayoutParams();
int height = params.height;
LayoutParams paramsChild = child.getLayoutParams();
LayoutParams paramsParent = parent.getLayoutParams();
paramsParent.height = paramsChild.height;
parent.setLayoutParams(paramsParent);
i have a RelativeLayout here's the code :
<RelativeLayout
android:id="#+id/camerapreview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:background="#000">
</RelativeLayout>
its a camera preview for the camera application, i set the width to match_parent.
and here is my java code :
RelativeLayout preview = (RelativeLayout) findViewById(R.id.camerapreview);
int w = preview.getWidth();
LayoutParams params = preview.getLayoutParams();
params.width = w;
params.height = w;
preview.addView(mPreview);
basically i decalaired the width of the RelativeLayout to match_parent to be dynamic to the width of any device. But i want the view to be square so i used the java code abave, but every time i ran the program this line int w = preview.getWidth(); returns zero. I must have missed something, help please :D thank you.
The size of view cannot be calculated until its parent is calculated you can force that with following code:
view.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
int widht = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
there is three way to do this, see this link
EDIT
you can use this too.
RelativeLayout layout = (RelativeLayout) findViewById(R.id.camerapreview);
ViewTreeObserver vto = layout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
hs.getViewTreeObserver().removeGlobalOnLayoutListener(this);
int width = layout.getMeasuredWidth();
int height = layout.getMeasuredHeight();
}
});
this may help you...
RelativeLayout preview = (RelativeLayout) findViewById(R.id.camerapreview);
int width = getResources().getDisplayMetrics().widthPixels;
ViewGroup.LayoutParams params = preview.getLayoutParams();
params.width = width;
params.height = width;
preview.setLayoutParams(params);
here preview will occupy entire screen width... and it will be square shaped...
Layout has width 'match parent' . So if it hasn't views (is empty) width = 0.
Solution:
Add views to layout
Or set width to 'fill parent'
I am trying to add a text to the textview for which i have set the width as Wrap_content. I am trying to get the width of this textview. But its showing 0 in all the cases. How Can i get the width of the textview after setting the text into it.
the code is as:
LinearLayout ll= new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
TextView tv = new TextView(this);
tv.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
ll.addView(tv);
tv.setText("Hello 1234567890-0987654321qwertyuio787888888888888888888888888888888888888888888888888");
System.out.println("The width is == "+tv.getWidth());// result is 0
this.setContentView(ll);
Please suggest.
Thanks in advance.
Views with the dynamic width/height get their correct size only after a layout process was finished (http://developer.android.com/reference/android/view/View.html#Layout).
You can add OnLayoutChangeListener to your TextView and get it's size there:
tv.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
public void onLayoutChange(View v, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) {
final int width = right - left;
System.out.println("The width is == " + width);
});
You can not get the width of a View with dynamic size before the layout is completely built. That means there is no way you can get it in onCreate(). One way would be to create a class that inherits from TextView and overrides onSizeChanged().
When are you calling this? Has it already been drawn to the screen?
It sounds like you are calling getWidth() too early.
You can also take a look at this question.
You should use this:
textView.getMeasuredWidth();
this works for me:
RelativeLayout.LayoutParams mTextViewLayoutParams = (RelativeLayout.LayoutParams) mTextView.getLayoutParams();
mTextView.setText(R.string.text);
mTextView.measure(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
int width = mShareTip.getMeasuredWidth();
//use the width to do what you want
mShareTip.setLayoutParams(mShareTipLayoutParams);
you can try this:
textView.measure(0,0);
int width = textView.getMeasuredWidth();
hello use this method:
textview.post(new Runnable() {
#Override
public void run() {
int width = textview.getWidth();
int height = textview.getHeight();
textview.setText( String.valueOf( width +","+ height ));
}
});
source: https://gist.github.com/omorandi/59e8b06a6e81d4b8364f
You can use this library to schedule the task of perform calculation on the width to the correct time after the view had been completely drawn
https://github.com/Mohamed-Fadel/MainThreadScheduler
Sample of use:
MainThreadScheduler.scheduleWhenIdle(new Runnable() {
#Override
public void run() {
int width = textview.getWidth();
int height = textview.getHeight();
textview.setText( String.valueOf( width +","+ height ));
}
});