How to place views equidistant horizontally in relative layout?
I want to place views in relative layout occupying equal space according to the number of views added, similar to weight in Linear Layout
Layout I tried: (For three views)
<?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">
<!--<View
android:id="#+id/root"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_centerHorizontal="true"
android:layout_margin="16dp"
android:background="#android:color/holo_blue_bright"/>-->
<RelativeLayout
android:id="#+id/left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true">
<View
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_centerHorizontal="true"
android:layout_margin="16dp"
android:background="#android:color/holo_blue_bright"/>
</RelativeLayout>
<RelativeLayout
android:id="#+id/middle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="#id/left">
<View
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_centerHorizontal="true"
android:layout_margin="16dp"
android:background="#android:color/holo_blue_bright"/>
</RelativeLayout>
<RelativeLayout
android:id="#+id/right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="#id/middle"
android:layout_alignParentEnd="true">
<View
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_centerHorizontal="true"
android:layout_margin="16dp"
android:background="#android:color/holo_blue_bright"/>
</RelativeLayout>
</RelativeLayout>
Problem with the above layout is that the first two views are like wrap_content and the third one occupies all remaining space. How to make each view occupy one-third of horizontal space?
Note:
1. Kindly provide solution only in relative layout, not in linear layout or constraint layout.
2. The solution required should not be nested with Linear or other layouts. (Want flat layout)
If you want to stick with the relative layout you can do like this, get the the screen width like this.(need to get the pixel value)
private int Screendp(){
DisplayMetrics dm = new DisplayMetrics();
WindowManager windowManager = (WindowManager) this.getSystemService(WINDOW_SERVICE);
windowManager.getDefaultDisplay().getMetrics(dm);
int widthInDP = Math.round(dm.widthPixels / dm.density);
return widthInDP;
}
this is how we can convert dp to px
public int dpToPx(int dp) {
float density = this.getResources()
.getDisplayMetrics()
.density;
return Math.round((float) dp * density);
}
So in your activity set llayoutparams for each and every child views like below,
parent= findViewById(R.id.parent);
left= findViewById(R.id.left );
middle= findViewById(R.id.middle);
right= findViewById(R.id.right );
RelativeLayout.LayoutParams leftparams = new RelativeLayout.LayoutParams( dpToPx(64), dpToPx(64));
leftparams.leftMargin= 0;
left.setLayoutParams(leftparams);
RelativeLayout.LayoutParams middleparams = new RelativeLayout.LayoutParams( dpToPx(64), dpToPx(64));
middleparams.leftMargin=dpToPx((Screendp()/3));
middle.setLayoutParams(middleparams);
RelativeLayout.LayoutParams rightparams = new RelativeLayout.LayoutParams( dpToPx(64), dpToPx(64));
rightparams.leftMargin=dpToPx((Screendp()/3)*2);
right.setLayoutParams(rightparams);
This is working and i have tried this.
Related
I have a simple linear layout and want to divide the screen into two equally sized parts.
In the upper one, I want to put a SurfaceView that has exactly the same size as its parent, i.e. half of the screen. Unfortunately, it always either takes all the screen or nothing (depending on the configuration).
Why is that and how can I change it?
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="2"
android:orientation="vertical">
<LinearLayout android:id="#+id/layoutUpperDaw"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#192832">
<com.example.MySurvfaceView
android:id="#+id/id_mySurfaceView"
android:layout_width="match_parent"
android:layout_height="0pt"
android:layout_weight="1"
OR
android:layout_height="match_parent"
>
</com.example.MySurvfaceView>
</LinearLayout>
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#193222">
...
</LinearLayout>
</LinearLayout>
When you provide weight you have to set height or weight to 0dp as below.
<LinearLayout android:id="#+id/layoutUpperDaw"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#192832">
and
<com.example.MySurvfaceView
android:id="#+id/id_mySurfaceView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
>
Update: Answer above is correct about weight usage, make sure either hight or width is 0dp at all places where you used weight.
You don't really need nested LinearLayout. Following should work.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.example.MySurvfaceView
android:id="#+id/id_mySurfaceView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
>
</com.example.MySurvfaceView>
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#193222">
</LinearLayout>
</LinearLayout>
Programmatically:
Find the parent layout.
GridLayout gridLayout =(GridLayout)findViewById(R.id.gridLayout);`
Get measured height and Width of parent.
int height = gridLayout.measuredHeight();
int width = gridLayout.measuredWidth();
3.Calculate child view height and width.For example two child each taking 50% of height in the parent but taking full width of parent:
int childHeight = height/2;
int childWidth = width;
4.Get instanceof LayoutParams depending on parent type.
GridLayout.LayoutParams params = new GridLayout.LayoutParams();
5. Set height and width on layout params.
params.width = childWidth;
params.height = childHeight;
6.Create child view and set Layout params.
ImageView imageview = new ImageView();
imageview.setLayoutParams(params);
7.Add child View to parent.
gridLayout.addView(ImageView);
I have problem with changing Exapandable layout params. I'm using layout from this library:
https://github.com/AAkira/ExpandableLayout
I put ImageView inside this layout and than when I download picture into ImageView I want my layout to wrap this image.
<com.github.aakira.expandablelayout.ExpandableRelativeLayout
android:id="#+id/expandable_area"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_below="#+id/event_accepted_people_scrollview"
android:layout_alignParentStart="true">
<android.support.v7.widget.AppCompatImageView
android:id="#+id/card_map_icon"
android:layout_width="70dp"
android:layout_height="70dp"
app:srcCompat="#drawable/vector_drawable_ic_map_black___px"
android:tint="#color/skilltrade_grey"
android:scaleType="center"
android:layout_marginTop="5dp"
android:layout_centerHorizontal="true"
android:background="#drawable/ripple_effect"/>
<TextView
android:id="#+id/no_map_snapshot_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/no_map_snapshot"
android:gravity="center_horizontal"
android:layout_marginBottom="15dp"
android:layout_below="#id/card_map_icon"/>
<ImageView
android:id="#+id/carditem_map_snapshot"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/details_map_textview"
android:scaleType="center"
android:layout_marginTop="5dp" />
</com.github.aakira.expandablelayout.ExpandableRelativeLayout>
Problem is that layout wraps only AppCompatImageView and TextView because ImageView source is not set and it's height is 0. After downloading picture layout is not wraping content correctlly...
That's what I'm doing now:
-I download picture in size 640x480.
-Than I scale it to match my screen
-After that when I know height of my image I change params of my Expandable layout like this:
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mapSnapshot.getLayoutParams();
params.width = width;//scaled picture width
params.height = height;//scaled picture height
mapSnapshot.setLayoutParams(params);
expandableArea.updateViewLayout(mapSnapshot, params);
Unfortunately it's not working and layouts height is still not matching ImageView...
I would be grateful for any help :)
I would like the have only one ImageButton centered horizontally and vertically, but with a responsive width of a specific percentage, let's say 70%, and its height according to its width (so it won't be stretched)
I did so far the centering and I'm trying to achieve the responsive width.
This is the code
<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="match_parent"
android:background="#30CCA4">
<ImageButton
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".30"
android:orientation="vertical"
android:layout_gravity="center"
android:id="#+id/imageButton"
android:src="#drawable/splash_image"
android:background="#null" />
How can I do the responsive width?
Thanks
Try this.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center">
<ImageButton
android:id="#+id/img_bt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FF4081" />
</LinearLayout>
Code :
ImageButton img_bt = (ImageButton) view.findViewById(R.id.img_bt);
Display display = getActivity().getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
LinearLayout.LayoutParams parms = new LinearLayout.LayoutParams(width/10*7, width/10*7);
img_bt.setLayoutParams(parms);
I am writing an application where need to assign rest of screen space to view.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/txtView_1"
android:layout_width="match_parent"
android:layout_height="100dp" />
<TextView
android:id="#+id/txtView_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Test Text" />
</LinearLayout>
and to set runtime I am using following:
private void process() {
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int txtView1Height = txtView_1.getHeight();
LayoutParams layoutParams = (LayoutParams) txtView_2.getLayoutParams();
layoutParams = new LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
(metrics.heightPixels - txtView1Height));
txtView_2.setLayoutParams(layoutParams);
}
But here it's taking not exact same remaining height..since textview sting not placing in center(this is how I simply check)...it might be mistaken to set height in pixel.
Any suggestion here?
You can use weight xml parameter
<TextView
android:id="#+id/txtView_2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:gravity="center"
android:text="Test Text" />
or in your case simple set height to match_parent
android:layout_height=match_parent
To check even more simpler set gravity to bottom. If you still want to do this programmatically dont use DisplayMetrics to get height (Action Bar and Software Buttons are also a part of display) use your root LinearLayout height. Also check if txtView1Height is not 0 (maybe view was not drawed at the moment of calculation)
I have a GUI where Initially margins of innerLayout are 0,10,0,100 and in my intention hideinfoarea() should remove the infoLayout and change the margins in 0, 10,0,10 and showInfoarea() should restore the initial margins and show infoLayout again.
Unfortunately when I set these margins some Layout become not well shown, for example the title is too close to mainLayout, and a piece of image will be covered by infoLayout when I re-enable it.
despite in my test with layout editor the margins are perfect.
In adition when I invoke showInfoarea() why the layout margins aren't restored to the original conditions, if I simply reverse the operation of hideInfoarea()?
Here my code
RelativeLayout mainLayout;
LinearLayout innerLayout;
public void hideInfoarea(){
mainLayout = (RelativeLayout) findViewById(R.id.mainContainer);
innerLayout = (LinearLayout) findViewById(R.id.innerLayout);
mainContainer.removeView(infoLayout);
//adjust margins
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) innerLayout.getLayoutParams();
params.setMargins(0, 10, 0, 10);
innerLayout.setLayoutParams(params);
}
public void showInfoarea(){
mainLayout = (RelativeLayout) findViewById(R.id.mainContainer);
innerLayout = (LinearLayout) findViewById(R.id.innerLayout);
mainContainer.addView(infoLayout);
//adjust margins
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) innerLayout.getLayoutParams();
params.setMargins(0, 10, 0, 100);
innerLayout.setLayoutParams(params);
}
Here the XML
<!-- The main content view -->
<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"
android:padding="5dp"
android:gravity="fill_horizontal|fill_vertical"
android:background="#color/Platinum"
android:id="#+id/mainLayout">
<TextView
android:id="#+id/txtTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="Sample"
android:textSize="12dp"
android:layout_marginBottom="10dp"/>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="#+id/innerlayout"
android:layout_marginTop="10dp"
android:layout_marginBottom="100dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:id="#+id/imageView"
android:scaleType="fitXY"
android:src="#drawable/rectangle"
android:layout_marginBottom="100dp"
android:layout_marginTop="10dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="400dp"
android:layout_height="100dp"
android:layout_alignParentBottom="true"
android:background="#drawable/background_label_mm"
android:layout_centerHorizontal="true"
android:orientation="vertical"
android:id="#+id/infoLayout"
android:layout_margin="5dp">
</LinearLayout>
</RelativeLayout>
<!-- The navigation drawer -->
<ListView
android:id="#+id/drawer"
android:layout_width="320dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#F3F3F4"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"/>
</android.support.v4.widget.DrawerLayout>
Be carefull, as you can read one the Reference: setMargins(int left, int top, int right, int bottom) method use px and your layout use dp. You have to do a conversion like:
// where "dp" is your value dip
int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
(float) dp, getResources().getDisplayMetrics());
// then set your margins
params.setMargins(0, px, 0, px);
See this answer: What is the correct way to specify dimensions in DIP from Java code? and the reverse one: Converting pixels to dp.
Also, you can read another thing one the Reference:
Sets the margins, in pixels. A call to requestLayout() needs to be done so that the new margins are taken into account.
Hope this helps.