I have designed an layout in which LinearLayout has 2 children LinearLayout and FrameLayout and in each child I put different views.
I just wanted to measure height and width of FrameLayout so that I could serve my purpose.
In program I am using
int height,width;
FrameLayout fr=(FrameLayout)findviewbyid(R.id.fr);
height=fr.getHeight();
width=fr.getWidth();
returns value as 0 for both
Even I tried with following code
int height,width;
FrameLayout fr=(FrameLayout)findviewbyid(R.id.fr);
height=fr.getMeasuredHeight();
width=fr.getMeasuredWidth();
returns same value 0
and finally I tried with following code,
int height,width;
FrameLayout fr=(FrameLayout)findviewbyid(R.id.fr);
height=fr.getgetLayoutParams().height();
width=fr.getLayoutParams().width;
returns me -2 and -1
I want the solution to get height and width of any layout programmatically?
The view itself, has it's own life cycle which is basically as follows:
Attached
Measured
Layout
Draw
So, depending on when are you trying to get the width/height you might not see what you expect to see, for example, if you are doing it during onCreate, the view might not even been measured by that time, on the other hand if you do so during onClick method of a button, chances are that by far that view has been attached, measured, layout, and drawn, so, you will see the expected value, you should implement a ViewTreeObserver to make sure you are getting the values at the proper moment.
LinearLayout layout = (LinearLayout)findViewById(R.id.YOUR VIEW ID);
ViewTreeObserver vto = layout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
this.layout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
this.layout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
int width = layout.getMeasuredWidth();
int height = layout.getMeasuredHeight();
}
});
As CapDroid say, you are trying to get the size before the view drawn, another possible solution could be to do a Post with a runnable on the View:
mView.post(new Runnable() {
#Override
public void run() {
int width = mView.getWidth();
int height = mView.getHeight();
}
}
Just wanted to add an answer here, since Koltin has some convenience methods to do this, which are a lot less ugly than adding and removing a onGlobalLayoutListener:
view.doOnLayout {
it.measuredWidth
it.measuredHeight
}
You can see more of the convinience methods here.
I think you are getting Height and Width in OnCreate() method that's why you getting always 0 values because at that time your view still not created.
Try to get height and width on some button click or else..
just give your height and You will get height or even width if wanted.
/**
* Get the view height before the view will render
* #param view the view to measure
* #return the height of the view
*/
public static int getViewHeight(View view) {
WindowManager wm =
(WindowManager) view.getContext().getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int deviceWidth;
if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2){
Point size = new Point();
display.getSize(size);
deviceWidth = size.x;
} else {
deviceWidth = display.getWidth();
}
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(deviceWidth, View.MeasureSpec.AT_MOST);
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
view.measure(widthMeasureSpec, heightMeasureSpec);
return view.getMeasuredHeight(); // view.getMeasuredWidth();
}
In Kotlin you can simply do this:
fr.post {
height=fr.height
width=fr.width
}
If you get -1 or -2 it could also be the numeric value of LayoutParams.WRAP_CONTENT (-2) or LayoutParams.MATCH_PARENT (-1).
I had same issue but didn't want to draw on screen before measuring so I used this method of measuring the view before trying to get the height and width.
Example of use:
layoutView(view);
int height = view.getHeight();
//...
void layoutView(View view) {
view.setDrawingCacheEnabled(true);
int wrapContentSpec =
MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
view.measure(wrapContentSpec, wrapContentSpec);
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
}
Most easiest way is to use ViewTreeObserver, if you directly use .height or .width you get values as 0, due to views are not have size until they draw on our screen. Following example will show how to use ViewTreeObserver
ViewTreeObserver viewTreeObserver = YOUR_VIEW_TO_MEASURE.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
YOUR_VIEW_TO_MEASURE.getViewTreeObserver().removeOnGlobalLayoutListener(this);
int viewHeight = YOUR_VIEW_TO_MEASURE.getHeight();
int viewWeight = YOUR_VIEW_TO_MEASURE.getWidth();
}
});
}
if you need to use this on method, use like this and to save the values you can use globle variables.
try with this metods:
int width = mView.getMeasuredWidth();
int height = mView.getMeasuredHeight();
Or
int width = mTextView.getMeasuredWidth();
int height = mTextView.getMeasuredHeight();
try something like this code from this link
ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
viewWidth = view.getWidth();
viewHeight = view.getHeight();
}
});
}
hope this helps.
As I just ran into this problem thought I would write it for kotlin,
my_view.viewTreeObserver.addOnGlobalLayoutListener {
// here your view is measured
// get height using my_view.height
// get width using my_view.width
}
or
my_view.post {
// here your view is measured
// get height using my_view.height
// get width using my_view.width
}
If you code in Kotlin use this nice extension function :
inline fun View.getDimensions(crossinline onDimensionsReady: (Int, Int) -> Unit) {
lateinit var layoutListener: ViewTreeObserver.OnGlobalLayoutListener
layoutListener = ViewTreeObserver.OnGlobalLayoutListener {
viewTreeObserver.removeOnGlobalLayoutListener(layoutListener)
onDimensionsReady(width, height)
}
viewTreeObserver.addOnGlobalLayoutListener(layoutListener)
}
Usage :
view.getDimensions { width, height ->
println("width = $width")
println("height = $height")
}
The first snippet is correct, but you need to call it after onMeasure() gets executed. Otherwise the size is not yet measured for the view.
For frame:
height=fr.getHeight();
width=fr.getWidth();
For screen:
width = getWindowManager().getDefaultDisplay().getWidth();
height = getWindowManager().getDefaultDisplay().getHeight();
I used DisplayMetrics to get the screen size and then i can assign the width/height to an element in %age
It will be like this
DisplayMetrics dmetrics = new DisplayMetrics();
int widthPixels=dmetrics.widthPixels;
int heightPixels=dmetrics.heightPixels;
//setting the height of the button
button_nextPuzzle.setMinHeight((int) ((heightPixels/3)*.30));
Worked for me very well!!!
Check behavior
Very Simple Solution
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.d(LOG, "MainActivity - onCreate() called")
fragments_frame.post {
Log.d(LOG, " fragments_frame.height:${fragments_frame.width}")
Log.d(LOG, " fragments_frame.height:${fragments_frame.measuredWidth}")
}
}
getDefaultDisplay().getHeight is deprecated. So better to use
getResources().getDisplayMetrics().heightPixels;
you can use coroutines as well, like this one :
CoroutineScope(Dispatchers.Main).launch {
delay(10)
val width = view.width()
val height= view.height()
// do your job ....
}
Related
I am inflating a view using the call
final View view = mActivity.getLayoutInflater().inflate(R.layout.photo_view, null, false);
The view is being inflated for the sole purpose of turning it into a Bitmap.
The following call is not working. Now if I make the call inside a DialogFragment's onCreateView it works -- so I know the code snippet itself works. But if I am just inflating the view for Bitmap conversion then the method public void onGlobalLayout() is never called.
ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
Log.i(TAG, "waiting for right time");
view.getViewTreeObserver().addOnGlobalLayoutListener(new
ViewTreeObserver.OnGlobalLayoutListener() {
#SuppressLint("NewApi")
#Override
public void onGlobalLayout() {
if (view.getLayoutParams().width <= 0 || view.getLayoutParams().height <= 0) {
int height = getDeviceHeight(mActivity);
int width = getDeviceWidth(mActivity);
LayoutParams layout = view.getLayoutParams();
layout.height = height;
layout.width = width;
view.setLayoutParams(layout);
}
doMyWork(view);
if (Utils.hasJellyBean()) {
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
}
});
}
I need this method because I want to have a non-zero dimension to create my bitmap from otherwise I get null for say, view.getDrawingCache(). So how do I force the execution of ViewTreeObserver.OnGlobalLayoutListener
Your view is not attached to window. Try call view.requestLayout() after onGlobalLayoutListener adding.
Your view is never attached to a window -- it will never be laid out by the framework. You will need to either attach it to a window (e.g. put it in your layout somewhere) or measure and lay it out manually.
int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
view.measure(widthSpec, heightSpec);
view.layout(view.getMeasuredWidth(), view.getMeasuredHeight());
After measuring a View with a constant dimensions with view.measure(), the getMeasuredHeight() and getMeasureWidth() is returning 0.
layout_view.xml, layout which is inflated to create the view
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dp"
android:layout_height="100dp">
</FrameLayout>
function which measures the dimensions
public void measureView(Context context){
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.layout_view,null,false);
view.measure( View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
Log.d(TAG,"Error width : " + view.getMeasuredWidth());
Log.d(TAG,"Error height : " + view.getMeasuredHeight());
}
When you call view.getMeasuredWidth() in onCreate() or onCreateView(), the view has not been drawn yet. So you need to add a listener and will get a callback when the view is being drawn. Just like this in my code:
final ViewTreeObserver vto = view.getViewTreeObserver();
if (vto.isAlive()) {
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
int viewWidth = view.getMeasuredWidth();
// handle viewWidth here...
if (Build.VERSION.SDK_INT < 16) {
vto.removeGlobalOnLayoutListener(this);
} else {
vto.removeOnGlobalLayoutListener(this);
}
}
});
}
NOTE: Remove the listener for better performance!
Don't call vto.removeOnGlobalLayoutListener(this) to remove the listener. Call it like this:
vto.getViewTreeObserver()
Are you measuring the view in onCreate(). The view isn't drawn yet. You have to wait until a time after the view is drawn before you can measure it.
Simple solution for this is to post a runnable to the layout. The runnable will be executed after the layout has happened.
For more info See this post
Edit
try to change
view.measure( View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
to
view.measure( View.MeasureSpec.EXACTLY, View.MeasureSpec.EXACTLY);
Try this way,hope this will help you to solve your problem.
view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
int width = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
}
});
if your measured view has visibility set to gone, measuring will return 0. You can set it to visible, measure, and then set back to gone, all from code.
You can not use View.MeasureSpec.* directly in measure call. Instead first makeMeasureSpec() and then use it to invoke measure():
final int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(ViewGroup.LayoutParams.WRAP_CONTENT/*can be match_parent or some exact value*/, View.MeasureSpec.UNSPECIFIED);
final int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(ViewGroup.LayoutParams.WRAP_CONTENT/*can be match_parent or some exact value*/, View.MeasureSpec.UNSPECIFIED);
view.measure(widthMeasureSpec, heightMeasureSpec);
Just in case someone was experiencing this problem with ImageView:
I noticed that if your ImageView doesn't have "android:src" set (i.e. you change it dynamically) it will always return zero from getMeasuredWidth/Height.
A simple workaround would be to set a placeholder for view.
You can use getViewTreeObserver in onCreate/onCreateView and other events.
fun setGlobalLayoutListener(view: View, method: () -> Unit) {
val vto1 = view.viewTreeObserver
if (vto1.isAlive) {
vto1.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
val vto2 = view.viewTreeObserver
if (vto2.isAlive) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
vto2.removeOnGlobalLayoutListener(this)
} else {
#Suppress("DEPRECATION")
vto2.removeGlobalOnLayoutListener(this)
}
// Your actions are here:
method()
}
}
})
}
}
And call it: setGlobalLayoutListener(view) {updateUI(view)}.
I also tried
view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
and then called view.control.measuredWidth in onCreateView()/onViewCreated(). But in some emulators (API 19) it returned wrong results.
I am dynamically creating some ImageViews inside a relativeLayout but I need the size to vary depending on the height and width of the screen. At the point where I set the height the views and layouts havent been created which means that the getHeight() and getWidth() are returning 0. I have looked at other threads on StackOverflow but none seem specific enough to my problem.
I am doing all this in a Fragment and would appreciate any guidance on how to solve this. Her is a small snippet of my code.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.fragment_hello_moon, parent, false);
RelativeLayout rl = (RelativeLayout) v.findViewById(R.id.l1);
tl.setBackgroundColor(Color.RED);
ArrayList<ImageView> imgViews = new ArrayList<ImageView>();
//Cant get height or width of parent as hasnt been created yet
int numberOfBells = 16;
int height = rl.getHeight() / numberOfBells;
int width = rl.getWidth() / 2;
final ImageView imageTopL = new ImageView(getActivity());
if (true){
imageTopL.setId(1);
imageTopL.setImageResource(R.drawable.bell_dl_256);
RelativeLayout.LayoutParams params1 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
params1.addRule(RelativeLayout.ALIGN_PARENT_TOP);
params1.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
params1.setMargins(50,10,0,10);
imageTopL.setLayoutParams(params1);
//Need the size to vary depending on the height/width
imageTopL.getLayoutParams().height = height;
imageTopL.getLayoutParams().width = width;
imageTopL.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
imageTopL.setImageResource(R.drawable.bell_ul_256);
}
});
imgViews.add(imageTopL);
}
for(ImageView i : imgViews){
rl.addView(i);
}
return v;
}
to get the size of the screen you can try:
DisplayMetrics metrics = this.getResources().getDisplayMetrics();
int width = metrics.widthPixels;
int height = metrics.heightPixels;
Look this: Get screen dimensions in pixels
You are trying to get the size of the views before they are actually measured and layed out on the screen (before onCreateView returns). Just because you inflate the view does not mean the system has any idea about the sizes. Try calculating the sizes after onCreateView returns like in onActivityCreated.
See the first answer to getWidth() and getHeight() always returning 0. Basically, you have to wait until after the first measure and layout pass, which doesn't happen until after onCreateView() and onViewCreated() have been called.
you can get height and width using
getViewTreeObserver().addOnPreDrawListener(new OnPreDarwListener() {
.... run () {
getHeight() + getWidth related stuff.
getViewTreeObserver.removeOnPreDrawListener(this);
}
});
To find height and width of screen, you can try this:
DisplayMetrics metrics = new DisplayMetrics(); //for all android versions
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int Measuredwidth = metrics.widthPixels;
int Measuredheight = metrics.heightPixels;
How to find the Width of the a view before the view is displayed? I do not want to add a custom view and tap the dimensions in the OnChanged().
Display display = getWindowManager().getDefaultDisplay();
View view = findViewById(R.id.YOUR_VIEW_ID);
view.measure(display.getWidth(), display.getHeight());
view.getMeasuredWidth(); // view width
view.getMeasuredHeight(); //view height
#dmytrodanylyk -- I think it will return width & height as 0 so you need to use following thing
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View contentview = inflater.inflate(R.layout.YOURLAYOUTNAME, null, false);
contentview.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
int width = contentview.getMeasuredWidth();
int height = contentview.getMeasuredHeight();
It will give you right height & width.
You should use OnGlobalLayoutListener which is called for changes on the view, but before it is drawn.
costumView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
costumView.getWidth();
}
});
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
view.measure(size.x, size.y);
int width = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
I like to use this technique as per my answer on a related question:
Post a runnable from onCreate() that will be executed when the view has been created:
contentView = findViewById(android.R.id.content);
contentView.post(new Runnable()
{
public void run()
{
contentHeight = contentView.getHeight();
}
});
This code will run on the main UI thread, after onCreate() has finished.
This is the best way...... WORK!!!
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (fondo_iconos_height==0) { // to ensure that this does not happen more than once
fondo_iconos.getLocationOnScreen(loc);
fondo_iconos_height = fondo_iconos.getHeight();
redraw_function();
}
}
I am trying to apply an animation to a view in my Android app after my activity is created. To do this, I need to determine the current size of the view, and then set up an animation to scale from the current size to the new size. This part must be done at runtime, since the view scales to different sizes depending on input from the user. My layout is defined in XML.
This seems like an easy task, and there are lots of SO questions regarding this though none which solved my problem, obviously. So perhaps I am missing something obvious. I get a handle to my view by:
ImageView myView = (ImageView) getWindow().findViewById(R.id.MyViewID);
This works fine, but when calling getWidth(), getHeight(), getMeasuredWidth(), getLayoutParams().width, etc., they all return 0. I have also tried manually calling measure() on the view followed by a call to getMeasuredWidth(), but that has no effect.
I have tried calling these methods and inspecting the object in the debugger in my activity's onCreate() and in onPostCreate(). How can I figure out the exact dimensions of this view at runtime?
Use the ViewTreeObserver on the View to wait for the first layout. Only after the first layout will getWidth()/getHeight()/getMeasuredWidth()/getMeasuredHeight() work.
ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
viewWidth = view.getWidth();
viewHeight = view.getHeight();
}
});
}
There are actually multiple solutions, depending on the scenario:
The safe method, will work just before drawing the view, after the layout phase has finished:
public static void runJustBeforeBeingDrawn(final View view, final Runnable runnable) {
final OnPreDrawListener preDrawListener = new OnPreDrawListener() {
#Override
public boolean onPreDraw() {
view.getViewTreeObserver().removeOnPreDrawListener(this);
runnable.run();
return true;
}
};
view.getViewTreeObserver().addOnPreDrawListener(preDrawListener);
}
Sample usage:
ViewUtil.runJustBeforeBeingDrawn(yourView, new Runnable() {
#Override
public void run() {
//Here you can safely get the view size (use "getWidth" and "getHeight"), and do whatever you wish with it
}
});
On some cases, it's enough to measure the size of the view manually:
view.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
int width=view.getMeasuredWidth();
int height=view.getMeasuredHeight();
If you know the size of the container:
val widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(maxWidth, View.MeasureSpec.AT_MOST)
val heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(maxHeight, View.MeasureSpec.AT_MOST)
view.measure(widthMeasureSpec, heightMeasureSpec)
val width=view.measuredWidth
val height=view.measuredHeight
if you have a custom view that you've extended, you can get its size on the "onMeasure" method, but I think it works well only on some cases :
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
final int newHeight= MeasureSpec.getSize(heightMeasureSpec);
final int newWidth= MeasureSpec.getSize(widthMeasureSpec);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
If you write in Kotlin, you can use the next function, which behind the scenes works exactly like runJustBeforeBeingDrawn that I've written:
view.doOnPreDraw { actionToBeTriggered() }
Note that you need to add this to gradle (found via here) :
android {
kotlinOptions {
jvmTarget = "1.8"
}
}
implementation 'androidx.core:core-ktx:#.#'
Are you calling getWidth() before the view is actually laid out on the screen?
A common mistake made by new Android developers is to use the width
and height of a view inside its constructor. When a view’s
constructor is called, Android doesn’t know yet how big the view will
be, so the sizes are set to zero. The real sizes are calculated during
the layout stage, which occurs after construction but before anything
is drawn. You can use the onSizeChanged() method to be notified of
the values when they are known, or you can use the getWidth() and
getHeight() methods later, such as in the onDraw() method.
Based on #mbaird's advice, I found a workable solution by subclassing the ImageView class and overriding onLayout(). I then created an observer interface which my activity implemented and passed a reference to itself to the class, which allowed it to tell the activity when it was actually finished sizing.
I'm not 100% convinced that this is the best solution (hence my not marking this answer as correct just yet), but it does work and according to the documentation is the first time when one can find the actual size of a view.
Here is the code for getting the layout via overriding a view if API < 11 (API 11 includes the View.OnLayoutChangedListener feature):
public class CustomListView extends ListView
{
private OnLayoutChangedListener layoutChangedListener;
public CustomListView(Context context)
{
super(context);
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
if (layoutChangedListener != null)
{
layoutChangedListener.onLayout(changed, l, t, r, b);
}
super.onLayout(changed, l, t, r, b);
}
public void setLayoutChangedListener(
OnLayoutChangedListener layoutChangedListener)
{
this.layoutChangedListener = layoutChangedListener;
}
}
public interface OnLayoutChangedListener
{
void onLayout(boolean changed, int l, int t, int r, int b);
}
You can check this question. You can use the View's post() method.
Use below code, it is give the size of view.
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
Log.e("WIDTH",""+view.getWidth());
Log.e("HEIGHT",""+view.getHeight());
}
This works for me in my onClickListener:
yourView.postDelayed(new Runnable() {
#Override
public void run() {
yourView.invalidate();
System.out.println("Height yourView: " + yourView.getHeight());
System.out.println("Width yourView: " + yourView.getWidth());
}
}, 1);
I was also lost around getMeasuredWidth() and getMeasuredHeight() getHeight() and getWidth() for a long time.......... later i found that getting the view's width and height in onSizeChanged() is the best way to do this........ you can dynamically get your CURRENT width and CURRENT height of your view by overriding the onSizeChanged() method.
might wanna take a look at this which has an elaborate code snippet.
New Blog Post: how to get width and height dimensions of a customView (extends View) in Android http://syedrakibalhasan.blogspot.com/2011/02/how-to-get-width-and-height-dimensions.html
In Kotlin file, change accordingly
Handler().postDelayed({
Your Code
}, 1)
You can get both Position and Dimension of the view on screen
val viewTreeObserver: ViewTreeObserver = videoView.viewTreeObserver;
if (viewTreeObserver.isAlive) {
viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
//Remove Listener
videoView.viewTreeObserver.removeOnGlobalLayoutListener(this);
//View Dimentions
viewWidth = videoView.width;
viewHeight = videoView.height;
//View Location
val point = IntArray(2)
videoView.post {
videoView.getLocationOnScreen(point) // or getLocationInWindow(point)
viewPositionX = point[0]
viewPositionY = point[1]
}
}
});
}
If you need to know the dimensions of a View right after it is drawn you can simply call post() on that given View and send there a Runnable that executes whatever you need.
It is a better solution than ViewTreeObserver and globalLayout since it gets called repeatedly not just once.
This Runnsble will execute only once and you will know the views size.
works perfekt for me:
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
CTEditor ctEdit = Element as CTEditor;
if (ctEdit == null) return;
if (e.PropertyName == "Text")
{
double xHeight = Element.Height;
double aHaight = Control.Height;
double height;
Control.Measure(LayoutParams.MatchParent,LayoutParams.WrapContent);
height = Control.MeasuredHeight;
height = xHeight / aHaight * height;
if (Element.HeightRequest != height)
Element.HeightRequest = height;
}
}