Android RecyclerView Spacing Differences between Platforms - android

Disclosure up front, this is a school project.
I've run into a somewhat confusing-to-me layout issue regarding a list of CardViews inside of a RecyclerView, that being that the spacing between cards is non-existent on 5.0, whereas it's fine on 4.4. Here's two screenshots to demonstrate.
Android 4.4 (On Device, Galaxy S4)
Android 5.0.1 (On Device, Nexus 4)
I can see the card corners in the 5.x version, so the cards are there. I have a feeling this is something to do with some XML attribute that I need for running 5.x that the support library fakes automatically on 4.x, but googling has failed me. Here's the relevant XML:
Fragment Layout
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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="com.hinodesoftworks.kanagt.HiraganaListFragment">
<android.support.v7.widget.RecyclerView
android:id="#+id/hira_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</FrameLayout>
Card Layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"
android:layout_width="match_parent"
card_view:cardCornerRadius="4dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/kana_card_display"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="46sp"
android:text="あ"/>
<TextView
android:id="#+id/kana_card_roma"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/kana_card_display"
android:layout_toEndOf="#id/kana_card_display"
android:text="a"
/>
<TextView
android:id="#+id/kana_card_info1_display"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/kana_card_display"
android:layout_toEndOf="#id/kana_card_display"
android:layout_below="#id/kana_card_roma"
android:text="INFO 1"/>
<TextView
android:id="#+id/kana_card_info2_display"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/kana_card_display"
android:layout_toEndOf="#id/kana_card_display"
android:layout_below="#id/kana_card_info1_display"
android:text="INFO 2"/>
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/kana_card_info2_display">
<ImageView
android:id="#+id/kana_card_diagram"
android:layout_width="match_parent"
android:layout_height="100dp"
android:scaleType="fitStart"
android:adjustViewBounds="true"/>
</HorizontalScrollView>
</RelativeLayout>
</android.support.v7.widget.CardView>
I'm really hoping this is a dumb mistake with a simple XML fix; that the support library version is working fine makes me hopeful of that.

If you want the padding on 5.0 follow the same rules as on previous platforms add this attribute to the CardView XML element
app:cardUseCompatPadding="true"
On Lollipop the shadows can be drawn outside of the view bounds. On Kitkat and lower extra space has to be reserved for the shadows. That's why on Lollipop the spacing would have to be set explicitly.

Related

Button getting out of the screen android layout

I got this relativelayout and on the design screen of android studio looks good
enter image description here
<?xml version="1.0" encoding="utf-8"?>
<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"
android:padding="8dp"
tools:context="com.checking.movi.movioperations.CartItems">
<TextView
android:id="#+id/txtcartprod"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Productos seleccionados:"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_cart"
android:layout_width="match_parent"
android:layout_height="649dp"
android:layout_below="#+id/txtcartprod"
/>
<Button
android:id="#+id/btn_placeorder"
style="?android:attr/buttonStyleSmall"
android:layout_below="#+id/recycler_cart"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/mybutton"
android:text="Continuar"
android:textColor="#ffffff" />
</RelativeLayout>
But when I test on the phone the button gets out of the screen if I decrease the size of the recyclerview it does appear can you guys give me a little help with this don't know to tell it to keep the 3 on the same screen
Giving width and height to views in dp's (or pixels) isn't the correct way. Because screen size isn't the same in all devices. Your design tab at Android Studio shows your layout in Pixel phone whose height is greater than your mobile phones. So, you can't see that button in your mobile phone.
I have added one line to your button and deleted another
Added this:
android:layout_alignParentBottom="true"
Deleted this:
android:layout_below="#+id/txtcartprod"
Changed height of RecyclerView to match_parent (to make it depend on screen size):
android:layout_height="match_parent"
And added this line:
android:layout_above= "#id/btn_placeorder"
Final version:
<?xml version="1.0" encoding="utf-8"?>
<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"
android:padding="8dp"
tools:context="com.checking.movi.movioperations.CartItems">
<TextView
android:id="#+id/txtcartprod"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Productos seleccionados:"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_cart"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above= "#id/btn_placeorder"
android:layout_below="#+id/txtcartprod"
/>
<Button
android:id="#+id/btn_placeorder"
style="?android:attr/buttonStyleSmall"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/mybutton"
android:text="Continuar"
android:textColor="#ffffff" />
</RelativeLayout>
I hope you understood all the changes I made. If you have difficulty, feel free to ask in the comments.

Android Activity Layout-Problem on only 1 of 15 test-devices (ImageView)

