Making list item sizes consistant - android

I have an issue where the sizes of list items vary depending on if the phone is 21+ or not.
How can it make it so devices that are pre-21 have the same spacing between items?
List:
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:clipToPadding="false"
android:divider="#color/transparent"
android:dividerHeight="0dp"
android:listSelector="#drawable/list_selector_transparent"
android:paddingBottom="1dp"
android:paddingTop="3dp"
android:scrollbarAlwaysDrawVerticalTrack="false"
android:smoothScrollbar="true"
android:visibility="visible" />
Item:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="false">
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="3.5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="1.5dp"
card_view:cardCornerRadius="3dp"
card_view:cardElevation="1.7dp">
</android.support.v7.widget.CardView>
</LinearLayout>
If you know a solution I would be very grateful. Thanks
Here is a picture of what I mean:
Picture of the issue

This is happening due to how shadows are drawn on different API levels. In 21+, the shadow is drawn outside the view itself, whereas on older levels it has to be drawn inside the view's bounds. The support library adds padding to the CardView on these older API levels in order to have room to draw the shadow.
You can add this attribute to your <android.support.v7.widget.CardView> tag to make them behave the same, regardless of API level:
app:cardUseCompatPadding="true"
From the documentation:
Before Lollipop, CardView adds padding to its content and draws shadows to that area.
and
Alternatively, If you want CardView to add inner padding on platforms Lollipop and after as well, you can call setUseCompatPadding(boolean) and pass true.

Related

ExoPlayer: remove redundant spaces between playback buttons and timeline row

I have custom ExoPlayer control bar. It takes quite a lot of space and I want to make it a bit narrower.
Here is what I want to remove/narrower (highlighted with red):
As you see I managed to remove some spaces already by playing around with paddingTop, layout_marginTop, layout_height parameters (it used to be even larger).
But it is not enough, it still takes a lot of space.
Question: How to narrower empty areas marked on the picture?
Here is what my custom exo_player_control_view.xml looks like (removed most of the elements for the purpose of simplicity):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#CC000000"
android:layoutDirection="ltr"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<ImageButton
android:id="#id/exo_play"
style="#style/ExoMediaButton.Play" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<com.google.android.exoplayer2.ui.DefaultTimeBar
android:id="#id/exo_progress"
android:layout_width="0dp"
android:layout_height="18dp"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>
Note: I fully understand that by narrowing those areas I might make the control panel less usable. It is ok. I want at least to have an ability to change them and test how it works.
First thing you should do is define height and width of ImageButton to wrap_content so it can behave properly.
The padding above play button is due to lack of height and width
Now the main thing. if you want to remove padding of TimeBar you need to set app:touch_target_height this height increasing the padding between your play button and time bar.This height is the touch area for inner bar, you can use this to increase the user touch area without increasing bar size and this will look like padding. make size 0dp and padding will be gone
well there is one more padding that is image padding..i pulled this play button image from exoPlayer library and i found this image also have some default padding. if you want to remove that padding also then change this image.
this play button image have size in square and as you can see the play button is a triangle, so they added padding to make this image in center and square.
Extra:- you can also define the size of inner bar by using app:bar_height but remember app:bar_height cannot cross app:touch_target_height. even if you define it more then app:touch_target_height you will see no effect. you can increase these size and see more by yourself below is the final result that i got (also edited and removed image padding). the button touching the bar(button background is null time bar background is #9e0c26)
<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">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#CC000000"
android:layoutDirection="ltr"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<ImageButton
android:id="#id/exo_play"
style="#style/ExoMediaButton.Play"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<com.google.android.exoplayer2.ui.DefaultTimeBar
android:id="#id/exo_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:bar_height="2dp"
app:touch_target_height="2dp" />
</LinearLayout>
</LinearLayout>

What can I do to shrink the space between my CardViews within a RecyclerView?

So I'm learning app development for Android, and I'm a bit stuck. I'm trying to make a RecyclerView with CardViews, but there is just too much space between CardViews. This is what it looks like.
I'm going for more of the look that the Google app has with the feed.
This is more like what I'm shooting for.
Anyways, I've searched and searched on this website for a solution to my problem and nothing seems to be working for me. I'm hoping that someone can give me something that will actually work.
Here's the xml for my cardview:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="10dp">
<android.support.v7.widget.CardView
android:id="#+id/cv"
android:layout_width="match_parent"
android:layout_height="120dp"
app:cardCornerRadius="10dp"
app:cardElevation="5dp"
app:cardUseCompatPadding="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
<TextView
android:id="#+id/note_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="false"
android:layout_below="#+id/event_time"
android:textSize="24sp" />
<TextView
android:id="#+id/note_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/note_title" />
</RelativeLayout>
</android.support.v7.widget.CardView>
The top and bottom spaces is caused by your padding
android:paddingBottom="10dp", remove this or reduce it
Decrease the PadingBotom of the root constraintLayout
you could put 3 or 4 dp instead of 10dp.
android:paddingBottom="10dp"
Also I do not know if the copy of your code was not good ... the constraintLayout must close at the end:
after this:
</android.support.v7.widget.CardView>
you must have this:
</android.support.constraint.ConstraintLayout>
From the documentation for CardView:
Before Lollipop, CardView adds padding to its content and draws shadows to that area. ... If you want CardView to add inner padding on platforms Lollipop and after as well, you can call setUseCompatPadding(boolean) and pass true.
In your layout, you have this attribute on your CardView tag:
app:cardUseCompatPadding="true"
This does the same thing as the method in the quote above.
As a result, even if you had zero margin on all sides of your cards, users would still see space in between them because of the inner padding behavior. If you want really tight spacing, you'll have to remove this attribute (though of course you'll still get the larger spacing pre-Lollipop).

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.

