Setting view height dependent on its width in android in layout xml - android

Is it possible that a view should make it height same as it's width?
or any other layout for this purpose, because for vector image it's compulsory to provide width and height.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/googleLoginBtn"
android:orientation="horizontal"
android:layout_centerVertical="true">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<ImageView
android:layout_width="fill_parent"
android:layout_height="<height should be equal to the width>"
app:srcCompat="#drawable/simple"
tools:ignore="MissingPrefix"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Snappy"
android:textColor="#FF4081"
android:textSize="30dp"
android:singleLine="true"
android:gravity="center"
android:layout_margin="10dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Type less, do more. Fastest way to transfer money & make other transactions."
android:layout_margin="10dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srcCompat="#drawable/simple"
tools:ignore="MissingPrefix"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Smart"
android:textColor="#FF4081"
android:textSize="30dp"
android:gravity="center"
android:layout_margin="10dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Type less, do more. Fastest way to transfer money & make other transactions."
android:layout_margin="10dp"/>
</LinearLayout>
</LinearLayout>

Update:
I would use a ConstraintLayout today and use the property app:layout_constraintDimensionRatio="1:1"
Old Answer:
It's not possible entirely in xml without using a custom ImageView. This would be a solution:
public class SquareImageView extends ImageView {
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMeasuredWidth();
setMeasuredDimension(width, width);
}
}
However if your Image is already Square you can use the normal ImageView:
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:adjustViewBounds="true" />
A third solution would be setting the width and height directly in your Code:
LayoutParams params = imageView.getLayoutParams();
params.height = params.width ;
imageView.setLayoutParams(params);

You should be able to use the Percent support library for this.
You can either replace the LinearLayout the ImageViewis inside of with a PercentRelativeLayout and have the other views android:layout_belowor wrap the ImageView in a PercentFrameLayout.
I'm going to assume you've already defined the app namespace in this file as xmlns:app="http://schemas.android.com/apk/res-auto" since I see you using the namespace.
Once you've included the appropriate support library, the PercentFrameLayout approach would look something like this:
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<android.support.percent.PercentFrameLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="fill_parent"
app:layout_aspectRatio="100%"
app:srcCompat="#drawable/simple"
tools:ignore="MissingPrefix"/>
</android.support.percent.PercentFrameLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Snappy"
android:textColor="#FF4081"
android:textSize="30dp"
android:singleLine="true"
android:gravity="center"
android:layout_margin="10dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Type less, do more. Fastest way to transfer money & make other transactions."
android:layout_margin="10dp"/>
</LinearLayout>

Just a little update: The PercentFrameLayout class was deprecated in API level 26.1.0. Consider using ConstraintLayout and associated layouts instead. More information here: https://developer.android.com/reference/android/support/percent/PercentFrameLayout

use this
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
int myWidth = (int) (parentHeight * 0.5);
super.onMeasure(MeasureSpec.makeMeasureSpec(myWidth, MeasureSpec.EXACTLY), heightMeasureSpec);
}

Related

Impossible to change the height of a container in Recycleview

I have had a big trouble since several hours;
I have a recyclerview with several elements in each item. For one of them (lv_container), I can decrease its height but not increase it.
See the screenshot:
the xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/dashboard_part_medical_file_locked_title"
android:textSize="18sp"
android:textStyle="bold" />
<RelativeLayout
android:id="#+id/main_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/row_dashboard_color"
android:orientation="horizontal"
android:padding="10dp">
<ImageView
android:id="#+id/dashboard_part_image"
android:layout_width="80dp"
android:layout_height="95dp"
android:layout_alignParentEnd="true"
android:paddingBottom="20dp"
android:paddingEnd="10dp"
android:paddingStart="10dp"
android:paddingTop="20dp"
android:src="#drawable/dossier_medical" />
<RelativeLayout
android:id="#+id/lv_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/dashboard_part_image"
android:layout_alignParentStart="true"
android:layout_alignTop="#+id/dashboard_part_image"
android:layout_toStartOf="#+id/dashboard_part_image"
android:background="#android:color/white"
android:padding="10dp">
<ImageView
android:id="#+id/sup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:src="#drawable/ic_sup" />
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_toStartOf="#id/sup"
android:text="#string/dashboard_part_medical_file_inside" />
</RelativeLayout>
</RelativeLayout>
</LinearLayout>
and the code of the viewholder
DisplayMetrics metrics = pContext.getResources().getDisplayMetrics();
RelativeLayout.LayoutParams lvContainerParams = (RelativeLayout.LayoutParams) lvContainer.getLayoutParams();
lvContainerParams.width = RelativeLayout.LayoutParams.WRAP_CONTENT;
lvContainerParams.height = (int) (40 * metrics.density + 20 * metrics.density);
lvContainer.setLayoutParams(lvContainerParams);
ViewGroup.LayoutParams mainContainerParams = mainContainer.getLayoutParams();
mainContainerParams.height = (int) (lvContainerParams.height + 20 * metrics.density);
mainContainer.setLayoutParams(mainContainerParams);
ViewGroup.LayoutParams params = itemView.getLayoutParams();
params.height = (int) (mainContainerParams.height + 50 * metrics.density);
itemView.setLayoutParams(params);
When I change the height of lvContainer (the white container), the height of mainContainer is well modified (as you can see with the blue container), but the white container always remains fixed. However, in debug, heights are well calculated.
I tried to call lvContainer.invalidate() and/or lvContainer.requestLayout(), but nothing changed.
What's the error? Why the height of item and mainContainer can be easily modified, but not this of lvContainer?
I need your help
Thanks
Try removing this line
android:layout_alignBottom="#+id/dashboard_part_image"