I'm testing a new activity in our Android app. On all but one devices, everything was fine - except for a Huawei P30 Pro.
The activity is quite simple: it shows an ImageView and a small menu-bar on the bottom. Before the image is set, a ProgressBar (spinning circle) gets shown.
On the Huawei P30 Pro, everything seems to work fine (the ProgressBar appears, the circle is spinning, the ProgressBar disappears), but no Image becomes visible. If you forward the image by pressing the Apply-button in the menuBar, the image gets correctly forwarded, so it actually is available, it just doesn't get shown within the activity.
We tested the same version of the app on several other devices (including Huawei P10, P20, several Samsung-phones and HTC) and everything was ok. But on both Huawei P30 Pro we had available, the same problem appeared.
The layout-code is pretty straightforward:
<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="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:layout_weight="10">
<LinearLayout
android:layout_height="0dp"
android:layout_width="fill_parent"
android:layout_weight="9"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:srcCompat="#tools:sample/avatars"
android:contentDescription="Image preview"/>
<ProgressBar
android:id="#+id/indeterminateBar"
android:indeterminate="true"
android:minWidth="100dp"
android:minHeight="100dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerInParent="true"
/>
</RelativeLayout>
</LinearLayout
android:layout_height="0dp">
<LinearLayout
android:layout_height="0dp"
android:layout_width="fill_parent"
android:layout_weight="1">
<!-- bottom menu-bar-code is here as a TableLayout, which works fine on all devices -->
</LinearLayout>
</LinearLayout>
Maybe the ImageView has a height of 0 so it isn't visible?
I'm puzzled about what it could be, since it's only that particular device...
I checked if the ImageView-drawable does properly get set (imageView.getDrawable() != null) and it looks like it does (it is not null), as well as the visibility-state, which also seems to be fine.
So at this point, I think it is a pure layout-problem.
I highly recommend to switch from LinearLayout to ConstraintLayout. Even though your current layout works on 14 of 15 devices, the height of the bottom menu is always 10% and this will not look good on devices with small heights (have you ever tried your layout in landscape? You will see what I mean).
Once switched to ConstraintLayout, your layout issue on the 15th device should also disappear.
I transformed your layout to use ConstraintLayout to show how it could look like. It also has less layouts inside.
<?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">
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:contentDescription="Image preview"
app:layout_constraintBottom_toTopOf="#id/bottomMenuBar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="#tools:sample/avatars" />
<ProgressBar
android:id="#+id/indeterminateBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:minWidth="100dp"
android:minHeight="100dp"
app:layout_constraintBottom_toTopOf="#+id/bottomMenuBar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="#+id/bottomMenuBar"
android:layout_width="fill_parent"
android:layout_height="50dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<!-- bottom menu-bar-code is here as a TableLayout, which works fine on all devices -->
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Please be aware that for visibility reasons in the layout preview I have added a fixed height for the LinearLayout of the bottom menu. Once you have understood the ConstraintLayout you should also change it for the menu bar. I kept it as a LinearLayout for easier usage with your real layout code.

Android Imagebutton is clipped

I'm having issues with my Activity and an ImageButton inside it. It looks like it is clipping:
This is the XML of the corresponding activity:
<?xml version="1.0" encoding="utf-8"?>
<!-- A RecyclerView with some commonly used attributes -->
<LinearLayout xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:id="#+id/todo_linear_layout"
android:layout_height="match_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="horizontal">
<ImageButton
android:id="#+id/imageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:adjustViewBounds="true"
app:srcCompat="#android:drawable/ic_input_add" />
<EditText
android:id="#+id/edittodo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20px"
android:layout_weight="5"
android:textColor="#android:color/black" />
</LinearLayout>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/todo_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" >
</android.support.v7.widget.RecyclerView>
</LinearLayout>
Additionally the Layout Designer in Android Studio shows the Layout correctly:
Where is the problem here? I already tried to change margin or padding values but the Button is still clipping in the running app on my android device.
I believe that what's happening is that the device you're running your app on doesn't have the #android:drawable/ic_input_add drawable.
I tried running the code you posted, and everything worked for me. However, if I delete the app:srcCompat attribute from the <ImageButton> tag, then I get the same behavior you posted in your first screenshot.
In general, you can't rely on 100% of devices having #android: resources. Some manufacturers remove resources, and others replace the values with nonsense (I've seen #android:color/white come through as gray, for example).
I recommend creating your own drawable (maybe even just manually copying the one from Android and adding it to your project), and referencing that instead.
app:srcCompat="#drawable/your_own_add"
Changing the app:srcCompat to:
android:src="#android:drawable/ic_input_add" did it! So the issue was, that the device didn't find that icon and displayed just something gray.

