Same elevation of views looks different for top and bottom views - android

Recently, I stunned with a problem. On my android phone elements of the list or scroll views with the same elevation have different shadows related to their positioning. For example, views on the top of the screen have a small light shadow, whenever views on the bottom of the screen have more dark and strong shadow. Here is a screenshot from Google Keep application:
So, I thought that this is because of exactly Google Keep application. Maybe guys from Google decided to do that trick with shadows for their application. Thus, I created a sample application.
My layout:
<?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="match_parent"
android:orientation="vertical">
<TextView
style="#style/AppButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:text="Test"/>
<TextView
style="#style/AppButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:text="Test"/>
<TextView
style="#style/AppButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:text="Test"/>
<TextView
style="#style/AppButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:text="Test"/>
<TextView
style="#style/AppButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:text="Test"/>
<TextView
style="#style/AppButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:text="Test"/>
<TextView
style="#style/AppButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:text="Test"/>
</LinearLayout>
My styles:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
<style name="AppButton">
<item name="android:background">#color/colorAccent</item>
<item name="android:elevation">4dp</item>
<item name="android:gravity">center</item>
<item name="android:padding">16dp</item>
<item name="android:textColor">#android:color/white</item>
</style>
</resources>
And the output is:
As you see, we have the same effect (top view has a small shadow, bottom view have a big shadow). So my questions are:
What I did wrong?
How can I achieve the same shadow for all views (not different by their positions)?
Also, I haven't found any explanations in docs, so where I can read about that phenomenon?
Does it happen on all devices or only on specific?
P.S.: I have Nexus 5X, Android 7.1.2.
UPD:
An important mention that from Android Studio Preview Window everything is fine. Every view has the same shadow as other. But on a real device, you can see the difference.

Shadows generated by Elevation API are positioned in 3D space, which means that the look of each shadow is affected not only by its elevation value, but also by shadow caster's x and y position on screen. It's pretty much like in the real world - objects beneath a light source cast shorter shadows than objects further away.
Take a closer look at the first image you posted. Shadows are longer on left edges of the left cards and on right edges of the right cards than on the edges at the horizontal center.
Ad. 1. Nothing. It just works that way.
Ad. 2. It's not possible using Elevation API. You can draw shadows by yourself.
Ad. 3. Don't know, sorry.
Ad. 4. All devices.
Ad. UPD. Shadows in the editor are static, so there's no effect you're observing.

Related

Views are overlapping

In my android application, I have a RelativeLayout which contains some Fragments. However, this layout does not scale to different screen sizes. Consider this screenshot when the screensize is 5.2" diagonally, 1080x1920 resolution 420dpi: (Desirable output)
When I change the phone to a 5.0", 1080x1920 resolution xxhdpi, I get this display:
As you can see the buttons on the two right-hand columns are overlapping, which is the problem I am asking about.
Here is the main activity XML file, which contains the various fragments
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:style="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:layout_margin="8dp">
<!--This is the box appearing at the top of the layout-->
<TextView
android:id="#+id/window"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:background="#drawable/window_border"
android:fontFamily="monospace"
android:minLines="1"
android:text=""
android:textAppearance="#style/TextAppearance.AppCompat.Large"
android:textIsSelectable="true"/>
<!--This is the first row of buttons, there are 4 of them-->
<fragment
android:id="#+id/screenOps"
android:name="net.magnistudio.deskcalculator.ScreenOps"
android:layout_width="wrap_content"
android:layout_alignEnd="#+id/digits"
android:layout_height="wrap_content"
android:layout_below="#+id/window"
tools:layout="#layout/layout_screen_ops"/>
<!--This is the 3x3 rectangle appearing directly below the screenOps
frag -->
<fragment
android:id="#+id/digits"
android:name="net.magnistudio.deskcalculator.Digits"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:layout="#layout/layout_digits"
android:layout_alignBottom="#+id/basicOps"/>
<!--This is the rightmost fragment-->
<fragment
android:id="#+id/basicOps"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:name="net.magnistudio.deskcalculator.BasicOps"
tools:layout="#layout/layout_basic_ops"
android:layout_alignParentEnd="true"
android:layout_below="#+id/window"/>
<!--Lower fragment, it is 6x4-->
<fragment
android:id="#+id/scientific"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="net.magnistudio.deskcalculator.Scientific"
tools:layout="#layout/layout_scientific"
android:layout_below="#+id/digits"/>
</RelativeLayout>
Each button has this style
<style name="calcBtnAppearance">
<item name="android:textSize">14sp</item>
<item name="android:textColor">#color/calcBtn</item>
<item name="android:textStyle">normal</item>
<item name="android:textAllCaps">false</item>
<item name="android:layout_width">0dp</item>
</style>
I think one solution would be to adjust programatically the sizes of the layouts based on the size of the current phone, but maybe that is just sweeping some other problem (of the layout itself) under the rug?
Also, each button is located within a LinearLayout, which is inside of the LinearLayout for the fragment. Consider this sample excerpt from a fragment layout file:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="3">
<Button
android:id="#+id/dig7"
style="#style/calcBtnAppearance"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text=""/>
more buttons
</LinearLayout>
<LinearLayout>
In the RelativeLayout the children are arranged according to their relative form to each other. As far as I remember, the RelativeLayout does not scale the contained elements if the resolution or the screen size changes.
Maybe you should take a look here:
[https://stackoverflow.com/a/21381065/6908102
][1]
A possible solution:
To adjust the size of the buttons to the respective resolutions, create a separate "values" folder for each resolution. (See also picture 2 marked blue).
- Picture 2 -
Then create a new "dimens.xml" file in each of these folders.
As an example:
res/values/dimens.xml:
<resources>
<!-- ButtonSize -->
<dimen name="dimenButtonHeight">15dp</dimen>
<dimen name="dimenButtonWidth">25dp</dimen>
</resources>
res/values-xxhdpi/dimens.xml:
<resources>
<!-- ButtonSize -->
<dimen name="dimenButtonHeight">10dp</dimen>
<dimen name="dimenButtonWidth">20dp</dimen>
</resources>
Of course, you still have to adjust the size specifications to your layouts.
res/values/style.xml:
In your Style.xml file you have to add the following lines:
<style name="calcBtnAppearance">
<item name="android:textSize">14sp</item>
<item name="android:textColor">#color/calcBtn</item>
<item name="android:textStyle">normal</item>
<item name="android:textAllCaps">false</item>
<item name="android:layout_height">#dimen/dimenButtonHeight</item>
<item name="android:layout_width">#dimen/dimenButtonWidth</item>
</style>
Maybe that will solve your problem. Otherwise, you can, as shown in Figure 2 well, synonymous for each Resolution create a separate "layout" folder. Then copy the files from the standard layout folder into the newly created folder and adjust them or you can also position the items in a different order. But is a little more work.

