Translating other views along with Button (on press) - android

I was looking to create a view like this:
It has the behavior of a button, so I used a ConstraintLayout and placed the image and the TextView ('some text here') on top of the button using constraints (the other text and icon is implemented as button text and icon respectively).
The xml is as follows (inside the constraint layout):
<com.google.android.material.button.MaterialButton
android:id="#+id/btn_plan_change"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingHorizontal="10dp"
android:paddingVertical="30dp"
android:text="start now"
android:textAlignment="viewEnd"
app:icon="#drawable/ic_chevron_right_black_24dp"
app:iconGravity="end"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/iv_plan_change"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginHorizontal="10dp"
android:layout_marginVertical="25dp"
android:background="#drawable/circle_background"
android:backgroundTint="?attr/colorPrimary"
android:elevation="2dp"
android:padding="10dp"
android:src="#drawable/ic_money"
app:layout_constraintBottom_toBottomOf="#id/btn_plan_change"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintStart_toStartOf="#id/btn_plan_change"
app:layout_constraintTop_toTopOf="#+id/btn_plan_change" />
<com.google.android.material.textview.MaterialTextView
android:id="#+id/tv_plan_change"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_margin="10dp"
android:elevation="2dp"
android:gravity="center_vertical"
android:lineSpacingExtra="5dp"
android:text="some text here"
app:layout_constraintBottom_toBottomOf="#+id/btn_plan_change"
app:layout_constraintStart_toEndOf="#+id/iv_plan_change"
app:layout_constraintTop_toTopOf="#+id/btn_plan_change" />
As you can see, I have used an elevation of 2dp on both the ImageView and the TextView to keep it on the same elevation as the button, but on pressing the button, both of them go behind the button and can't be seen.
I have experimented with animating translationZ of both both views on button press and release, but it doesn't work so well (sometimes animates later than button, sometimes goes behind it).
I would love to have a working implementation.

Related

Constraint Layout Centre Text Position with End Reference to Other Widget

I have a dialog widget with navigation bar contains title and close button. I want to put the title in centre of the device, and put the close button in the end of layout. However when the title is long, then it will overlap with the close button. Here is my code:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:maxLines="1"
android:ellipsize="end"
android:text="Title" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:text="Close" />
</androidx.constraintlayout.widget.ConstraintLayout>
Any workaround to achieve this?
Thank you.
Normally, to center text, you would constrain the start and end of the text to the end point of the centering region. In this case, since the text should be centered on the screen, you would attach the start to the parent start and the end to the parent end. This works unless the centered text exceeds the empty center region and overlaps the "Close" TextView. Unfortunately, there is no way to make these constraints and tell the centered view to avoid overlapping the TextView on the right.
To make it work, I would introduce another TextView that is a duplicate of the "Close" TextView, make it invisible and attached to the top and start of the parent. This will create a region between the two TextViews where the text can be centered. To ensure that the text does not overlap the end TextView, specify app:layout_constrainedWidth="true" on the centered view. Something like this:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/space"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Close"
android:visibility="invisible"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:text="This is some very long text that should stretch across the device and ellipsize."
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toStartOf="#+id/textView2"
app:layout_constraintStart_toEndOf="#+id/space"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Close"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Barrier
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="left"
tools:layout_editor_absoluteX="306dp"
tools:layout_editor_absoluteY="62dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
which will show in the designer like this for long text:
and like the following for short text:
There are other ways to do this that would involve some coding, but this is an XML-only solution which, IMO, is preferable.

How to align two text in extreme ends (left and right) in a Single Button View android