Android layout renders wrong on Marshmallow

I have just noticed that my Android app layout is broken when displayed on Marshmallow. It is fine on Nexus 5 with Android 5.1.1 but it renders wrong on Nexus 5 and Nexus 5x with the latest version of Android.
The layout consist of little triangle (see red part) aligned to the bottom and above it there is some view (white) that should span all available height of its parent (grey part).
And this is how it renders on Android 5.1.1 (Nexus 5):
while on Android 6.0 (Nexus 5 and Nexus 5X) it is:
The problem looks like the red view doesn't respect its parent alignment (bottom, right) and it makes the white view (which is placed above) to disappear.
The simplified layout of the grey view and its children is (I have added some background colours to see the view bounds):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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:background="#777777">
<View
android:id="#+id/preview_triangle"
android:layout_width="#dimen/preview_triangle_width"
android:layout_height="#dimen/preview_triangle_height"
android:layout_marginRight="#dimen/preview_triangle_margin_right"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:background="#ff0000"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#id/preview_triangle"
android:orientation="horizontal">
<View
android:layout_width="#dimen/preview_margin_horizontal"
android:layout_height="match_parent"/>
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:padding="3dp"
android:background="#drawable/round_rectangle_white_radius_3dp">
<WebView
android:id="#+id/preview_webview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
<FrameLayout
android:id="#+id/preview_close"
android:layout_width="#dimen/preview_margin_horizontal"
android:layout_height="#dimen/preview_margin_horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left|top"
android:layout_marginLeft="#dimen/preview_close_margin_left"
android:src="#drawable/icn_close"
android:contentDescription="#null"/>
</FrameLayout>
</LinearLayout>
</RelativeLayout>
The above layout is placed into separate preview.xml file and then included into main layout like this:
<include
android:id="#+id/fragment_main_loyalty_preview_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_below="#id/fragment_main_loyalty_logo_container"
android:layout_above="#id/fragment_main_loyalty_buttons_container"
android:layout_marginTop="#dimen/fragment_main_loyalty_preview_container_margin_top"
android:layout_marginBottom="#dimen/fragment_main_loyalty_preview_container_margin_bottom"
android:visibility="visible"
layout="#layout/preview"/>
UPDATE
The problem disappears if I replace hosting ScrollView with FrameLayout or so.
I really don't get it why the intermediary parent renders fine and its child is affected by the top most parent :)
And the situation can be reproduced inside Eclipse just by switching target API in the designer.
UPDATE - SIMPLIFIED TEST CASE
Below is the simplest layout I was able to create and reproduce my problem.
Basically the red area should be placed between green and blue ones.
The height of the red area should match the space available between green and blue views as there is another view (see #id/margin_placeholder) which height affects the distance between these two.
Inside the red area I wanted to put white view at the bottom of red area.
And this little white fellow renders different way on Android 6.0:
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
android:id="#+id/top"
android:layout_width="match_parent"
android:layout_height="90dp"
android:layout_marginTop="10dp"
android:background="#007700"/>
<View
android:id="#+id/margin_placeholder"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_below="#id/top"/>
<FrameLayout
android:id="#+id/bottom"
android:layout_width="match_parent"
android:layout_height="90dp"
android:layout_below="#id/margin_placeholder"
android:background="#000077"/>
<RelativeLayout
android:id="#+id/middle"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_below="#id/top"
android:layout_above="#id/bottom"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:background="#770000">
<View
android:layout_width="16dp"
android:layout_height="8dp"
android:layout_marginRight="16dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="#ffffff"/>
</RelativeLayout>
</RelativeLayout>
</ScrollView>
It renders fine if I upgrade targetSdkVersion from 16 to 20.

RelativeLayout background rendering over children

I have this (simplified) layout.-
<RelativeLayout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/background_pattern" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginBottom="#dimen/dimen5"
android:layout_marginTop="#dimen/dimen15"
android:background="#drawable/background_grey" >
<ImageView
android:id="#+id/logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:contentDescription="#string/app_logo"
android:src="#drawable/app_logo" />
</RelativeLayout>
</RelativeLayout>
Which renders good in eclipse layout editor: my app_logo image over background_grey, which is over background_pattern image. But when I run on device, background_grey renders over background_pattern as expected, but also over its child app_logo.
Am I doing something wrong or is this some kind of bug when nesting several layouts with background attribute?
As a workaround, I suppose I can replace background attributes for ImageViews, but I'm pretty sure this may work and I'm missing something obvious.
Notes
Working with the latest ADT and deploying on Nexus 4, 4.2.2
background_grey is a 9-patch image

Categories

Resources