How to set width of a View equal to any displaysize?

I am using a HorizontalScrollView to slide TextViews over the screen . My question now is, if there is any way to make the width of each RelativeLayout match the width of the phone screen, independent of the phone the user uses.
So is there a way to like get the display width of the device and then set it as the width of my RelativeLayout? Or is there even a better way to do it?
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="20dp"
android:layout_marginTop="20dp"
android:fillViewport="true">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="320dp"
android:layout_height="match_parent"
android:background="#android:color/holo_blue_dark">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:textSize="15sp"
android:textColor="#android:color/black"
android:id="#+id/info"
android:layout_margin="5dp"
android:textAlignment="center"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/info"
android:text="0"
android:textSize="80dp"
android:layout_centerHorizontal="true"
android:id="#+id/getrunkeneLiter"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="320dp"
android:layout_height="match_parent"
android:background="#android:color/holo_green_light">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:textColor="#android:color/black"
android:layout_margin="5dp"
android:id="#+id/danke"
android:textAlignment="center"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Feedback verfassen"
android:onClick="feedback"
android:layout_below="#+id/danke"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
</LinearLayout>
</HorizontalScrollView>
You can get the screen size and set it to each of your views programmatically. Alternatively, you can use a weighted LinearLayout and set its size to number of elements times screen size.
You can use this function to get the screen size (and then use the x value of the Point):
public static Point getScreenSize(Context context) {
final Point size = new Point();
final WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
final Display display = wm.getDefaultDisplay();
display.getSize(size);
return size;
}
To update the relative layouts you need to add an id to each of them. For example:
<RelativeLayout
android:id="#+id/first_subview"
android:layout_width="320dp"
android:layout_height="match_parent"
android:background="#android:color/holo_blue_dark">
And then in your activity:
private void updateViews() {
Point screenSize = getScreenSize(this);
updateView(findViewById(R.id.first_subview), screenSize);
updateView(findViewById(R.id.second_subview), screenSize);
...
}
private void updateView(View view, Point screenSize) {
view.getLayoutParams().width = screenSize.x
}

Customize seeekbar endpoints

