Setting layout dimensions and clipping all insides controls - android

Is it possible to forcefully set dimensions of a layout and clip its content?
For example, see following layout:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content>
<Button
android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test" />
</FrameLayout>
In this layout, FrameLayout size will be equal to Button. Now assume that I want to set this layout's dimension to 50dp width and height, clipping all controls (here button) in that size, so that total size of layout will be 50dpx50dp. Is it possible to do so?
I thought setting width, height, and android:clipChildern="true" for layout should do the trick, but it seems that it does not work. or maybe I'm using it incorrectly.

Related

Let Linearlayout width be 650dp if parent is over 650dp, otherwise match parent

I'm creating a LinearLayout inside a FrameLayout, the LinearLayout needs to be centered inside FrameLayout, but the width of LinearLayout needs to change as follows:
If parent FrameLayout is over 650dp, then set LinearLayout width to 650dp, this leaves some margin at left and right of linear layout.
If parent FrameLayout is under 650dp, then set Lineralyout width to match parent.
Parent FrameLayout width will change on orientation change, I tried to use OnLayoutChangeListener, OnGlobalLayoutListener, OnAttachStateChangeListenerto detect the width after screen rotates, but none of them works.
Am I on the right track by trying to find the width of parent view?
Or is it possible to use parent view as ConstraintLayout and make the LinearLayout inside comply 650 when possible and expand to parent when width is not enough?
(Note I can't use different values under different layout res folders like sw600 or sw600-land, as the parentview is not necessarily occupying the entire screen, it might just be one of the two columns on the screen)
The appropriate way to handle this is to create another layout file under layout-land and use a 650dp width for that. And for more description on supporting different screens see the official training here.
For any one interested, I solved it with a ConstraintLayout per Eugen's comment. This will make sure the LinearLayout's width matches parent on smaller screens(<650dp) and cap the width to 650dp on bigger screen sizes
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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="wrap_content">
<LinearLayout
android:id="#+id/row_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintWidth_max="650dp"/>
</android.support.constraint.ConstraintLayout>
<LinearLayout
android:layout_width="300dp"
android:layout_height="100dp"
android:background="#f00"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:maxWidth="200dp"
android:minWidth="200dp"
android:background="#00f"
>
</LinearLayout>
</LinearLayout>
Result when parent width = 150dp

XML Layout weight not working in a ScrollView on android API23

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;

Why wrap_content has no effect?

Set wrap_content in RecycleView holder:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:background="#android:color/black">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/textView3"
android:textColor="#android:color/white"
android:textSize="17dp"
android:background="#drawable/bubbleblue170x140_2" />
</RelativeLayout>
But text in TextView is not wrapped, there is a lot of empty space in the bubble, inside TextView.
How can I force to see something like this in iOS version:
In Android using 9-patch image as background.
The height of your text view is wrap and the big size is becuase of your 9patch image (probably having a big size)
And the width of that is match parent as you wanted in xml layput.
Just change the size of your 9 patch and make the width wrap content too
Resize your 9patch. You should also change the RelativeLayout's height and width to wrap_content. Or, even better, you should remove the RelativeLayout (it seems useless).

ImageView with LayoutParams match_parent doesn't match parent when parent size changes at runtime

I have an imageview that I want to fill it's parent RelativeLayout to act as a background image.
The image is the correct size until the other views in the relative layout expand, and thus expand the size of the entire layout (just height in my case) (ie: a large string from the internet has been loaded into a textView). Then the image view doesn't grow to continue matching the parent. Is that expected behavior and if so, how do we get around it?
Here's my layout code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/parentLayout">
<my.BlurredImageView
android:scaleType="centerCrop"
android:id="#+id/profile_bg"
ImageUrl= "Avatar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
/>
<LOTS AND LOTS OF OTHER VIEWS>
OK I am sure you know this already, but for thoroughness I thought I should mention that the easiest way to set the background of the relative layout is directly in the background field:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="drawable file or file from internet you load programatically"
android:id="#+id/parentLayout">
Now to your question. If for whatever reason you really need an imageView as a background, then use the width and height as 0dp because you are aligning to parent on all 4 sides. See if this makes a difference:
<my.BlurredImageView
android:scaleType="centerCrop"
android:id="#+id/profile_bg"
ImageUrl= "Avatar"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
/>
To check the actual size of the image view, and whether it fills your relative layout, the most practical way would be to make the background of the RelativeLayout bright green, and the background of the imageView bright Orange. Then you always know exactly where they are :-)

Android layout Height and width

I use match_parent for height,but I don't want to use wrap_content or fill_parent for width. I want to set height as same as width. How can I do that in layout.xml?
Your question largely depends on whether you are in portrait or landscape.
If you are trying to make a layout width to match the height in portrait, then your layout will be going off screen, which does not seem possible in xml. And vice-versa, matching the height to the width in landscape would make the layout go offscreen as well.
If you are trying to make a square layout the same dimension as the smallest dimension of the screen, then a round about way to do that in xml is to make a shape drawable that is square, transparent and larger than your screen size. Then set the drawable to be an imageview inside a relativelayout and set your width and heights to the proper settings (match_parent or wrap_content). Then add views to the relativelayout as needed and reference them to the parent and not the image, making the new views reside "on top" of the imageview.
In portrait, the following relativelayout is square:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:adjustViewBounds="true"
android:src="#drawable/square_draw" />
</RelativeLayout>
</LinearLayout>
In landscape, the following relativelayout is square:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:adjustViewBounds="true"
android:src="#drawable/square_draw" />
</RelativeLayout>
</LinearLayout>
Also, make sure that adjustViewBounds is set to true. For some reason, this solution does not allow the image to grow larger than the screen size and it also uses more resources due to the overdraw.

Categories

Resources