how to add shadow to elements in android using api 29 - android

It looks like there's a lot of information on how to add a shadow to an element like a toolbar or a footer, but none of them seem to work for me. I'm working with api 29 (Android 10) and would like a current practice in adding shadows to elements. Hopefully, today, this means not having to create a separate drawable and then setting that to the background and can be today elegantly achieved by setting elevation and without having to bring in another library. Unfortunately, none of the simpler solutions seem to work for me at the moment. Below is a simplified version of the most recent pattern I tried:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff">
<Toolbar
android:layout_width="match_parent"
android:layout_height="10dp"
android:elevation="4dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="lorem ipsum......"/>
<Button
android:margin="10dp"
android:text="Submit"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>

Related

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.

How to control the drawing order of overlapping elements android activity?

I think I have tried and researched enough, if not everything, yet I just can't get the two icons on the right get displayed in android emulator.
The strange thing is, that they are perfectly visible in design window.
Moreover, with similar/same GUI design, other activities display all my elements just fine.
I already know well, that how views overlap on screen depends on order of elements as I place them in the 'Component Tree' of Android Studio IDE.
Correctly looking design in Android Studio:
Missing icons on the right in emulator:
Moreover, the app in missing the title, which could be caused by an inappropriate parent activity class (its Activity which I changed from AppCompatActivity as I spent quite some time with the AS Designing tool).
How else can I control the order of elements when they overlap?
Or what weird Android concept am I still missing?
Or what has changed since all worked fine for me?
Below is the code XML for app design:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.sbm.bc.smartbooksmobile.ActivityTeacherHwkCheckByTask">
<ImageView
android:id="#+id/Problems"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_gravity="right"
android:layout_marginTop="57dp"
android:elevation="24dp"
android:visibility="visible"
app:srcCompat="#drawable/ic_problems" />
<ImageView
android:id="#+id/Talar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_gravity="right"
android:layout_marginRight="42dp"
android:layout_marginTop="57dp"
android:elevation="24dp"
android:visibility="visible"
app:srcCompat="#drawable/ic_menu_talar" />
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/holo_blue_dark"
android:fitsSystemWindows="true">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="45dp"
android:background="#android:color/holo_blue_bright">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="40dp"
android:visibility="visible">
<LinearLayout
android:id="#+id/ListOfTaskRows"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="24dp"
android:orientation="vertical"
android:visibility="visible">
</LinearLayout>
</ScrollView>
</TableRow>
<TextView
android:id="#+id/Description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="63dp"
android:allowUndo="false"
android:elevation="20dp"
android:ems="10"
android:text="Ăšloha"
android:textAlignment="center"
android:textSize="18sp"
android:visibility="visible" />
</RelativeLayout>
I think you are missing the fact that the RelativeLayout children are drawn in front of each other if they overlap. In your case you have a TableRow whose width is match_parent - it fills the parent's width but as it's added after the image views it's drawn in front of them.
You could constrain the table's width so that it leaves room for the images by setting it's layout_alignEnd attribute to the id of your left-most image, so that the table would end where the image begins.
Well, believe it or not the reason for missing icons was, that I decided to derive my app from plain Activity and not AppCompatActivity as I had it before.
So I have restored my activity to extends AppCompatActivity again and lo and behold.. It works.
This of course also enabled the Activity title again.
As its a pure nonsence (another one) and my time wasted counts already in days (not only this issue, but many other crappy designs and apparent bugs in ADT), I've just decided to abbandon native Android development in the near future and switch back to Xamarin/C# instead. (I've started my Android development from C# Xamarin 4 years ago and only left because of insufficient HW access support at that time).
Howhg !
For user of "Material Design":
Another simple workaround is using "elevation" property of any GUI element.
By increasing this value, one can force to draw this element on foreground over those with lower elevation.
As a bonus (or drawback), you get shading around your elevated GUI element according to how much you have elevated.
I wonder how much this feature prolongs rendering time
Another question is min supported API version. (Did not find it right away..)

Placing Button to Overlapping Two Layouts with Layout Weight with Kitkat and below support

I am trying to place a button overlapping two layouts. The Layouts must have the layout_weight as shown in the image below, I've been struggling on it for a while, .. I succeeded with the below code .. but only for api 22 (lollipop) & 23 (MarshMallow).. Problem occurs in API 19 (Kitkat) & below .. The Lower layout seem to cover the button .. ie, button is half visible from the top.
Please help me to achieve like in image with all android version support ..
TIA !
Code which worked on API 22 & 23 but not in 19 and Below:
<?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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.automovill.automovill.testing">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="1">
<LinearLayout
android:id="#+id/LL1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight=".55"
android:background="#2961a7"
android:orientation="vertical">
</LinearLayout>
<Button
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_marginTop="-25dp"
android:background="#ffd016"
android:padding="10dp"
android:text="TESTING"
android:textColor="#000"
android:textStyle="bold" />
<RelativeLayout
android:id="#+id/LL2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="-25dp"
android:layout_weight=".45"
android:background="#163d6d">
</RelativeLayout>
</LinearLayout>
To be honest, I think you'll have to perform all kinds of crazy gymnastics to get the standard layouts do this. LinearLayout is not the right tool because the expectation is that the elements are all adjacent to each other (you may have been exploiting a bug before).
You can do standard layout gymnastics, or you can go ahead a write your own ViewGroup to manage the layout positions of the child view to conform to your needs. You'll end up having to compute pixels and all that. Probably no way to avoid these manual computations since the usual layout typically expect view adjacency rather than overlap.
Maybe try it with adding the following code to your button's layout:
android:layout_marginBottom="-25dp"
I would try to move the button at the top of the layout file. There is an implicit rule in RelativeLayout about the z ordering of the views. The further down the view the higher is the z value.

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