I have some issue with follow structure:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/white_rectangle_radius10">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/first"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
/// many views here
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/second"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/first"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
/// many views here
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/third"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/second"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
/// many views here
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Programatically it can be 3 inner constraints or 4 or 2.
Root Constraint has round border radius.
Programatically when one of inner items clicked I set to this item background color, BUT when its first or last it overlap root border radius.
Note:
No need to suggest cardview as root element (not my option)
"Smart play" with margins/paddings also doesn't suit me because it should be changed programatically.
Is there some option to do it via XML?
When I added background color to first element it's top start/end corners not rounded.
First it is not recommended to nest layouts if you are going to use constraintLayout.
Second is how to design your view smoothly?
one of constraintlayout benefits is using the drag and drop option, therefore, start by doing that and ensure to place every item in its right place (but do not apply any constraint yet).
once all items are on the layout, click any item and look at the tool bar above the mobile screen, there is a magic wound, click on it, the constraint will be generated automatically based on the way you orgnized the view on the screen.
once that is done, now you might need to adjust the margins a bit according to the requirements.
also please assign id to each view before clicking the magic wound.
I hope I was helpful.
Related
My application has a lot of nested recycler views , In one of those I have a layout which holds an image and a textview like this.
The text view is an indicator which would disappear when the user opens that specific course.
And it would become something like this :
Since the indicator is present only on some of the courses , the indicator might disappear (view.gone) and appear (view.visible) on certain conditions.
This is the recyclerview code that holds these courses.
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv_video_packs"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/margin_16dp"
android:clipToPadding="false"
android:paddingEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/rv_continue_watching" />
Notice that the recycler view is a wrap content.
When there is a case of multiple courses , some courses might not contain the new video indicator. And if those courses with no indicator is present on the screen then the recyclerview would wrap its height to only hold on to the course image , something like this.
but the issue is , when we scroll horizontally , some courses might contain the indicator , meaning that the recyclerview should increase its height accordingly to accommodate the indicator as well .
Instead recyclerview fails to update its height to wrap around both the view hence resulting in this incomplete view.
This is happening because the recyclerview was unable to update its height when scrolling hence making the view cut in half.
I have tried multiple ways to fix this like ,
Setting setHasFixedSize to false etc . But didnt seem to work
This is happening only sometimes.
The only viable solution now is to fix the recycler view height to a specific height so that it holds both the views.
But I want a more scalable and optimum solution if possible for this .
Is there any way to make recyclerview recalculate its height ?
Recyclerview Item view code.
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true"
android:clickable="true"
android:orientation="vertical"
>
<ImageView
android:id="#+id/iv_learn_item"
android:visibility="invisible"
android:layout_width="134dp"
android:layout_height="200dp"
android:adjustViewBounds="true"
android:layout_marginStart="16dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:foreground="?attr/selectableItemBackground"
/>
<androidx.constraintlayout.widget.Guideline
android:id="#+id/video_update_tv_guideline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintGuide_begin="195dp"
android:orientation="horizontal"
/>
<TextView
android:id="#+id/video_update_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="#id/iv_learn_item"
app:layout_constraintEnd_toEndOf="#id/iv_learn_item"
app:layout_constraintTop_toBottomOf="#+id/video_update_tv_guideline"
android:layout_marginStart="#dimen/dimen_11dp"
android:layout_marginEnd="#dimen/dimen_11dp"
style="#style/content_update_pill"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
Adapter code
rvVideoPacks.layoutManager =
LinearLayoutManager(itemView.context, LinearLayoutManager.HORIZONTAL, false)
rvVideoPacks.setHasFixedSize(false)
rvVideoPacks.itemAnimator = null
rvVideoPacks.isNestedScrollingEnabled = true
rvVideoPacks.adapter = videoPackAdapter
EDIT :
I have also tried to make the indicator invisible , but that just creates an extra space at the bottom , making it look bad.
I want the recyclerview to adjust its height accordingly.
One way to fix this issue is give fix height to main ConstraintLayout if possible for your layout.
I'm working on the UI of my project, specifically I'm in a compound view extending a FrameLayout. Inside it I have two buttons, one (the smaller one) on top of the other (the larger one). I managed to make the smaller button be always on top with the 'android:elevation' property. The problem is that when I run the app and I click on the larger button, it hides the smaller one behind it, despite having a lower elevation property. I want the smaller one to be always on top even if the user clicks on the other button, but I can't manage to make it work.
Here is the xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="80dp"
android:layout_height="80dp"
android:padding="0dp"
android:layout_margin="0dp">
<Button
android:layout_width="match_parent"
android:layout_height="match_parent"
android:insetTop="0dp"
android:insetBottom="0dp"/>
<Button
android:layout_width="20dp"
android:layout_height="30dp"
android:backgroundTint="#color/black"
android:layout_gravity="bottom|end"
android:insetTop="0dp"
android:insetBottom="0dp"
android:elevation="10dp"/>
</FrameLayout>
you may try to set up translationZ instead elevation (or next to it) - translationZ is intended to be "fixed" elevation and elevation is dynamic, can be animated. note that every Button has a stateListAnimator set up, which is overriding elevation parameter in default implementation. check out what it does in HERE
easy way to fix would be to set for both Buttons android:stateListAnimator="#null", but you will loose some anims when click occur
easiest way would be to have one FrameLayout, inside two additional FrameLayouts and inside each one Button - fastest, but unelegant and not so efficient (but still for two buttons it won't be noticeable)
I have an element that should remain centered in the layout and a button on the right size. The button width is variable.
The following design exemplify two scenarios.
Scenario 1: Long text button
Scenario 2: Small text button
The current solution is have an invisible duplicated button on the left. This is not ideal because the button look and feel may also vary for different locales. I have tried guidelines but that would require to define a percentage and I would prefer if it was dynamic. Barriers don't seem to work either because I would need them to be mirrored.
Any tips how to achieve this?
Try doing width with 0dp and give them weight and change this in runtime
may be they are in linear layout which is horizontal.
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)
button.getLayoutParams();
params.weight = 1.0f; // afterwards you can do the same with changing the weight
button.setLayoutParams(params);
Perhaps you can take advantage of the ConstraintLayoutStates:
https://riggaroo.co.za/constraintlayout-constraintlayoutstates/
And have two layouts one for each scenario.
I ended up using a different solution. I used two guidelines, one at 20% and another at 80%, to define the areas where the button could expand to.
When no button is available, I used the property app:layout_constrainedWidth="false" that ignores the constrainst and allow the title to expand to the available space.
I used this solution because I may need multiple buttons with different call to actions according to the selected language. It would be difficult to manage multiple hidden anchor buttons.
If I understand your pictures correctly, you want to have two elements on your screen:
A View that's centered on the screen, it can be any width size.
A Button that's positioned to the right of the View that can also be any width size. You want this button to be centered in the empty space between the View and the edge of the right screen.
You can try this:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="#+id/view"
android:layout_width="100dp"
android:layout_height="100dp"
android:gravity="center"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:text="1"
android:textColor="#FFFFFF"
android:background="#000000"
/>
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="#+id/view"
app:layout_constraintEnd_toEndOf="parent"
android:text="2"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
I want to set app:layout_constraintHorizontal_bias="0.0" so that my TextView stays towards left. When I set it from layout editor by dragging the tiny circle to 0, the circle moves back to default 50. Also tried doing it from xml, but the layout has no effect on bias attribute at all.
If I remove the right constraint, the text goes offscreen owing to wrap_content width. Adding right constraint (along with existing left constraint) requires me to set horizontal bias to achieve permanent left alignment
This answer suggests to add constraint to "parent" (instead of another view, I guess), I tried it and set left and right constraints to parent but still no luck. (left was constraint to image view)
I tried left aligning it with another view (by selecting notification_subject and notification_body and using "Align Left Edges"), still no change in layout
This is my TextView
<TextView
android:id="#+id/notification_subject_tv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/notification_subject"
android:textAppearance="#style/TitleTextAppearance"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toRightOf="#id/notification_item_iv"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginRight="16dp"
android:layout_marginLeft="16dp"
app:layout_constraintHorizontal_bias="0.0"/>
Rendered layout in editor:
I think you have two issues here:
You are trying to match the constraint by using layout_width="0dp". I believe this should be set to layout_width="wrap_content".
On one side of your constraints you are using layout_constraintEnd_toEndOf="parent" and then layout_constraintLeft_toRightOf="#id/notification_item_iv" on the opposite side. Please can you change this to layout_constraintStart_toEndOf="#id/notification_item_iv"
Complete code:
<TextView
android:id="#+id/notification_subject_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/notification_subject"
android:textAppearance="#style/TitleTextAppearance"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/notification_item_iv"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginRight="16dp"
android:layout_marginLeft="16dp"
app:layout_constraintHorizontal_bias="0.0"/>
I am trying to build an Android UI where I need 7 boxes with the days of the week. In order to do this, I decided to go with a ConstraintLayout in order to be able to auto resize my views on any screen.
I created a chain between all 7 views with the with the "spread_inside" attribute, with worked but since I had my views' widths set to wrap_content, due to the nature of TextViews the views did not have equal widths. So I tried making them have equal widths by setting all of 7 views' widths to 0dp. This works but leaves no space between the views. Is there a way to add some spacing between these 7 views? Or is there another way of achieving the "equal widths" to all 7 views while keeping the auto-resizing ability on any screen? Is this even possible with ConstraintLayout or should I keep using LinearLayout for this kind of things? (as seen in the last screenshot)
I want my views to shrink when the screen is small and to expand up to a level when the screen is big. Please see the screenshots below of how it looks now. I want to add an 8dp padding between each view (on a LinearLayout I achieve this by adding a transparent divider on the layout with 8dp width, as in the last screenshot)
How it should look, achieved using LinearLayout
if you want them to be all the same width you don't even need spread_inside, just set the width to 0dp and then add margins to the views. for example:
<?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="match_parent">
<View
android:id="#+id/view1"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginRight="4dp"
android:layout_marginLeft="8dp"
android:background="#ffff0000"
app:layout_constraintEnd_toStartOf="#+id/view2"
app:layout_constraintStart_toStartOf="parent"/>
<View
android:id="#+id/view2"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginRight="8dp"
android:layout_marginLeft="4dp"
android:background="#ff00ff00"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/view1"/>
</android.support.constraint.ConstraintLayout>
keep in mind that space between views will be the sum of 2 margins, first and last view will have only 1 margin space, so you need to set them accordingly (like 4dp for margins between views and 8dp for first and last margin)