this is my layout code
i use like root a grid layout and then for every row a frame layout inside that frame layout two frame layouts with image and txt...
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:columnCount="1"
android:rowCount="2">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
android:layout_width="200dp"
android:layout_height="220dp"
android:layout_marginLeft="2dp"
android:layout_marginTop="2dp"
android:layout_marginBottom="0.1dp"
android:layout_marginRight="2dp"
android:layout_row="1"
android:layout_column="1">
<ImageView
android:layout_width="150dp"
android:layout_height="190dp"
android:id="#+id/am"
android:layout_gravity="top|center_horizontal"
android:src="#drawable/black" />
<TextView
android:layout_width="153dp"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="text"
android:id="#+id/w"
android:layout_gravity="bottom|center"
android:layout_marginBottom="10dp" />
</FrameLayout>
<FrameLayout
android:layout_width="200dp"
android:layout_height="220dp"
android:layout_marginRight="2dp"
android:layout_marginLeft="2dp"
android:layout_marginTop="0dp"
android:layout_row="1"
android:layout_column="0"
android:layout_gravity="right|center_vertical">
<ImageView
android:layout_width="150dp"
android:layout_height="190dp"
android:id="#+id/imageView"
android:layout_gravity="top|center"
android:src="#drawable/black" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="text"
android:id="#+id/textView2"
android:layout_gravity="bottom|center"
android:layout_marginBottom="10dp" />
</FrameLayout>
</FrameLayout>
this is how its seen
looks cool rigth?
well this is my problem when i take this to a bigger screen this happends
well i dont whant this i whant that the text and images grow to take half of screen like first one...
HOW I DO THIS!!!
You are using fix layout_width and layout_height sizes at the FrameLayout and ImageView too. This way you wont reach the desired goal. You should use wrap_content value instead of fix sizes and play with the layout_weight. For example in a LinearLayout put two FrameLayout which contains the image and the text, after that add layout_weight="1" to the FrameLayout attributes.
Don't use a frame layout.
Layout_weight is what you should use if you want to set your dimensions in relation to your view size(but don't nest weights as it quickly becomes very inefficient), or set the dimensions in your code based on the size of your view.
you hardcoded all of your view dimensions so they are always going to interact poorly with changes in screen size
Related
I am trying to code one of my first android apps. I am trying to position a text below an image, but the image takes up most of the screen and one of the textviews which are supposed to be below it are not displayed. I am using a RelativeLayout.
Here is my code snippet.
<RelativeLayout
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.jsk.myapp.MainActivity">
<TextView
android:id="#+id/t1"
android:layout_width="wrap_content"
android:text="My App"
android:layout_centerHorizontal="true"
android:textSize="30sp"
android:layout_alignParentTop="true"
android:layout_height="wrap_content" />
<ImageView
android:scaleType="centerCrop"
android:id="#+id/img"
android:layout_below="#id/t1"
android:layout_width="match_parent"
android:layout_height="200dp"
android:src="#drawable/i1"
/>
<TextView
android:id="#+id/t2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/img"
android:textSize="24sp"
android:text="Description"/>
</RelativeLayout>
I have also tried changing the scale type of the imageview, but it doesn't work. Only when I explicitly specify the width and height parameters of the image, the text is visible below the image.
What changes can I make in this code to get the desired output ?
If you add a rough diagram of what you want to achieve your question can be answered better. From my understanding, and by looking at your code it seems you are trying to add 2 TextView's at the top and bottom (one each) and then an ImageViewsandwiched in between.
First, add the 2 TextView's. Set the one as android:layout_alignParentTop = true and android:layout_alignParentBottom = true. Then add the ImageView. In the ImageView, you can set android:layout_height = "wrap_content" and then android:layout_below=<id of the top text view> as well as android:layout_above = <id of the bottom text view>.
So something like this:
<RelativeLayout
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.jsk.myapp.MainActivity">
<TextView
android:id="#+id/t1"
android:layout_width="wrap_content"
android:text="My App"
android:layout_centerHorizontal="true"
android:textSize="30sp"
android:layout_alignParentTop="true"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/t2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:textSize="24sp"
android:text="Description"/>`
<ImageView
android:scaleType="centerCrop"
android:id="#+id/img"
android:layout_below="#id/t1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="#drawable/i1"
android:layout_above="#id/t2"
/>
</RelativeLayout>
If you're using wrap_content for your ImageView's height and if your ImageView's actual image is large enough then it will surely take up entire space.
In that case, you'll have to explicitly mention exact height of the View, so that text below is show up.
What you want to do to fix this situation is to change actual height of the image itself. If you do that, image will fit itself entirely but takes less height and then text should show up.
So you have two options,
1) Either fix your image height in your layout, OR
2) Fix actual image height so that it's more appropriate in your usecase
I hope this answers your question.
You need to assign a size for ImageView based on screen size
Use PercentRelativeLayout
My compileSdkVersion is 24 so I use compile 'com.android.support:percent:24.0.0' inside my app:gradle dependencies
example :
<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">
<TextView
android:id="#+id/t1"
android:layout_width="wrap_content"
android:text="My App"
android:layout_centerHorizontal="true"
android:textSize="30sp"
android:layout_alignParentTop="true"
android:layout_height="wrap_content" />
<ImageView
android:scaleType="centerCrop"
android:id="#+id/img"
android:layout_below="#id/t1"
android:layout_width="match_parent"
app:layout_heightPercent="50%" <---------- here its taking 50% of screen height
android:src="#drawable/myImageName"
/>
<TextView
android:id="#+id/t2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/img"
android:textSize="24sp"
android:text="Description"/>
</android.support.percent.PercentRelativeLayout>
If you use LinearLayout go for layout_weight attribute
make t2 alignParentBottom true
and
let img view layout_above t2
<RelativeLayout
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.jsk.myapp.MainActivity">
<TextView
android:id="#+id/t1"
android:layout_width="wrap_content"
android:text="My App"
android:layout_centerHorizontal="true"
android:textSize="30sp"
android:layout_alignParentTop="true"
android:layout_height="wrap_content" />
<ImageView
android:scaleType="centerCrop"
android:id="#+id/img"
android:layout_below="#id/t1"
android:layout_above="#+id/t2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/i1"
/>
<TextView
android:id="#id/t2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:textSize="24sp"
android:text="Description"/>
</RelativeLayout>
I would like to have image behind TextView in FrameLayout. I need FrameLayout to adjust it's height to TextView inside and not to be affected by image size. Image should be behind the text in it's original size, cropped by FrameLayout. This is what I tried:
<FrameLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:layout_gravity="right|center_vertical"
android:gravity="center"
android:alpha="0.1"
android:id="#+id/img_logo" />
<TextView
android:textAppearance="?android:attr/textAppearanceMedium"
android:textAllCaps="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:gravity="left|center_vertical"
android:id="#+id/text_long" />
</FrameLayout>
It's almost what I want except the FrameLayout's height is affected by image size. It should change only with text.
Actually I think you can do this without overriding any layouts or writing any java code. Instead you can wrap the whole thing in a RelativeLayout move the TextView after the FrameLayout and set the FrameLayout's top and bottom to align with the textView. I admit it is a bit messy; to address that I would recommend either making it a custom view or putting it in another xml file that you include.
Edit: Actually, you don't need the FrameLayout any more, instead you can set the android:layout_alignTop and android:layout_alignBottom attributes on the ImageView instead. Here is what it look like:
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
<ImageView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_alignTop="#+id/text_long"
android:layout_alignBottom="#id/text_long"
android:scaleType="centerCrop"
android:layout_gravity="right|center_vertical"
android:gravity="center"
android:alpha="0.1"
android:id="#+id/img_logo"/>
<TextView
android:textAppearance="?android:attr/textAppearanceMedium"
android:textAllCaps="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:gravity="left|center_vertical"
android:id="#id/text_long" />
</RelativeLayout>
I have a TextView and a square ImageView that I would like to show in a horizontal linear layout. Each should take half of the parent view's width and the height should fit the content (i.e. the image). The text should be centered vertically.
Additional constraint is that the image should not grow beyond a given maxWidth (= maxHeight), and excess width should be made available to the TextView. Obviously, this conflicts with the 50/50 rule above. Is there a way to prioritize the constraints, i.e. allow the image to take half of the space unless it exceeds a given size?
These are layouts I tried:
The first one nicely stretches the left side to the available space. But the image takes more than half of the width as its layout_weight is not specified (as in image below).
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Some text."/>
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="200dp"
android:adjustViewBounds="true"
android:src="#drawable/image" />
</LinearLayout>
When I add layout_weight to the ImageView it always takes half of the width and ignore the maxWidth (see image below).
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:maxWidth="200dp"
android:adjustViewBounds="true"
android:src="#drawable/image" />
Enclosing the ImageView in another LinearLayout enables the maxWidth again, but the enclosing LinearLayout still takes half of the available space (see image below).
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right">
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:maxWidth="200dp"
android:adjustViewBounds="true"
android:src="#drawable/image" />
</LinearLayout>
Another option I have found for similar scenarios is to use a RelativeLayout with an invisible view as a center divider, but that locks the division to 50/50 (or wherever the divider is placed).
Okay, gonna go on ahead and post the xml I created, it's pretty much simple, it does most of your conditions.. One thing I'm having trouble with is the part where each view takes half of the parent view's width. Hope this still helps you in some way.
sample_layout.xml
<?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="wrap_content"
android:layout_margin="2dp"
android:background="#android:color/darker_gray">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/img_sample"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginRight="2dp"
android:layout_toLeftOf="#id/img_sample"
android:background="#color/colorPrimary"
android:gravity="center_vertical"
android:text="Some text." />
<ImageView
android:id="#id/img_sample"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginLeft="2dp"
android:adjustViewBounds="true"
android:maxWidth="200dp"
android:src="#drawable/sample_img" />
</RelativeLayout>
Here is a sample screenshot:
If ever you figure out how to the the half of each thing, kindly comment it here, It'd be nice to know about it for possible future use. :)
PS: Have you considered doing the half of each thing programatically? Like checking the LayoutParams then dynamically setting weightSum and the layout_weights.
Sample Image retrieved from this link
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_weight="1"
android:adjustViewBounds="true"
android:background="#color/blue"
android:src="#drawable/ic_launcher" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_margin="5dp"
android:layout_toStartOf="#id/imageView"
android:background="#color/colorPrimary"
android:padding="10dp"
android:text="Some text. " />
</RelativeLayout>
It won't be a perfect solution in term of performance. But you can achieve it by playing with FrameLayout and ImageView.
Here is the output:
Layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/textGray"
android:orientation="vertical">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/skyBlue">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#android:color/white">
<ImageView
android:id="#+id/imageView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="200dp"
android:src="#drawable/ic_settings"
android:visibility="invisible" />
<TextView
android:id="#+id/TextView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:text="!" />
</FrameLayout>
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:maxWidth="200dp"
android:src="#drawable/ic_settings" />
</LinearLayout>
</FrameLayout>
</LinearLayout>
In order to achieve desire behaviour, You would have to set same images to both imagesviews in this layout. one of them is invisble, It is just helping to make parent with same width and heights which would lead us to create TextView with same dimensions.
Note: If you want to change textView alignment, you can do it with layout_gravity or gravity.
I have 2 ImageButtons and a ToggleButton in a relative layout that fills it's parent. Here is the xml code:
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/relative2">
<ImageButton
android:layout_width="80dp"
android:layout_height="80dp"
android:id="#+id/imageButton4"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:src="#drawable/ic_exposure_minus1"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp" />
<ImageButton
android:layout_width="80dp"
android:layout_height="80dp"
android:id="#+id/imageButton6"
android:src="#drawable/ic_cancel_black"
android:layout_alignTop="#+id/imageButton4"
android:layout_toEndOf="#+id/imageButton4"
android:layout_marginLeft="5dp" />
<ToggleButton
android:layout_width="80dp"
android:layout_height="80dp"
android:text="New ToggleButton"
android:id="#+id/toggleButton"
android:checked="false"
android:clickable="true"
android:textOn="+"
android:textOff="-"
android:textSize="18dp"
android:layout_below="#+id/imageButton4"
android:layout_toStartOf="#+id/imageButton6"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:layout_alignParentEnd="false"
android:layout_alignParentStart="false" />
</RelativeLayout>
When the device is in portrait mode there is enough height room for the buttons. When the device is rotated to landscape, the relative layout gets smaller and there is no room for all the buttons. The lack of room is in the height dimension. So the Togglebutton that lays at the bottom of the other buttons is scaled automatically to smaller height, so that it fits.
I would prefer that all the buttons' height would be changed equally instead of just the last one (the ToggleButton) getting smaller in height. I would then have 3 buttons that have the same height, instead of 2 keeping the initial height and one with smaller height.
Could I get this result by changing the xml file?
PS: To make it more clear:
To make 3 buttons equal height, change your parent layout from relative layout to linear layout. And enable layout weight attribute equally. So they will be in same size.
You should use LinearLayout if you want to make a uniform UI across different orientation.
Use Orientation property along with layout weights and you will get your desired result.
You just have to make nested Linearlayouts accordingly.
Here is your layout made using linear layout.
Hope you understand the significance of using linearlayouts.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="5dp" >
<ImageButton
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_weight="0.5"
android:id="#+id/imageButton4"
android:src="#drawable/ic_exposure_minus1"
android:layout_marginLeft="5dp"/>
<ImageButton
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_weight="0.5"
android:id="#+id/imageButton6"
android:src="#drawable/ic_cancel_black"
android:layout_marginLeft="5dp" />
</LinearLayout>
<ToggleButton
android:layout_width="match_parent"
android:layout_height="80dp"
android:text="New ToggleButton"
android:id="#+id/toggleButton"
android:checked="false"
android:clickable="true"
android:textOn="+"
android:textOff="-"
android:textSize="18dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"/>
</LinearLayout>
I am trying to create a layout as per this picture (paint'ed).
Layout Design
Target level is API 17. This has to be created programmatically, not using XML. This has to be a responsive design.
I extensively researched and attempted other partially similar situations on stackoverflow, using GridLayout, TableLayout, GridView, various layout parameters, gravity, weight, view nesting and so on. However,
(a) I can't get the text buttons width to fill the available width real estate as per device screen size and orientation. Buttons with shorter texts are coming with shorter width.
(b) The plus, minus and number buttons are of fixed height and width irrespective of screen sizes and orientation. But they are not aligning with the text button in the left on the same row. only the bottom few pixels are visible.
I would appreciate any code snippet that can achieve the above layout. Thanks a million.
UPDATE:
Following inputs from #tiny-sunlight, I did this. Next I will recreate this programmatically.
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/layoutTable"
android:padding="5dp"
android:orientation="vertical"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/layoutRow"
android:padding="5dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_marginEnd="10dp"
android:layout_weight="17"
android:text="This is my button"
android:textSize="15sp"
android:textAllCaps="false"
android:gravity="start"
android:layout_width="0dp"
android:layout_height="40dp" />
<Button
android:layout_marginEnd="5dp"
android:layout_weight="1"
android:text="-"
android:textSize="15sp"
android:textStyle="bold"
android:layout_width="40dp"
android:layout_height="40dp" />
<TextView
android:layout_marginEnd="5dp"
android:layout_weight="1"
android:layout_marginTop="0dp"
android:paddingTop="10dp"
android:text="0"
android:textSize="15sp"
android:gravity="center"
android:layout_width="40dp"
android:layout_height="40dp" />
<Button
android:layout_weight="1"
android:text="+"
android:textSize="15sp"
android:textStyle="bold"
android:layout_width="40dp"
android:layout_height="40dp" />
</LinearLayout>
</LinearLayout>
</ScrollView>
Try to build layout below programmatically.
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:padding="5dp"
android:orientation="vertical"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:padding="5dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_marginRight="10dp"
android:layout_weight="1"
android:text="1111"
android:layout_width="0dp"
android:layout_height="40dp" />
<ImageView
android:layout_marginRight="5dp"
android:src="#mipmap/ic_launcher"
android:layout_width="40dp"
android:layout_height="40dp" />
<TextView
android:layout_marginRight="5dp"
android:background="#44bb11"
android:layout_marginTop="0dp"
android:paddingTop="10dp"
android:text="11"
android:layout_width="40dp"
android:layout_height="40dp" />
<ImageView
android:src="#mipmap/ic_launcher"
android:layout_width="40dp"
android:layout_height="40dp" />
</LinearLayout>
</LinearLayout>
</ScrollView>
You can use a recycler view, which will provide you scrolling option plus bind views on the fly for you.
So load a linear layout (orientation horizonal) into the recycler view. now for the layout, it then becomes easier. You need a textview, button,textview,button.
For each of these textview and buttons, set widht = 0dp and weight as 7,1,1,1 respectively i.e. your leftmost textview occupy 70% of width whereas all other occupy 10%. Obviously you can change these weights as per your requirements. Thats it for the layout.
Now just fill your data using the adapter.