I have a parent RelativeLayout and 3 child views. View one and View two are align parent bottom. I want my view three to be aligned above view one if view one is visible, otherwise align above view two if view one is not visible.
Here's my layout:
<?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"
xmlns:tools="http://schemas.android.com/tools">
<View
android:id="#+id/one"
android:layout_width="200dp"
android:layout_height="100dp"
android:layout_alignParentBottom="true"
android:background="#color/green"
tools:visibility="visible"/>
<View
android:id="#+id/two"
android:layout_width="250dp"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:background="#color/red"/>
<View
android:id="#+id/three"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_above="#id/one"
android:layout_marginBottom="10dp"
android:background="#color/yellow"/>
</RelativeLayout>
I know if I put view one and view two into another layer and align view three above the other layer it will work, but as of current architecture i am not allowed to do that. Is there any other way to achieve this? Would ConstraintLayout be able to solve this issue?
Try this:
<?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"
xmlns:tools="http://schemas.android.com/tools">
<View
android:id="#+id/one"
android:layout_width="200dp"
android:layout_height="100dp"
android:layout_above="#+id/two"
android:background="#android:color/holo_green_dark"
tools:visibility="visible"/>
<View
android:id="#+id/two"
android:layout_width="250dp"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:background="#android:color/holo_red_dark"/>
<View
android:id="#+id/three"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_above="#+id/one"
android:layout_marginBottom="10dp"
android:background="#android:color/holo_blue_bright"/>
</RelativeLayout>
The thing is you just add
android:layout_above="#+id/two"
to view one which will make it stay above view two and add
android:layout_above="#+id/one"
to view three which will make it stay above view one.
So if view one is visibility is gone view three will stay above view two.
You can test this by setting visibility to gone for view one.
Would ConstraintLayout be able to solve this issue?
Yes.
We can achieve this by doing it programmatically.
Find the below code to align the third view based on the first view visibility status.
final View view3 = findViewById(R.id.three);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(100, 100);
params.addRule(RelativeLayout.ABOVE, view3.getVisibility() == View.VISIBLE ? R.id.one : R.id.two);
view3.setLayoutParams(params);
If you want to go with your current Layout, then you can programatically set the height of view one to zero instead of changing its visibility. In this case, view 3 remains on the top of one and because of zero height, view 3 will appear on the top of view two.
RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.one);
relativeLayout.getLayoutParams().height = 0;
Related
I am using the RecyclerView to inflate a Linear Vertical listViews, However, although the width of a child is set to match_parent, RecyclerView wraps that at runtime.
Here is a screenshot of the problem:
item_recyclerView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="#+id/tag_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="0dp"
android:maxLines="2"/>
<TextView
android:id="#+id/tag_role"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<com.google.android.material.imageview.ShapeableImageView
android:id="#+id/user_pic"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_weight="0"
android:rotation="-45"
android:scaleType="centerCrop"
android:src="#drawable/ic_user"
app:shapeAppearanceOverlay="#style/ShapeAppearanceOverlay.App.circleImageView" />
</LinearLayout>
When inflating a layout file, the layout_ attributes on the root view will be ignored unless you specify a parent ViewGroup in the inflate() call. You are not currently doing so.
In your onCreateViewHolder() method, replace this:
ItemQuestionPostBinding binding = ItemQuestionPostBinding.inflate(inflater);
with this:
ItemQuestionPostBinding binding = ItemQuestionPostBinding.inflate(inflater, parent, false);
Note also that you probably don't want to be using match_parent for the height of your RecyclerView's items:
android:layout_width="match_parent"
android:layout_height="match_parent"
This will give the appearance that only a single item is visible in your RecyclerView, since each item will be the full height of the screen. This is currently not a problem for the exact same reason that the match_parent width is being ignored.
give for your parent linearlayout weightSum 5
give for imageView weight 1 and do his width 0
and for child linearlayout weight 4
enter code here
discover.xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:behavior_peekHeight="#dimen/peek_height">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/discover_displays"
android:layout_width="match_parent"
android:layout_height="#dimen/peek_height"
android:background="#drawable/round_corners"
android:orientation="vertical">
<TextView
android:id="#+id/to"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingTop="#dimen/pad_17"
android:paddingBottom="#dimen/pad_16"
android:text="#string/to"
android:textAlignment="center"
android:textColor="#color/light_gray"
android:textSize="#dimen/pad_12"
android:visibility="gone"
android:textStyle="bold" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/disp"
android:layout_width="match_parent"
android:layout_height="#dimen/disp_height"
tools:listitem="#layout/disp_item" />
<ProgressBar
android:id="#+id/progress"
style="?android:attr/small"
android:layout_width="#dimen/progress_bar"
android:layout_height="#dimen/progress_bar"
android:layout_gravity="center"
android:layout_marginTop="#dimen/text_width"
android:indeterminate="true"
android:progressBackgroundTint="#color/progressbar_background"
android:progressTint="#color/progressbar_color" />
<TextView
android:id="#+id/discovery_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="#dimen/pad_26"
android:gravity="center"
android:paddingStart="#dimen/element_margin"
android:paddingEnd="#dimen/element_margin"
android:text="#string/discovery_message"
android:textColor="#color/text_color"
android:textSize="#dimen/text_size"
android:visibility="visible" />
<androidx.appcompat.widget.AppCompatButton
android:id="#+id/error_action"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="#dimen/pad_12"
android:background="#color/discovery_error_item"
android:padding="#dimen/discovery_error"
android:textColor="#color/white"
tools:text="#string/bluetooth_label" />
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</LinearLayout>
Current Layout :
Expected layout : The Recyclerview in the above pick should have a height as below, while the 3 views progressbar, discover state message, error action should be aligned in the middle as in order (one below the other). How to accomplish the same ?
The view with id : "to" is optional, since its being used in two fragments, 1 fragment uses it and other dont, hence the visibility is hidden and made visible whenever required. I am using the coordinator layout, since a bottomsheet view is being used.
The recyclerview height needs to be adjusted, keeping the progress bar, discovery state message, error actions being aligned to center when its visible one after the other (either recyclerview is visible at a time, or the 2 views are visible at a time (progress bar, discover error state or the button) or only the error button is visible at a time aligned to the center) . Please help in aligning the view items to the center when the visibility of one view is not present. currently the view aligns to the top if there is no visibility. Thanks.
I believe you can nest ConstraintLayout within the CoordinatorLayout and implement your screen in the Constraint Layout by adding the constraints you wish.
Should be easy enough.
You have to use a combine of linear layout and relative layout with the relative as parent , and recycler and the linear as childs of it , its look like this :
<RelativeLayout>
<RecyclerView android:layout_width="match_parent" android:layout_height="match_parent"\><LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android: orientation="vertical" ... android:gravity="center"></LinearLayout>
</RelativeLayout>
I created the ListView item as Constraint Layout. It has one ImageView which is constrained to the parent(top and start) and one LinearLayout which is constrained to this ImageView(top to top, start to end, bottom to bottom). In the Java part, I do some logic that in some cases ImageView is GONE and other cases it will be Visible. There isn't any problem with this part. The layout is like that:
And code like that:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:paddingHorizontal="#dimen/activity_horizontal_margin"
android:paddingVertical="#dimen/activity_vertical_margin">
<ImageView
android:id="#+id/image"
android:layout_width="50dp"
android:layout_height="50dp"
android:contentDescription="#string/list_image_cd"
android:src="#drawable/app_logo"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="#+id/texts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginLeft="24dp"
android:orientation="vertical"
app:layout_constraintStart_toEndOf="#id/image"
app:layout_constraintTop_toTopOf="#id/image"
app:layout_constraintBottom_toBottomOf="#id/image">
<TextView
android:id="#+id/miwok_word"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="miwok" />
<TextView
android:id="#+id/english_word"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="english" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
I can fix the problem by changing the layout to LinearLayout. But in Constraint Layout when ImageView is GONE one of textview is gone, the other remains. I have read similar to this ConstraintLayout, when constraint dependent view is gone, the layout view behave weirdly . But in my situation why one of the textviews is still remains if this is the child view of linear layout (why all linear layout isn't gone?).
Layout in the app (I change english text into phrases, but miwok isn't seen):
Because the LinearLayout has its top and bottom constraints set to the ImageView, it will be centered vertically on the ImageView. See the documentation that addresses this. "Vertically centered" means that the vertical center of the LinearLayout and the ImageView will be at the same y position.
Now, when the ImageView is set to GONE, the ImageView is reduced to a virtual point. Since it is constrained to the start and top of the parent, the "gone" view will now be a point at the screen's origin (0,0). The LinearLayout remains constrained to the top and bottom of the ImageView as before, so it is still centered on the ImageView. But, since the ImageView is now a point at the origin, and its centered has shifted, the LinearLayout must shift up to keep centered on the ImageView. As a result, the top TextView leaves the top of the screen and can no longer be seen.
How you would fix this depends on what you are trying to do.
As your LinearLayout top and bottom constraint is given to imageview and when it's gone it's height become less and because of that top textview is not visible.
#Cheticamp give more information in his answer.
You can change your constraint like below and it will work as you want. Change Imageview top and bottom constraint to LinearLayout top and bottom.
<?xml version="1.0" encoding="utf-8"?><?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp">
<ImageView
android:id="#+id/image"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="#mipmap/ic_launcher"
app:layout_constraintBottom_toBottomOf="#+id/texts"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/texts" />
<LinearLayout
android:id="#+id/texts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginLeft="24dp"
android:orientation="vertical"
app:layout_constraintStart_toEndOf="#+id/image"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/miwok_word"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="miwok" />
<TextView
android:id="#+id/english_word"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="english" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
I'm trying to create a layout containing, among other things, a LinearLayout. The XML for the whole screen is:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="#+id/fileSelView"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Spinner android:id="#+id/dirListSpinner"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"/>
<Spinner android:id="#+id/fileTypeSpinner"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"/>
<EditText android:id="#+id/fileNameTF"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_toRightOf="#+id/fileTypeSpinner"/>
<LinearLayout android:id="#+id/centerBox"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_below="#+id/dirListSpinner"
android:layout_above="#+id/fileTypeSpinner"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true">
<ListView android:id="#+id/dirView" android:background="#f00"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:layout_weight="1"/>
<RelativeLayout android:id="#+id/buttonBox" android:background="#0f0"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_weight="0">
<Button android:id="#+id/upButton"
android:text="Up"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"/>
<Button android:id="#+id/mkdirButton"
android:text="MkDir"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_below="#+id/upButton"
android:layout_centerHorizontal="true"/>
<Button android:id="#+id/okButton"
android:text="OK"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_below="#+id/mkdirButton"
android:layout_centerHorizontal="true"/>
<Button android:id="#+id/cancelButton"
android:text="Cancel"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_below="#+id/okButton"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
The result of this layout looks like this:
The LinearLayout itself is laid out the way I want, within its parent, but its contents come out all wrong. It has two children: a ListView on the left and a RelativeLayout on the right. The ListView should take up all the available height, and as much width as possible, while the RelativeLayout should be a small as possible and vertically centered within its parent. Instead, the ListView ends up being way too narrow, and the RelativeLayout grows to fill the space, despite the ListView having android:layout_weight="1" and the RelativeLayout having android:layout_weight="0". Also, the RelativeLayout is aligned with the top of its parent, despite having android:gravity="center_vertical".
What am I doing wrong?
UPDATE
OK, I changed android:gravity="center_vertical" to android:layout_gravity="center" on the RelativeLayout, and now it is vertically centered within its parent, as desired.
Regarding the layout weight issue, I tried changing android:layout_width="fill_parent" to android:layout_width="0px" on the ListView, but that didn't work; I'm getting the same result as before, with the ListView way too narrow and the RelativeLayout expanding to take up the available space.
The layout now looks like this: http://thomasokken.com/layout-problem2.png
Note that the buttons in the RelativeLayout are not correctly centered horizontally. It's as if the RelativeLayout got sized and laid out correctly at first, and then grew towards the left later, without re-laying out its children.
I haven't been able to get the ListView to get sized properly using a RelativeLayout parent, either. Could it be resizing itself in response to a setAdapter() call? I'm using a custom ListAdapter class whose getView() method returns RelativeLayout objects:
public View getView(int position, View convertView, ViewGroup parent) {
File item = items[position];
if (convertView == null) {
Context context = parent.getContext();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.file_selection_dialog_row, null);
ImageView icon = (ImageView) convertView.findViewById(R.id.fdrowimage);
icon.setImageResource(item.isDirectory() ? R.drawable.folder : R.drawable.document);
}
TextView text = (TextView) convertView.findViewById(R.id.fdrowtext);
text.setText(item.getName());
return convertView;
}
The layout for the list rows looks like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<ImageView android:id="#+id/fdrowimage"
android:layout_height="35dp" android:layout_width="wrap_content"
android:layout_alignParentLeft="true"
android:paddingRight="5dp" android:paddingLeft="3dp"/>
<TextView android:id="#+id/fdrowtext"
android:layout_width="wrap_content" android:layout_height="35dp"
android:layout_toRightOf="#+id/fdrowimage"
android:layout_alignTop="#+id/fdrowimage"
android:layout_alignBottom="#+id/fdrowimage"
android:gravity="center_vertical"
android:textSize="23dp"/>
</RelativeLayout>
There are a few things going on here.
First as to the vertical centering of the RelativeLayout. android:gravity="center_vertical" indicates that the children of this view should have center_vertical applied. And it is actually working. As you can see by the size of the green background, your RelativeLayout is only as big as it needs to be to fit the buttons. You have two solutions. If you want the height of the view to stay the same and be centered inside its parent, you would use android:layout_gravity="center". If you want the RelativeLayout to fill the column then you need to set the layout_height of the RelativeLayout to be "fill_parent". android:layout_gravity applies to the view itself inside its parent. android:gravity applies to the view's children.
Second is the layout weight issue. The LinearLayout will first layout any wrap_content items (ie, your RelativeLayout), then it will apply children that have a layout_weight AND a size of 0. If you want your layout_weight to work properly, you need to set the layout_width of the ListView to "0px".
I have the following structure defined in an xml layout file.
<RelativeLayout android:id="#+id/mainLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_height="wrap_content">
<FrameLayout android:id="#+id/frame" android:layout_centerInParent="true" android:layout_width="wrap_content" android:layout_height="wrap_content" ></FrameLayout>
<Button android:id="#+id/button" android:layout_below="#id/frame" android:layout_width="wrap_content" android:layout_height="wrap_content" />
</RelativeLayout>
The FrameLayout is positioned correctly in the center of its parent. But the Button isn't getting positioned under it. Instead it's displaying in the top left corner.
Am I doing something incorrectly or is this a bug with RelativeLayout?
How have you checked whether frame layout is in the center of parent or not ?
Try adding some view inside frame layout or give some fix height and width to it. It might solve the problem.