I want to update seekbar UI such that there will be a vertical lines at both the endpoints of seekbar. I tried this by setting a custom drawable image (horizontal line with vertical lines at endpoints)in android:progressDrawable attribute but with that seekbar is not visible(only thumb is visible). I also tried creating custom views at left and right of seekbar but with that vertical lines doesn't remain at exact position in different device. Also as seekbar has default left and right padding i need to give margins to show vertical lines exactly at seekbar endpoints which can be different for different device.
What is an ideal approach to achive this requirement?
<SeekBar
android:id="#+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxHeight="#dimen/dp1"
android:paddingLeft="0px"
android:paddingRight="0px"
android:progressDrawable="#color/white"/>
<View
android:layout_width="#dimen/dp1"
android:layout_height="#dimen/dp10"
android:layout_alignLeft="#+id/seekBar"
android:layout_alignTop="#+id/seekBar"
android:layout_marginLeft="#dimen/dp16"
android:bawrckground="#color/white"
android:id="#+id/view" />
<View
android:layout_width="#dimen/dp1"
android:layout_height="#dimen/dp10"
android:layout_alignRight="#+id/seekBar"
android:layout_alignTop="#+id/seekBar"
android:layout_marginRight="#dimen/dp16"
android:background="#color/white”/>
I guess you have already answered your question. As you said the difference is only because of left and right padding then you can achieve this by simply changing margins of the views as follows.
Suppose this is your XML:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<View
android:id="#+id/view1"
android:layout_width="1dp"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/seekBar"
android:layout_alignParentLeft="true"
android:layout_alignTop="#+id/seekBar"
android:background="#android:color/black" />
<View
android:id="#+id/view2"
android:layout_width="1dp"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/seekBar"
android:layout_alignParentRight="true"
android:layout_alignTop="#+id/seekBar"
android:background="#android:color/black" />
<SeekBar
android:id="#+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:maxHeight="1dp"
android:progressDrawable="#android:color/black" />
</RelativeLayout>
Then just add following lines to your java file:
SeekBar seekBar = (SeekBar) findViewById(R.id.seekBar);
((ViewGroup.MarginLayoutParams) findViewById(R.id.view1).getLayoutParams()).leftMargin = seekBar.getPaddingLeft();
((ViewGroup.MarginLayoutParams) findViewById(R.id.view2).getLayoutParams()).rightMargin = seekBar.getPaddingRight();
This is definitely not the best solution but yes it's pretty simple.
Here are few pictures of what it looks like
Are you looking something like this? I have used layout weight with .05 for end points and .90 (%) for the seekbar... also given thumb. you can change it to your requirement.
<LinearLayout
android:id="#+id/ll_wizard_bar"
style="#style/Widget.AppCompat.ButtonBar"
android:layout_width="match_parent"
android:layout_gravity="center_vertical"
android:layout_height="30dp"
android:layout_margin="18dp"
android:orientation="horizontal">
<View
android:layout_width="0dp"
android:layout_weight=".05"
android:layout_height="30dp"
android:background="#FF0000FF" />
<SeekBar
android:id="#+id/my_seekbar"
android:layout_width="0dp"
android:layout_weight=".90"
android:layout_height="wrap_content"
android:maxHeight="15dip"
android:minHeight="15dip"
android:thumb="#android:drawable/star_big_off"
android:progressDrawable="#drawable/oval_shape"
android:layout_below="#+id/iv_consumericon"
android:indeterminate="false"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
/>
<View
android:layout_width="0dp"
android:layout_weight=".05"
android:layout_height="30dp"
android:background="#FF0000FF" />
</LinearLayout>
Remove edges
To get seekbar attached to your vertical lines.. cut off the padding programatically. my_seekbar.setPadding(0, 0, 0, 0); : Courtesy
https://stackoverflow.com/a/33475281/705428
Seekbar has default left and right padding
Solutions
You can use Programmatic way .In here, calling setPadding.
The view may add on the space required to display the scrollbars,
depending on the style and visibility of the scrollbars. So the values
returned from getPaddingLeft(), getPaddingTop(), getPaddingRight() and
getPaddingBottom() may be different from the values set in this call.
Demo XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<View
android:id="#+id/view1"
android:layout_width="10dp"
android:layout_height="50dp"
android:background="#54d66a"
/>
<SeekBar
android:id="#+id/seekBar"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:progress="0"
android:max="100"
android:layout_toRightOf="#+id/view1"/>
<View
android:layout_width="10dp"
android:layout_height="50dp"
android:background="#000000"
android:layout_toRightOf="#+id/seekBar"
/>
</RelativeLayout>
Java Class
oncreate()
SeekBar SeekBarOb=(SeekBar)findViewById(R.id.seekBar);
SeekBarOb.setPadding(20,0,0,0);
Bad Approach
Using hard coded Value .Call DisplayMetrics .
A structure describing general information about a display, such as
its size, density, and font scaling.
DisplayMetrics metrics = getResources().getDisplayMetrics();
int DeviceTotalWidth = metrics.widthPixels;
int DeviceTotalHeight = metrics.heightPixels;
Now For responsive
SeekBarOb.setPadding(DeviceTotalWidth*2/100 ,0,0,0); // add your value
Finally
FYI
Don't change demo XML , Add this in your java class
DisplayMetrics metrics = getResources().getDisplayMetrics();
int DeviceTotalWidth = metrics.widthPixels;
int DeviceTotalHeight = metrics.heightPixels;
SeekBar SeekBarOb=(SeekBar)findViewById(R.id.seekBar);
SeekBarOb.setPadding((int) (DeviceTotalWidth*.85/100),0, (int) (DeviceTotalWidth*2.10/100),0);