I have a button for showing list of items in a different popup
In that button, I want a text as a label which is left aligned and a text on the right side which would be dynamically added depending on the item selected from the popup
How to align these two texts on a single button? I'm new to android.
Tried giving different ascii characters as spaces but didn't help
<Button
android:id="#+id/button"
android:layout_width="400dp"
android:layout_height="80dp"
android:textAllCaps="false"
android:textColor="#color/white"
android:textSize="14dp" />
Expected Result
[**Name** john] ---- single button view with two texts
Wrap your button and textviews withhin a frame layout, along with elevation to display the textviews over the button :
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="80dp"
android:textAllCaps="false"
android:textSize="14dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|start"
android:text="TextView 1"
android:layout_margin="5dp"
android:elevation="2dp"
android:outlineProvider="none"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|end"
android:text="TextView 2"
android:layout_margin="5dp"
android:elevation="2dp"
android:outlineProvider="none"/>
</FrameLayout>
Note: android:outlineProvider="none" will remove the shadow on the textviews that the elevation provides.

Material buttons steal clicks from a view that is declared after them in layout hierarchy

I want to hide some part of the content under a scrim (like in drawer layout).
The MaterialComponents buttons that are under this scrim view are receiving clicks to the scrim view, and that is a major problem.
content scrim view:
<FrameLayout
android:id="#+id/scrim"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="gone"
android:background="#color/transparent"
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
button that steals clicks:
<com.google.android.material.button.MaterialButton
android:id="#+id/add_at_start"
android:theme="#style/ButtonArrowShapedLeft"
style="#style/ButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="Add"
android:visibility="gone"
tools:visibility="visible"
app:icon="#drawable/ic_add_black_24dp"
app:layout_constraintStart_toStartOf="#+id/container"
app:layout_constraintTop_toBottomOf="#+id/container" />
I already established that the problem lies within the button being elevated.
If I set the elevation of the scrim even to 2dp, the button receives no clicks, despite the fact it has probably more dp of elevation than the scrim view.
But this does not solve my problem, it actually makes it worse, because the scrim view now covers everything on the screen, even the content that is way later in layout hierarchy.
I know I can just disable the buttons when the content scrim is visible, but this just doesn't seem right and the buttons feeling entitled to stealing clicks just because of some ludicrous elevation actually angries me enough to seek help.
try this :
<com.google.android.material.button.MaterialButton
android:id="#+id/add_at_start"
android:theme="#style/ButtonArrowShapedLeft"
style="#style/ButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="Add"
android:visibility="gone"
android:clickable="true"
tools:visibility="visible"
app:icon="#drawable/ic_add_black_24dp"
app:layout_constraintStart_toStartOf="#+id/container"
app:layout_constraintTop_toBottomOf="#+id/container" />

Align views right in ConstraintLayout without clipping

I am creating a dialog with two buttons aligned right in relation to the parent ConstraintLayout.
Everything is fine, until the text of the buttons becomes very long. When the text of either or both buttons is lengthy, the buttons extend beyond the bounds of the parent, causing clipping of the text, as shown in the image below. I would like to handle cases where there is longer text.
i.e. The desired behavior would be
buttons should wrap text when text is long
buttons should stay within bounds of parent and obey parent padding
buttons should stay aligned right of parent
When button text is short, the layout works as intended:
When button text is long:
Cancel text is truncated when cancel button text is long. This is happening because the button itself is being pushed past the parent's boundaries.
Cancel text pushed beyond parent boundaries when ok button's text is long, again, because the button is pushed beyond the parent's boundaries.
Layout code
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="#dimen/dialog_padding"
android:paddingLeft="#dimen/dialog_padding"
android:paddingRight="#dimen/dialog_padding"
android:paddingTop="#dimen/dialog_padding">
<TextView
android:id="#+id/dialog_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/dialog_text_margin"
tools:text="Dialog title" />
<TextView
android:id="#+id/dialog_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/dialog_text_margin"
app:layout_constraintTop_toBottomOf="#id/dialog_title"
tools:text="Dialog text content" />
<Button
android:id="#+id/cancel_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toStartOf="#id/ok_btn"
app:layout_constraintTop_toBottomOf="#id/dialog_content"
tools:text="Dismiss" />
<Button
android:id="#+id/ok_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#id/dialog_content"
tools:text="Accept" />
</android.support.constraint.ConstraintLayout>
Things that I've tried to no avail:
adding app:layout_constraintStart_toStartOf="parent" to the cancel button causes the buttons to no longer be aligned right, and so that solution is incorrect
constraining the end of the dismiss button to the start of the accept button causes buttons to no longer be aligned right
using layout_width="0dp" for the buttons and using app:layout_constrainedWidth="true" has no effect
Here are two screen shots of what I think you are trying to accomplish.
First, with some short text:
Now with some long text:
I took a few liberties with the layout and introduced a guideline at 33% of the width that the button are constrained to. You didn't specify how much the button could expand horizontally, so I made this assumption.
The XML for this layout follows. I set the width of the buttons to 0dp or match_constraints so their size would adjust. The buttons have also been placed into a packed chain that groups the two buttons together. The horizontal bias is set to 0.5 now, but increasing it will move the group to the right if it starts to creep left on you.
The ConstraintLayout documentation has some good descriptions of these features and how to use them.
<android.support.constraint.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.33" />
<TextView
android:id="#+id/dialog_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/dialog_text_margin"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Dialog title" />
<Button
android:id="#+id/cancel_btn"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toStartOf="#+id/ok_btn"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toEndOf="#+id/guideline"
app:layout_constraintTop_toBottomOf="#+id/dialog_title"
tools:text="Dismiss" />
<Button
android:id="#+id/ok_btn"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="#+id/cancel_btn"
app:layout_constraintTop_toTopOf="#+id/cancel_btn"
tools:text="Accept" />

