I have view layout using a CardView that is supposed to look like this
And it looks fine on devices running Android 9 and above (API 28+). However, on anything older it looks to be broken:
The layout is as follows:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView 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="125dp"
android:layout_height="40dp"
android:layout_marginEnd="8dp"
app:cardCornerRadius="165dp"
app:cardElevation="8dp"
app:contentPadding="8dp"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal"
>
<android.support.v7.widget.CardView
android:layout_width="24dp"
android:layout_height="24dp"
app:cardCornerRadius="16dp"
app:cardElevation="0dp"
>
<ImageView
android:id="#+id/tab_icon"
android:layout_width="26dp"
android:layout_height="26dp"
android:layout_gravity="center"
tools:src="#tools:sample/avatars"
/>
</android.support.v7.widget.CardView>
<TextView
android:id="#+id/tab_title"
android:layout_width="60dp"
android:layout_height="match_parent"
android:layout_marginStart="4dp"
android:layout_marginEnd="6dp"
android:ellipsize="end"
android:gravity="center_vertical"
android:maxLines="1"
android:paddingBottom="2dp"
android:textColor="#android:color/black"
android:textSize="14sp"
tools:text="Sample User"
/>
<ImageView
android:id="#+id/tab_close"
android:layout_width="14dp"
android:layout_height="14dp"
android:src="#drawable/btn_close"
/>
</LinearLayout>
</android.support.v7.widget.CardView>
I'm using the 'com.android.support:cardview-v7:28.0.0' dependency.
It seems the issue was the value set for cardCornerRadius. Setting it to 20dp got me the desired border-radius without breaking the layout.
You can use SDP - a scalable size unit
dependencies {
implementation 'com.intuit.sdp:sdp-android:1.0.6'
}
FYI
<android.support.v7.widget.CardView
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="125dp"
android:layout_height="40dp"
android:layout_marginEnd="8dp"
app:cardCornerRadius="165dp"
app:cardElevation="8dp"
app:contentPadding="8dp"
>
Leads to inconsistency. Different layouts end up hard-coding different font sizes and margins, making the app appear less polished.
TRY
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
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="#dimen/_125sdp"
android:layout_height="#dimen/_35sdp"
android:layout_marginEnd="#dimen/_5sdp"
app:cardCornerRadius="#dimen/_150sdp"
app:cardElevation="#dimen/_5sdp"
app:contentPadding="#dimen/_5sdp"
>
.........
<android.support.v7.widget.CardView
android:layout_width="#dimen/_22sdp"
android:layout_height="#dimen/_22sdp"
app:cardCornerRadius="#dimen/_12sdp"
app:cardElevation="0dp"
>
NOTE
Switch to AndroidX.
AndroidX replaces the original support library APIs with packages in
the androidx namespace. Only the package and Maven artifact names
changed; class, method, and field names did not change.
Like
<androidx.cardview.widget.CardView
Related
first of all I am new to Android-Development.
My question is regards alignment of different views in Android Studio/Development.
Specifically the properly height-alignment of an icon and text.
Icon-Text-Alignment
As you can see, I tried to align the text with the icon. However the result looks slightly different in the emulator.
Here is my .xml-file:
<?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"
tools:context=".DashboardActivity">
<TextView
android:id="#+id/textView3"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginStart="32dp"
android:layout_marginTop="32dp"
android:layout_marginBottom="352dp"
android:fontFamily="#font/poppins_medium"
android:text="Dashboard"
android:textAlignment="viewStart"
android:textColor="#color/colorText"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/imageView10"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.04" />
<ImageView
android:id="#+id/imageView10"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginEnd="32dp"
app:layout_constraintBottom_toBottomOf="#+id/textView3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/textView3"
app:layout_constraintTop_toTopOf="#+id/textView3"
app:srcCompat="#drawable/ic_settings_black_24dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
My questions are:
1. How can i fix the alignment of these two views?
2. Why is the result in the emulator different?
3. Is there a best-practice to align views properly?
<?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"
tools:context=".DashboardActivity">
<TextView
android:id="#+id/textView3"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginStart="32dp"
android:layout_marginTop="32dp"
android:layout_marginBottom="352dp"
android:fontFamily="#font/poppins_medium"
android:text="Dashboard"
android:textAlignment="viewStart"
android:textColor="#color/colorText"
android:textSize="30sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toStartOf="#+id/imageView10" />
<ImageView
android:id="#id/imageView10"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginEnd="32dp"
app:srcCompat="#drawable/ic_settings_black_24dp"
app:layout_constraintTop_toTopOf="#id/textView3"
app:layout_constraintBottom_toBottomOf="#id/textView3"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
You can do this simply by using a custom toolbar and adding a menu to it.
Try using Custom toolbar :
<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="match_parent"
android:orientation="vertical"
tools:context=".terminalShortActivity">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#4EACE2"
app:popupTheme="#style/ThemeOverlay.AppCompat">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
style="#style/TextAppearance.AppCompat.Widget.ActionBar.Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Terminal Shortcuts"
android:textColor="#FFFFFF" />
</LinearLayout>
</androidx.appcompat.widget.Toolbar>
</LinearLayout>
So I dig into the alignment issue a little further and came up with a few "solutions". Generally speaking and to answer my questions the "Custom Toolbar" is not the right solution to align the views.
The problem lies in the padding of fonts. Android take the whole view to align views and not as assumed the "text" only. Therefore the alignment looks off.
Different paddings/fonts
Poppinsmedium: without padding
Poppinsmedium: with padding; normal state
Android-Font: with padding; normal state
The bottom-padding can be eliminated with the following code:
android:includeFontPadding="false"
Or check this thread for more in-depth knowledge of the issues of font-padding.
To align views, now I am using Chain-Constraints and do it without padding. It looks like the best-way to align views, especially Text-Views. However, I have to say that despite the deleting of the bottom padding it is necessary to adjust the alignment a littlebit with the vertical-bias.
For reference:
constraintlayout.com
Android-Doc: constrain-chain
My current constraint layout gives me even spacing in the layout preview and also on my api 28 + 29 emulators, it displays even spacing. However when I use my real api 19 device to test the spacing, it gives me uneven spacing (check picture below). What's the cause for the uneven spacing and how can I fix it so that it's even for all devices?
I ended up using guidelines and margins and that fixed the issue:
<?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="200dp"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:id="#+id/fragevent_threephotolayout_image1"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:layout_marginStart="16dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="#id/guideline"
android:layout_marginEnd="4dp"/>
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.65"/>
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5"/>
<ImageView
android:id="#+id/fragevent_threephotolayout_image2"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#id/guideline2"
android:layout_marginEnd="16dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toRightOf="#+id/guideline"
app:layout_constraintTop_toTopOf="#id/fragevent_threephotolayout_image1"
android:layout_marginBottom="4dp"
android:layout_marginStart="4dp"/>
<ImageView
android:id="#+id/fragevent_threephotolayout_image3"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginEnd="16dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toRightOf="#id/guideline"
app:layout_constraintBottom_toBottomOf="#id/fragevent_threephotolayout_image1"
app:layout_constraintTop_toBottomOf="#id/guideline2"
android:layout_marginLeft="4dp"
android:layout_marginTop="4dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
you must check some ways for it:
Don't use percents for width and height
Use margin left and right instead of start and end
Use padding instead of margin
As you see in your images, margin top or bot between 2 images of right side don't have an issue, so you can do what happen between them on others.
different devices have a different screen size that's why uneven space occurs, with
help of SDP master we can rectify this issues, below i gave sdp master link kindly add
this to yous "res" folder
kindly go to the link copy dimen value file inside the res folder and paste to
you res folder, and use this dimen values instead of manually given size(like 10 dp
12 dp)
You can use with Linear Layout as Below
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="200dp"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:orientation="horizontal"
android:weightSum="1">
<ImageView
android:id="#+id/fragevent_threephotolayout_image1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="#mipmap/ic_launcher"
android:layout_marginRight="6dp"
android:layout_weight="0.4"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="2"
android:layout_marginLeft="5dp"
android:layout_weight="0.6">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:layout_marginBottom="5dp"
android:src="#mipmap/ic_launcher"
android:layout_weight="1"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:layout_marginTop="5dp"
android:src="#mipmap/ic_launcher"
android:layout_weight="1"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
This is my custom view (custom_view.xml): *Note that I define 3 margins on the CardView.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView 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="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:background="#color/white"
android:orientation="vertical"
app:cardCornerRadius="4dp"
app:cardElevation="0dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="16dp"
android:background="#color/white">
<ImageView
android:id="#+id/left_image"
android:layout_width="64dp"
android:layout_height="40dp"
android:layout_marginTop="5dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="#id/left_image"
android:layout_toLeftOf="#+id/right_image"
android:layout_toRightOf="#id/left_image"
android:layout_toStartOf="#id/right_image"
android:orientation="vertical">
<com.ringapp.ui.view.TypefaceTextView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<com.ringapp.ui.view.TypefaceTextView
android:id="#+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
<ImageView
android:id="#id/right_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_marginTop="5dp"
android:src="#drawable/icon_md_gray_arrow" />
</RelativeLayout>
</android.support.v7.widget.CardView>
I add the custom layout on the following xml (container.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"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:orientation="vertical">
<com.ringapp.ui.view.CustomView
android:id="#+id/test2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
app:description="edsc"
app:title="title" />
<com.ringapp.ui.view.CustomView
android:id="#+id/test"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
app:description="asdasd"
app:title="asdasdasd" />
</LinearLayout>
The problem is that the margins that I defined on the custom_view.xml doesn't appear on the container.xml layout. Why is this happening? If I paste the code of custom_view.xml directly on container.xml the margins appears.
Instead of
<com.ringapp.ui.view.CustomView
android:id="#+id/test2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Try this:
<include layout="#layout/custom_view" android:id="#+id/test2/>
I believe when you use the code you have, android tries to over right some of your view's properties, especially when you explicitly overwrite the layout width / height. Try the above line of code in place of yours. Also, no need to overwrite the layout width / height if you're just going to wrap content, as the layout dimensions will be brought over from your custom_view.
Edit: To clarify, your code would probably even work if you took out the layout width / height overwrites. But you should use includes when bringing other XML layouts into a different XML layout. The way you 'included' your view is fine, but should probably be used fro when you write custom view classes that extend android 'View'.
The following code is rendering with undesired view boundaries on devices with android versions pre lollipop:
<android.support.v7.widget.CardView
android:id="#+id/cardView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:cardBackgroundColor="#color/transparent"
app:cardCornerRadius="#dimen/card_corner_radius"
app:cardElevation="0dp"
app:cardUseCompatPadding="true">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.makeramen.roundedimageview.RoundedImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:adjustViewBounds="true"
app:srcCompat="#{radio.radioLogo}"
app:riv_corner_radius="#dimen/card_corner_radius"
android:alpha="#{radio.playing}"/>
<LinearLayout
android:id="#+id/overlay_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="#color/transparent"
android:gravity="center"
android:orientation="vertical"
android:visibility="#{radio.recording?View.VISIBLE:View.GONE}">
<TextView
android:id="#+id/recording_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/transparent"
android:text="#string/recording"
android:textAppearance="?android:textAppearanceLarge"
android:textColor="#color/white" />
<TextView
android:id="#+id/recording_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/transparent"
android:text="#{radio.recordingElapsedTime}"
android:textAppearance="?android:textAppearanceLarge"
android:textColor="#color/white" />
</LinearLayout>
</FrameLayout>
</android.support.v7.widget.CardView>
ps: I tried card_view:cardPreventCornerOverlap="false"
and it doesn't solve my problem.
lollipop render
Pre lollipop render
Thanks in advance for any interest in helping.
I found a solution that worked for me and I wanted to post it in case any one else came across this situation.
I set the maximum elevation to 0dp and now rendering is perfect on API level 16 too.
<android.support.v7.widget.CardView
android:id="#+id/cardView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:cardBackgroundColor="#color/transparent"
app:cardCornerRadius="#dimen/card_corner_radius"
app:cardElevation="0dp"
app:cardMaxElevation="0dp"
app:cardUseCompatPadding="true">
If you need to keep elevation on v21 devices and remove cardview weird boundaries on pre21 devices - create values-v21/dimens.xml with:
<dimen name="card_elevation">2dp</dimen>
And values/dimens.xml with:
<dimen name="card_elevation">0dp</dimen>
Then add property to CardView:
app:cardElevation="#dimen/card_elevation"
I tried using the Percent Support Library as detailed here and here. It works nicely in the Android Studio designer, but when I try to install my app into my phone, nothing is showing but an empty screen. What might the problem be?
Edit:
I've added the following lines in my gradle file dependencies.
compile 'com.android.support:appcompat-v7:23.0.0'
compile 'com.android.support:support-v4:23.0.0'
compile 'com.android.support:design:23.0.0'
compile 'com.android.support:percent:23.0.0'
And here is my fragment layout:
<RelativeLayout 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" tools:context="org.atpms.fairfare.ReportFragment"
android:id="#+id/fragment_report" >
<ProgressBar android:id="#+id/report_progress" style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content" android:layout_height="match_parent"
android:layout_marginBottom="8dp" android:visibility="gone"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
<RelativeLayout
android:id="#+id/report_form"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/reportButton"
android:gravity="center">
<ImageView
android:id="#+id/report_background"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:src="#drawable/report"
android:adjustViewBounds="true" />
<android.support.percent.PercentRelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignTop="#+id/report_background"
android:layout_alignBottom="#+id/report_background"
android:layout_alignLeft="#+id/report_background"
android:layout_alignStart="#+id/report_background"
android:layout_alignRight="#+id/report_background"
android:layout_alignEnd="#+id/report_background">
<EditText
android:id="#+id/plateNumberField"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_widthPercent="58%"
app:layout_heightPercent="14%"
app:layout_marginTopPercent="20%"
app:layout_marginLeftPercent="36%"
android:textColor="#color/plate_number"
android:background="#null"
android:gravity="center"
android:textSize="24sp"
tools:ignore="TextFields"/>
<ImageView
android:id="#+id/meterPictureButton"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_widthPercent="12%"
app:layout_heightPercent="15.5%"
app:layout_marginTopPercent="38%"
app:layout_marginLeftPercent="84%"
android:src="#drawable/camera" />
<ImageView
android:id="#+id/meterPicture"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_widthPercent="97.2%"
app:layout_heightPercent="42%"
app:layout_marginTopPercent="55.8%"
app:layout_marginLeftPercent="1.6%"
android:scaleType="fitXY"
tools:ignore="ContentDescription" />
</android.support.percent.PercentRelativeLayout>
</RelativeLayout>
<Button
android:id="#+id/reportButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/report"
android:layout_alignParentBottom="true"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:background="#drawable/report_button"
android:textSize="20sp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:textColor="#color/button_text"
android:textAllCaps="false"
android:gravity="center"
tools:ignore="UnusedAttribute" />
</RelativeLayout>
</RelativeLayout>
Update:
Ok, I've inflated the exact same layout from an Activity using setContentView, and it works fine. It seems that the problem only arises when I try to use the PercentRelativeLayout in a Fragment layout. It appears that LayoutInflater isn't correctly inflating a layout with PercentRelativeLayout elements, but I'm still unsure and continuing to investigate.
It's not a very nice solution, but I solved this problem by just getting rid of the fragment, and making it a full-blown activity.