I've seen other answers to this question but none worked for me; for example the top answer here (How to get the height of recyclerview item in "onBindViewHolder") says to do this:
view.measure(
View.MeasureSpec.makeMeasureSpec(recyclerViewWidth, View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
but then doing view.getMeasuredHeight() only returns whatever I pass in for recyclerViewWidth.
Basically I want to set the size of components within the recycler view cell as fractions of the cell's size, but those fractions depend on the position of the cell. I'm a bit frustrated since this is so simple to do in iOS and seems so much more convoluted in android.
I am not a fan of setting percentages by code on Android. And if you do want to set your view's sizes relative to its parent, ContraintLayout are your best friend for setting items based on percentage guidelines, barriers, and ratios are something you should look into, it is efficient and you do not have to worry about calculation yourself.
https://developer.android.com/reference/androidx/constraintlayout/widget/ConstraintLayout
Related
Is there any good way of getting the height of the content inside RecyclerView? Considering all items may have different height.
In my scenario I'm using a LinearLayoutManager.
I've searched around and found surprisingly few results for this problem.
RecyclerView.computeVerticalScrollRange will give an estimation - it averages the height of the rows being currently displayed and multiplies that by the result of getItemCount
computeHorizontalScrollRange for width if you're orientation is horizontal.
RecyclerView is a ViewGroup. You can use getChildAt / getChildCount to get views. Then from the view, you can call getWidth / getHeight.
If you have ItemDecorators and need to get size including them, you can use LayoutManager's getDecorated<xxx> methods.
I use to experiment with View.measure method:
recycler.measure(View.MeasureSpec.makeMeasureSpec(recycler.width, View.MeasureSpec.EXACTLY), View.MeasureSpec.UNSPECIFIED)
val height = recycler.measuredHeight
If your items are simple enough (e.g. with fixed heights), it should work.
I want to arrange a set of custom widgets inside a GridView. There are predefined templates which describe a count of elements and arrangement config. Max width and heigh for each of them have to be provided in order to avoid scrolling. How can I get a size of the displayed GridView when computing items size in adapter's "GetView" method?
You have access to few functions in order to get a GridView Height and Width as any other View. Look at the documentation here.
The size of a view is expressed with a width and a height. A view
actually possess two pairs of width and height values.
The first pair is known as measured width and measured height. These
dimensions define how big a view wants to be within its parent (see
Layout for more details.) The measured dimensions can be obtained by
calling getMeasuredWidth() and getMeasuredHeight().
The second pair is simply known as width and height, or sometimes
drawing width and drawing height. These dimensions define the actual
size of the view on screen, at drawing time and after layout. These
values may, but do not have to, be different from the measured width
and height. The width and height can be obtained by calling getWidth()
and getHeight().
Try doing a quick search on their doc next time, even if it's Xamarin, the Android doc is pretty reliable and you only need some adjustment to make it work.
(e.g.) : grivView.Width; instead of gridView.getWidth(); one being a property on Xamarin to follow C# standards, the other is a function.
I'm having a hard time finding example usage, or explanations, of the Android View concept of "measured state".
To be clear, this is different from measured width and measured height. See in Android docs.
The general idea is that a View has a desired width and height, which is constrained by two factors.
The first constraint is the parent View to which the View is attached. This will describe the maximum width and size of the View. If the View has asked to be wider or taller than the parent view, then it's measured height and measured width will be constrained such that the values are no greater than the parent's. These values, which can be MATCH_PARENT, WRAP_CONTENT or a dp value, get converted to measured widths and heights once the parent View's width and height constraints are included. This guarantees that no child is larger than it's parent.
The second constraint comes from the View's siblings, or in other words, from other Views attached to the same layout. The ViewGroup (Layout) will resolve a View's width and height such that it displays correctly. These resolved width's and height's are the values you get from getWidth() and getHeight().
There is a lot of good documentation on the Android development portal. In particular look at the Layout section of the View class: http://developer.android.com/reference/android/view/View.html#Layout
Edit: Sorry for misunderstanding your question. I've taken a look at the concept of measured state for a view, and I can only find a single documented state: MEASURED_STATE_TOO_SMALL. This leads me to believe that it's use may be very limited and it's existence is primarily for the purpose of future functionality or to be made use of by custom Views/ViewGroups.
The documentation for MEASURED_STATE_TOO_SMALL states the following:
Bit of getMeasuredWidthAndState() and getMeasuredWidthAndState() that
indicates the measured size is smaller that the space the view would
like to have.
This leads me to believe that the bit will be set whenever a fixed dp/px value is given to the View which is larger than the parent's width and height and therefore the View's measured width and height will have been scaled down.
If you manage to find more states or additional information as to where it is used, please to update the question. All the best!
I've seen a ton of different questions and answers to the problems people are having with retrieving height and width of views, particularly this thread.
The following are mentioned methods to retrieve View dimensions:
onWindowFocusChanged() in your activity
Subclassing the type of view you're using and overridding either onSizeChanged(), onLayout(), or onMeasure()
Using a ViewTreeObserver and addOnGlobalLayoutListener()
Each of them seem to work in some cases, while in other cases people say something doesn't work correctly. Since there isn't a setOnDimensionsKnown(OnDimensionsKnown odk) or similar method for the View class, which of these methods (or possibly one not mentioned) will give me the dimensions my view will eventually have, regardless if it's drawn yet, has wrap_content or fill_parent parameters, or it has explicit height and width set in px, dp, or similar?
EDIT: Perhaps a specific example would be helpful, I'm trying to make a PopupWindow wrap it's contents, and to be offset in the -x direction by the value of it's width. The problem is that the contents width, and thus the popupwindows width, are not measured until after I show the popup. So basically I can't think of a good way to measure the width it will be before it is drawn to screen.
My usual approach is to override whatever view class I need the dimensions of before it being drawn, and create my own setOnDimensionsKnown(OnDimensionsKnown odk) method and fire it with the width and height values that onMeasure is called with. This works it every case I've needed, but it doesn't seem very elegant to override every view class to do this.
I can post code to help explain the example more.
Good way of doing it is adding an OnGlobalLayoutListener() to the view, as stated in this answer (point 3 in your question, in my opinion that's the most reliable for any View). The way I do it for a PopupWindow is to inflate it's layout and then call measure on it:
popupView = getActivity().getLayoutInflater().inflate(R.layout.popup_layout, null);
popup = new PopupWindow(popupView, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, true);
popupView.measure(view.getMeasuredWidth(), view.getMeasuredHeight()); //the view is parent's layout (not sure if those are correct values, but it measures okay in my case)
and then just get the numbers by calling popupView.getMeasuredHeight() and .getMeasuredWitdh().
Your problem is probably long gone by now, but hopefully someone else will stumble upon this and find it helpful. :)
I'm moving a view after an animation completes(to slide out a menu from the left). However, I don't seem to be able to achieve the effect I'm looking for. What I'd like is for the view to extend to the right past the parent's bounds, like this:
but what's happening is actually this:
The view resets itself to stay within the bounds of the parent. Even if I set an absolute pixel value (by looking at the display's width, or even a randomly large value).
The reason I need to do this is detailed in this SO question about a view's actual position after an animation has completed:
TranslateAnimated ImageView not clickable after animation [Android]
any thoughts? Thanks!
So, here is a related question. It explains how to move a view out of the screen.
I had same problem and I found the solution. I hope it can be helpful.
You need to set fixed width if you want to achieve this effect. To find real width of the view you need to measure it.
So full solution is:
view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
int height = view.getMeasuredHeight();
int width = view.getMeasuredWidth();
view.setLayoutParams(new LinearLayout.LayoutParams(width, height));
(Use LayoutParams of the type corresponding the type of the parent layout)