I have a recycler view which is not displaying a specific layout. I know that the layout is the problem, because I've tried with different layouts and they are being displayed. I don't get any errors in the console for the bad layout.
That layout is structured as follows:
<android.support.percent.PercentRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:background="#000"
android:layout_height="match_parent">
<android.support.percent.PercentRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/border_color"
app:layout_heightPercent="30%">
</android.support.percent.PercentRelativeLayout>
</android.support.percent.PercentRelativeLayout>
I see it rendered properly, but probably is something wrong with it. I want that each of my recycler's items to have 30% height, that's why I'm using app:layout_heightPercent="30%". If I remove the outer layout the inner layout will take all the space. How can I achieve this 30% height, because clearly this is not working.
Try this:-
I have set height as 100dp for parent PercentRelativeLayout. It is working for me.
<android.support.percent.PercentRelativeLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:background="#000"
android:layout_height="100dp">
<android.support.percent.PercentRelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#888888"
app:layout_heightPercent="30%">
</android.support.percent.PercentRelativeLayout>
</android.support.percent.PercentRelativeLayout>
For anyone having the same problem, give an id to the outer layout, or whatever layout your recycler items might have outer,
define it in your holder:
outer = (PercentRelativeLayout) view.findViewById(R.id.outer);
and inside your onBindViewHolder set your height programatically:
Display display = ((Activity)ctx).getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
//int width = size.x;
int height = size.y;
((MyRecyclerHolder) holder).outer.getLayoutParams().height = height/3;(or whatever ratio you want)
Related
I am doing an Android project in AndroidStudio where a ScrollView contains a vertical LinearLayout and within that LinearLayout there is an ImageView and another LinearLayout. I am trying to set the ImageView to be 10 times smaller than the LinearLayout, the result is showing up correct in the Preview window but not on my phone (Xperia Z3 with API23).
This is what I see in the preview window and what I want to achieve
But on my phone the image fills the width of the screen and the image height is proportional to the original image(almost fills half the screen, so far from what it should be according to the weights)
The app worked like it is supposed to on a Google Pixel 7.1.1 with API25.
Here is a part of the code:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:fillViewport="true"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_weight="1"
android:adjustViewBounds="true"
android:layout_height="0dp"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:id="#+id/image"
android:scaleType="fitCenter"
android:src="#drawable/bjj2" />
<LinearLayout
android:layout_weight="10"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="0dp">
<LinearLayout
...rest of the app
</LinearLayout>
</LinearLayout>
</ScrollView>
Here is the full code https://github.com/IvarsGoldingen/Bjjscorekeeper/blob/master/app/src/main/res/layout/activity_main.xml
Can someone please tell me what I'm doing wrong.
One should understand how dimensions are calculated.
Let's look one by one.
1) ScrollView is fill_parent/fill_parent (actually one can change this to match_parent/match_parent as fill_parent is deprecated as far as I remember, but it doesn't matter in this case).
So, ScrollView is shown fits whole screen (width and height).
2) LinearLayout inside ScrollView is match_parent/wrap_content. And that is correct. One should use wrap_content for views that inside ScrollView.
The reason why - is that ScrollView is used to wrap long views with usually unknown height (like lists). Imagine here match_parent as height - height of LinearLayout would be calculated based on height of scroll view, which is whole screen height, and LinearLayout height can be greater that screen height. Just not logical. But everything is OK till now. Move on.
3) Items inside LinearLayout. You want them to be 1/10 and 9/10 of height of parent layout. Also, you set height for inner items to 0 to show that you want height to be calculated from weights.
And here you got a cycle of dependencies. LinearLayout height is wrap_content and depends on sum of heights of inner elements.
And inner elements' height is calculated from parent LinearLayout height.
Additionally, you want ImageView to be 1/10 of the LinearLayout height. But actually seems like you want ImageView to be 1/10 of the screen's height, as LinearLayout height can be greater than screen's height (and looks like this is what you get on your device).
You say, that everything is OK in preview in Android Studio.
To demonstrate that not everything is OK try this:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:fillViewport="true"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_weight="1"
android:adjustViewBounds="true"
android:layout_height="0dp"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:id="#+id/image"
android:scaleType="fitCenter"
android:src="#drawable/bjj2" />
<LinearLayout
android:layout_weight="10"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="0dp">
<View
android:layout_width="match_parent"
android:layout_height="1000dp"/>
</LinearLayout>
</LinearLayout>
</ScrollView>
Just put some big (bigger than screen's height) view inside your inner-inner LinearLayout and you will see that in preview your image is bigger than 1/10 of screen's height. But it is 1/10 of LinearLayout's height.
How to solve your issue?
I think the only way is to calculate 1/10 of the screen's height and resize bitmap with image you want to have and set that bitmap to ImageView.
Or any other way to set exact height to ImageView.
Or review your layout and create something different.
we can set height of the image view at run time by avoiding layout_weight using display metrics .
e.g
DisplayMetrics displayMetrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int height = displayMetrics.heightPixels;
int width = displayMetrics.widthPixels;
yourImageView.getLayoutParams().height = height / 5;
yourImageView.getLayoutParams().width = width / 4;
I use ScrollView with multiple Views but I have an ImageView on the top. What I need is auto fitting image height as screen height as.
My current layout starts like this :
<LinearLayout
android:orientation="vertical"
android:id="#+id/layout_dashboard"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:layout_width="match_parent"
android:layout_height="wrap_content"
layout="#layout/toolbar_dashboard_layout" />
<ScrollView
android:scrollbars="none"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
Thanks.
To make sure ImageView adjusts its height, use attribute adjustViewBounds for example:
<ImageView android:id="..."
android:adjustViewBounds="true" ... />
Your screen dimensions cannot be known in a resource file, as the Android system takes these files and then renders them to the given device screen.
So, to make any View proportional to the screen size, we need to set its parameters programmatically. Luckily, Android gives us Display, which holds data about our display. Use this object to retrieve the height of the display, then set the height of our View to that:
ImageView imageView = (ImageView) findViewById(R.id.image_view);
Display display = getWindowManager().getDefaultDisplay();
//We need to store the dimensions in a Point object.
Point point = new Point();
display.getSize(point);
//Now, set the width and height.
profileImage.getLayoutParams().width = point.x;
profileImage.getLayoutParams().height = point.y;
I'm trying to use PercenRelativeLayout into ListView, but it doesnot works,
height and width percents are ignored and nothing were showing into the listview.
it works only for marshmallows.
here is list item xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.percent.PercentRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:background="#d20404"
android:id="#+id/test_image_id"
android:layout_width="match_parent"
android:layout_height="300dp" />
<TextView
android:background="#000"
android:text="sfgfashdsfg"
android:layout_below="#+id/test_image_id"
app:layout_heightPercent="50%"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.percent.PercentRelativeLayout>
I have a sample project on github
I have opened this issue to google. The answer were
The height of your ListView row item is insufficiently specified.
The first child says it wants to take 60% of the row height (note that
this is heightPercent and not aspectRatio), and the second child says
it wants to take 10% of the row height. But nothing tells ListView how
tall the entire row wants to be. So it ends up being with height 0.
Note that the semantics of height=match_parent do not work in ListView
rows, and if this works in any one particular Android platform version
(for however much you can say it works), it is purely incidental.
https://code.google.com/p/android/issues/detail?id=202479
I encountered the same problem with android K and android L.
The percent layout won't work correctly before android M. The reason is that they depend on the size hint being delivered in the measuring step. Before android M most layouts would provide size hint 0.
Convert your percent relative layout to relative layout and set the height of the views programmatically according to your device height.
This is not a very elegant solution but it worked for me.
XML Code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/test_image_id"
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="#d20404" />
<TextView
android:id="#+id/textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/test_image_id"
android:background="#000"
android:text="sfgfashdsfg" />
</RelativeLayout>
Java Code:
// to get the height of the screen
int height = getWindowManager().getDefaultDisplay().getHeight();
// to set height to each textview to 50% of screen
textView1.getLayoutParams().height = (int) (height * 0.50);
I would start with my goal. What I want to achieve is to have layout which is 3 times bigger then real screen of phone.
Right now I try to test my solution, but I have problem with scrolling.
This is how look my layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="400dp"
tools:context=".Zo"
android:id="#+id/zo_root"
>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="9">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3"
android:background="#color/Red"
></FrameLayout >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3"
android:background="#color/Yellow"
></FrameLayout >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3"
android:background="#color/Blue"
></FrameLayout >
</LinearLayout>
</ScrollView>
My code behind:
#Override
protected void onCreate (Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_zo);
setParameterForScroolView();
}
private void setParameterForScroolView()
{
ParameterKeeper parameterKeeper = new ParameterKeeper(this);
LinearLayout linearLayout = (LinearLayout)findViewById(R.id.zo_root);
linearLayout.getLayoutParams().height = parameterKeeper.getHeightOfScreen() *3;
}
The code behind works well, cause my whole screen is red, but I can't scroll it at all.
There was answer which said, that I need to remove from scrollView android:fillViewport="true". After that my LinearLayout diseapers like in this question.
I added LinearLayout as root (source) but it not helped me at all.
Have you got any idea to solve it?
I try also set height 1600dp instead 400dp for Root LinearLayout in xml to be sure, that it's not problem with recalculating view. It's not working too.
You are changing the size of the wrong layout. you suppose to modify the height of the first layout inside the scroll view.
Some way scroll doesn't work if the child elements have layout_weight and I change programmatically value of height in parent's view.
In my case the only way to make it works was to set height equal to size of screen in every of frame layout in code of activity. This way I could reach my goal which was to have layout height == 3 x real screen size
I want to have 2 layouts inside ScrollView. First layout should be on the full screen and second layout below first one. When activity starts it is not possible see second layout. Second layout is possible see after scroll screen. Please take a look on my image for better understand.
Layout code: `
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="15dp" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/layout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
<LinearLayout
android:id="#+id/layout2"
android:layout_width="match_parent"
android:layout_height="200dp"
android:orientation="vertical" >
<!-- this layout can be any height you want -->
</LinearLayout>
</LinearLayout>
</ScrollView>`
Get the device screen height:
Point size = new Point();
getWindowManager().getDefaultDisplay().getSize(size);
int screenHeight = size.y;
Find the LinearLayout:
LinearLayout layout = (LinearLayout)findViewById(R.id.layout1);
Set the height of the layout based on the screen height you got earlier:
LayoutParams params = layout.getLayoutParams();
params.height = screenHeight - getStatusBarHeight();
Done. Be sure to call all of those methods in your onCreate method.
Hope this helps!