Button overlapping EditText when keyboard is open

I have the following ConstraintLayout in my Android application:
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white">
<ImageView
android:id="#+id/image_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/icon"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
/>
<TextView
android:id="#+id/instructions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/spacing_large"
android:text="#string/instruction"
app:layout_constraintTop_toBottomOf="#id/support_ic"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
/>
<Button
android:id="#+id/call_button"
android:layout_marginTop="#dimen/spacing_large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#null"
android:text="#string/phone"
android:textSize="18sp"
android:textColor="#drawable/button"
app:layout_constraintTop_toBottomOf="#+id/instructions"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
/>
<EditText
android:id="#+id/message_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:lines="8"
android:hint="#string/support_message_hint"
android:textColorHint="#color/text_hint"
android:inputType="textCapSentences|textMultiLine"
android:background="#color/background_gray"
android:padding="#dimen/spacing_small"
android:textColor="#color/black"
app:layout_constraintBottom_toTopOf="#+id/send_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:gravity="top|left"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintVertical_weight="1"
/>
<Button
android:id="#+id/send_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/support_send"
android:background="#color/button_blue"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</android.support.constraint.ConstraintLayout>
When I open the keyboard, the view adjusts and the bottom two widgets (the button and the editText) move with the keyboard. My problem however, is that whenever this happens, the #id/call_button Button lays on top of the editText. I do not want this. I want the editText to overlay the button when the keyboard is open.
Is there any way to make the editText take precedent when overlapping other widgets in this scenario? I tried adding editText.bringToFront() in my onCreate method, but that didn't do anything.
Also, I am trying to avoid nesting the bottom two widgets (the button and the editText) inside of their own layout. I want them all to remain in the same ConstraintLayout. Thank you for the help ahead of time.
I added android:elevation="4dp" to the editText's xml and it worked.
Material Design guidelines specify that Buttons use elevation in both their pressed (8dp elevation) and upressed (2dp elevation) states. https://material.io/guidelines/material-design/elevation-shadows.html#elevation-shadows-elevation-android
Which view you see when two are stacked on top of each other at the same elevation is dependent on the ordering of those views in your layout (e.g. why you expected the views written later to overlay the views written earlier), but elevation takes precedence over this.
As you've found, you can add elevation to your other views to make them "higher" than your button, but this is a bit ugly and might have some unwanted side-effects. I think a better choice would be to set the manifest attribute android:windowSoftInputMode="adjustPan" on your activity. This will cause your activity's view to slide up when the keyboard opens, rather than resizing.

Categories

Resources