Theme.AppCompat.Dialog theme creates empty (dead) space

In my application, I am using an Activity with the theme "Theme.AppCompat.Dialog" to display it as a dialog. That works out well, however, the dialog fills the entire screen height, leaving a lot of space empty. To illustrate my issue, here is a picture of opening the dialog (on an unusually high resolution to demonstrate the issue better):
The higher the resolution, the greater this space.
Here is a code snippet:
<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="wrap_content"
android:orientation="vertical"
xmlns:tools="http://schemas.android.com/tools">
<!--This is the yellow box-->
<LinearLayout
android:id="#+id/dialog_button_bar"
android:layout_alignParentBottom="true"
style="?android:buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content">
[Buttons...]
</LinearLayout>
<!--This is the red box-->
<ScrollView
android:layout_above="#id/dialog_button_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
[LinearLayout containing rows...]
</ScrollView>
If I remove the android:layout_alignParentBottom="true" and the android:layout_above="#id/dialog_button_bar" attributes, the whole layout jumps to the top and now the empty space is below my layout.
What am I doing wrong? :(
It seems like this is some kind of intended behavior. The standard Android app installation dialog seems to behave the same way (leaving a lot of blank space between the permission part and the buttons) so I guess I'll keep it this way...
Create new Style in styles.xml
<style name="MyCustomDialog" parent="Base.Theme.AppCompat.Light.Dialog">
<item name="android:windowNoTitle">true</item>
<item name="windowActionBar">false</item>
</style>
Now in AndroidManifest.xml, add android:theme="#style/MyCustomDialog" to your Dialog activity.

TableLayout not shown properly

I'm having trouble with the layout of my Android app.
The graphical preview editor shows me an image like (and this is how I want it to look like):
I am using a table layout that looks like this:
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:shrinkColumns="*"
android:stretchColumns="*" >
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ffffff"
android:padding="5dp" >
<TextView
style="#style/leftColumn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Branche" />
<TextView
android:id="#+id/textViewBranche"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/rightColumn"
android:text="Branche"
/>
</TableRow>
</TableLayout>
styles.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<!-- ... -->
<style name="leftColumn">
<item name="android:background">#2B60DE</item>
<item name="android:textColor">#ffffff</item>
</style>
<style name="rightColumn">
<item name="android:background">#C0C0C0</item>
<item name="android:textColor">#ffffff</item>
</style>
</resources>
If I run my app it looks like this:
As you can see only one text view is displayed. I would like the table layout to have 2 columns (just like in the preview). The first one (blue) indicating what I am displaying and the second (grey) the information provided by my adapter. However I only see the provided information of my adapter (in this case "sonstige (others)". So basically I only see the right column.
I have no idea why I can't see the content of the first text view (respectively the first row).
I played around with some properties like layout_width and layout_height but it doesn't change.
I'm running this app on my S3.
Any help would greatly be appreciated.
Cheers

Mask of the components of android when you click

I'd like to get this effect in android, I tried setting the background of the layout but without success, it would be like putting a mask on the elements of layout. An example of these is when you click a button on google play, which look like this:
when you click it puts a mask on blue button.
Could someone help me?
Thank you.
I did the following, I created the layout with image and text.
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/android" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="APP" />
</LinearLayout>
and create framelayout
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/bg_default"
android:clickable="true">
<include
android:layout_gravity="center_vertical"
layout="#layout/test1" />
</FrameLayout>
but only the background is changed, the images and text are not placed the mask. Am I doing something wrong?
The first thing that comes to my mind to implement this kind of affect is:
1. Create a layout(Linear/Relative) with the Icon and the text (android icon and APPS text in your example.)
2. Set it to wrap-content for both dimensions.
3. Place this layout inside FrameLayout.
4. Inside this FrameLayout add a button and set it to match-parent, for this button create a selector like this and apply it as it background:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- pressed -->
<item android:state_pressed="true"
android:drawable="#drawable/botton_shape_pressed" />
<!-- focused -->
<item android:state_focused="true"
android:drawable="#drawable/botton_shape_selected" />
<!-- default -->
<item android:drawable="#drawable/botton_shape_released" />
5. For the pressed texture create a semi-transparent blue texture. for the other two states apply a full transparent texture. this will result in the mask affect you looking for.

Removing blank space next to App Logo (ActionBar Sherlock)

Can someone tell me how to eliminate the padding to the left of the app logo???
Here's what im talking about http://s9.postimage.org/ksxjpx1e7/Untitled.png
You can easily reproduce this even with ABS Demos, by adding to AndroidManifest.xml
android:logo="#drawable/icon"
I even tried editing abs__action_bar_home.xml directly but somehow that damned padding is still there.
<view xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
class="com.actionbarsherlock.internal.widget.ActionBarView$HomeView"
android:background="#00ff00" >
<ImageView
android:id="#id/abs__home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:padding="0dip"
android:layout_marginLeft="0dip"
android:layout_marginBottom="#dimen/abs__action_bar_icon_vertical_padding"
android:layout_marginRight="8dip"
android:layout_marginTop="#dimen/abs__action_bar_icon_vertical_padding"
android:adjustViewBounds="true"
android:contentDescription="#null"
android:scaleType="fitCenter" />
<ImageView
android:id="#id/abs__up"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|left"
android:layout_marginRight="-8dip"
android:contentDescription="#null"
android:src="?attr/homeAsUpIndicator"
android:visibility="gone"
tools:ignore="ContentDescription" />
</view>
As one of the comments pointed out, the padding is reserved for the up icon. The padding is present even though the up icon is not being displayed (so that the logo doesn't move when you hide/show the up icon). Using action bar (and ActionBarSherlock) there are basically 2 ways how to remove the gap:
1.Remove the up icon
The size of the up icon affects the left padding, if you put there a bigger image than the arrow is, the gap will be bigger. If you remove it the gap will be gone. Beware that removing the up icon might not bring the exact looks you wish. Up icon and logo are partially overlapped (the up icon has negative right margin) so removing the up icon (it actually sets the image to nothing, does not affect the visibility) might cause that the logo is partially hidden behind the left edge of the screen.
To remove the up icon set android:homeAsUpIndicator to #null.
<style name="MyTheme" parent="#style/Theme.Sherlock">
<item name="homeAsUpIndicator">#null</item>
<item name="android:homeAsUpIndicator">#null</item>
</style>
2.Hide home layout and use custom view instead
This way it's more work, but you can affect the result better. You would need to put the icon and the title into the custom view. To hide the home layout and show custom, you have to set android:displayOptions in the action bar style. And then set the proper custom view in the code (you can set it in styles too, but that way it's buggy).
<style name="MyTheme" parent="#style/Theme.Sherlock">
<item name="actionBarStyle">#style/MyActionBarStyle</item>
<item name="android:actionBarStyle">#style/MyActionBarStyle</item>
</style>
<style name="MyActionBarStyle" parent="#style/Widget.Sherlock.ActionBar">
<item name="displayOptions">showCustom</item>
<item name="android:displayOptions">showCustom</item>
</style>

Categories

Resources