How to make a CardView have a clickable&checkable effect, and how to make it dark themed?

Background
Before CardView was introduced, I made some selectors on my app to mimic cards, and let the user also choose which theme to use for the app (some prefer a dark theme) :
The problem
I wanted to make it look&work more natively, so I tried using CardView.
Sadly, I fail to understand how to set the CardView have a clickable&checkable effect (the native one of each platform, maybe with a different color), and also have the ability to set it a dark theme.
The questions
How do I make a CardView have a clickable effect? On Lollipop it's a ripple effect. On previous ones it's full color changing within the boundaries of the CardView. I'd also like to customize the color of the clickable effect, and let it also be checkable.
How do I make a dark-theme CardView ?
You have to use the CardView.Dark style for the dark-theme CardView. You can also just use the colors as mentioned in the 11th and 12th comments of this bug.
This was requested on google at https://code.google.com/p/android/issues/detail?id=194497
But after release of Android Support Library, revision 23.2.1 (March 2016) This functionality is added.
Add dark theme for CardView
update Support Library to Android Support Library to 23.2.1
Example:
Add below attribute to your cardview
style="#style/CardView.Dark"
as shown here
<?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="wrap_content">
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/cards"
style="#style/CardView.Dark"
android:layout_width="match_parent"
android:layout_height="match_parent"
card_view:cardCornerRadius="4dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:padding="10dp">
<TextView
android:id="#+id/usersName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:paddingTop="10dp"
android:text="Username"
android:textColor="#FFFFFF" />
<TextView
android:id="#+id/others"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/usersName"
android:layout_centerVertical="true"
android:paddingTop="10dp"
android:text="Others"
android:textColor="#FFFFFF" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>

Android layout unwanted padding

So i am having this layout file (below). As you can see, there is no padding or margin. The dimen.xml files also dont have any padding/margin. Finally, i do NOT change the layout programmatically at all.
<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"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/root"
android:padding="0dp"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:id="#+id/toolbarholder"
android:layout_alignParentTop="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardElevation="16dp"
app:cardCornerRadius="0dp">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
</android.support.v7.widget.Toolbar>
</android.support.v7.widget.CardView>
<ListView
android:layout_below="#+id/toolbarholder"
android:layout_above="#+id/cardroot"
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:divider="#null"
android:dividerHeight="0dp"
android:layout_marginTop="0dp" />
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/cardroot"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#color/transparentblack"
app:cardCornerRadius="0dp"
app:cardElevation="16dp"
android:layout_alignParentBottom="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/buttonholder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:weightSum="3">
<ImageView
android:id="#+id/previous"
android:layout_width="35dp"
android:layout_height="35dp"
android:src="#drawable/previous"
android:layout_weight="1"/>
<ImageView
android:id="#+id/play"
android:layout_width="35dp"
android:layout_height="35dp"
android:src="#drawable/play"
android:layout_weight="1"/>
<ImageView
android:id="#+id/next"
android:layout_width="35dp"
android:layout_height="35dp"
android:src="#drawable/next"
android:layout_weight="1"/>
</LinearLayout>
<SeekBar
android:id="#+id/seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/buttonholder" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>
Below are two screenshots from two different devices.
Lenovo k3 Note:
HTC Desire 550:
Any ideas what might be the cause of this?
Ok Guys... thanks for your input. Turns out the "Cardview Documentation" mentions that:
Before L, CardView adds padding to its content and draws shadows to that area. This padding amount is equal to maxCardElevation + (1 - cos45) * cornerRadius on the sides and maxCardElevation * 1.5 + (1 - cos45) * cornerRadius on top and bottom.
This means that the Margin is intended behavior to draw the shadows and simulate elevation. One possible solution for everyone having the same problem, is use the attribute cardUseCompatPadding in your layout as follows:
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardElevation="0dp"
app:cardUseCompatPadding="true">
</android.support.v7.widget.CardView>
This will cause your layout to be "rendered" the same way (the pre-Lollipop way //sad ) in every device regardless of the API. At least this way we can fix a common layout that works for all versions given this restriction.
Hope it helps.
UPDATE: If you decide to go for "app:cardUseCompatPadding=true" here is another advice. Use negative layout_margin, to balance-out the unwanted padding from the compat library. Example below:
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="-10dp"
app:cardCornerRadius="0dp"
app:cardUseCompatPadding="true"
app:cardElevation="8dp">
</android.support.v7.widget.CardView>
This way your layout can get rid of unwanted padding AND look the same pre-lollipop and after lollipop.
Hope this helps even more. :)
The possible reason is that well HTC mobiles especially have different types of internal layout files. So Lenovo Nexus and SAMSUNG may be functioning properly but thanks to HTC's difference in these situations it is a big problem for lot of developers. If you really want it to work on HTC as well I recommend the best way to make it work on HTC is to create your own xml files which resemble the android support ones. I recommend if you want to proceed you try to get a hang of the native xml file of the android card one and use the same. Now HTC has to use your custom ones which are equal to all other android ones but not in HTC. What I am saying is that now It will work properly on all devices. But be warned, this just might turn out to be long and painful if you can't get a hang of the native xml file. If you do it'll probably then become a breeze for you. I hope you understand me.
Have you tried setting the height for your linear layout or set it to match parent instead? It doesn't seem like there is extra padding but rather that your items in the list are not the same height as the image even gets Cut off.

Categories

Resources