Stretch image in imageView in ViewPager

I am developing an application for Android that displays pictures of animals in ImageView in PageViewer. On most of the phones, everything seems fine. However, on my S7 (display resolution higher than the resolution of the picture), I can't get the picture to stretch to expand the device width.
The imageView also has a Xamarin photoView attacher attached to it, however I don't think it has any effect. I tried to remove it and it's still the same.
I already tried android:adjustViewBounds and all android:scaleType and unfortunately it didn't help.
Here is my xml code:
Part of the activity xml:
<fieldguideapp.droid.MyViewPager
android:id="#+id/pagerAnimalProfile"
android:layout_width="match_parent"
android:background="#000000"
android:layout_height="wrap_content" />
PagerLayout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:id="#+id/imgPagerLayoutImageView" />
<RelativeLayout
android:id="#+id/relLayoutImgPagerImageDesc"
android:orientation="horizontal"
android:layout_width="match_parent"
android:gravity="center"
android:layout_height="wrap_content"
android:background="#FFFFFFFF"
android:layout_gravity="bottom">
<TextView
android:text="Image desc"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FFFFFFFF"
android:textColor="#FF000000"
android:id="#+id/txtImgPagerImageDescription"
android:layout_alignParentLeft="true" />
<LinearLayout
android:id="#+id/linLayoutImgPagerIndicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_centerHorizontal="true"
android:layout_alignBottom="#id/txtImgPagerImageDescription" />
<TextView
android:text="Image credit"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FFFFFFFF"
android:textColor="#FF000000"
android:id="#+id/txtImgPagerImageCredit"
android:layout_alignParentRight="true"
android:layout_alignBottom="#id/linLayoutImgPagerIndicator" />
</RelativeLayout>
</LinearLayout>
Part of code that changes the height of the pager:
// To specify the height of the pager, select the highest child
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
int height = 0;
for (int i = 0; i < ChildCount; i++)
{
View child = GetChildAt(i);
child.Measure(widthMeasureSpec, MeasureSpec.MakeMeasureSpec(0, MeasureSpecMode.Unspecified));
int h = child.MeasuredHeight;
if (h > height) height = h;
}
if (Resources.Configuration.Orientation == Android.Content.Res.Orientation.Portrait)
{
heightMeasureSpec = MeasureSpec.MakeMeasureSpec(height, MeasureSpecMode.Exactly);
}
base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
}
EDIT: Here is what I get:
I would appreciate any kind of help or advice. Thanks
I eventually resized the picture manually using Bitmap.CreateScaledBitmap() method to fit the screen dimensions and then set it using ImageView.SetImageDrawable() and it works perfectly. I need to call GC.Collect() before and after in order to avoid OutOfMemoryException.
Although this isn't ideal, it works.

Adapt child's width to parent's width

I'm facing an issue with an xml layout.
This is the full xml:
<FrameLayout
android:id="#+id/root"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:adjustViewBounds="true"
tools:src="#drawable/segment_cultura"/>
<LinearLayout
android:id="#+id/message_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#color/black_divider"
android:padding="4dp">
<TextView
android:id="#+id/message"
style="#style/TextAppearance.AppCompat.Caption"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="2"
android:textColor="#color/white_secondary_text"
/>
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="end"
android:src="#drawable/ic_message"/>
</LinearLayout>
<ImageView
android:id="#+id/cancel"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="top|end"
android:layout_margin="4dp"
android:src="#drawable/ic_close"/>
</FrameLayout>
The goal: Use this as an item in a fixed height horizontal RecyclerView, using ONLY the image to determine the size of the item. Other views, such message_container or cancel will need to adapt to this size.
The problem: message_container needs to fill the width of the item, but it shouldn't modify the item width when there is a long text in message. It should go to the 2nd line and then get ellipsized. What happens instead is message never goes to the second line and makes the parents (message_container and root) enlarge to fit its text.
I'm looking for a solution that only involves xml, if I can't find it a custom view is preferred to some logic in the adapter.
Thank you for your time.
I solved this by using:
image.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (root != null && image.getWidth() != 0)
root.getLayoutParams().width = image.getWidth();
});

Categories

Resources