I would like to put a shadow on the right side of a fragment inside a viewpager. An example would be the Shazam app, when you swipe the first view across, it has a shadow to the right.
I attempted to do this by creating a 10dp wide gradient the height of my main fragment (which is a relative layout, and setting it to align to the right of the parent, with a -10dp margin on the right. Unfortunately, nothing is drawn once it's moved outside of the fragments relative layout.
The xml for my main fragment is:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/homeFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/home_background"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/homeShadow"
android:layout_width="10dp"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_marginRight="-10dp"
android:background="#drawable/home_shadow"
android:orientation="vertical" >
</LinearLayout>
</RelativeLayout>
I have searched and can not find anything that says whether I can draw outside of the fragments relative layout or not. I found a clipChildren setting which I attempted on the relative layout and elsewhere to no effect.
Is there a way to have something drawn outside the boundaries of the fragments relativelayout?
If not, any suggestions on getting a shadow drawn to the right of a fragment as you swipe it across the screen?
Related
I have a relative layout with a margin and a floating action button that is nested inside this layout.
<?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:layout_margin="#dimen/activityMargin"
android:orientation="vertical"
android:clipToPadding="false">
<android.support.design.widget.FloatingActionButton
android:id="#+id/id_FABSave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
app:srcCompat="#drawable/ic_save_white"/>
</RelativeLayout>
As you can see in the attached picture, the drop shadow of the floating action button is cut off. How does this happen and how can it be fixed?
In your relative layout tag, use padding instead of margin and add the attribute android:clipToPadding="false" to avoid the shadows being cut.
<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:padding="#dimen/activityMargin"
android:clipToPadding="false">
Problem is that shadows are cut by bounds of view or view group. To tackle this issue you have to use:
android:clipChildren
Defines whether a child is limited to draw inside of its bounds or not.
android:clipToPadding
Defines whether the ViewGroup will clip its children and resize (but not clip) any EdgeEffect to its padding, if padding is not zero.
Problem is that you have to set this to many views in xml if you want to render shadow. I resolved this issue on level of themes.xml. In my top level theme I just set:
<item name="android:clipChildren">false</item>
<item name="android:clipToPadding">false</item>
Then, if there is space on screen, shadow is rendered. I hope it won't break something else.
EDIT: It breaks some views. For example CameraPreview will set black background to whole screen. Be careful with scrolling views, etc.
I'm trying to figure out the best parent layout to build this interface with.
Here are some additional information/ requirements:
A) The ViewGroup that contains everything.
B) MapView that fills the available vertical spacing
C) RecylcerView that scrolls a list of item horizontally. Has a fixed height (i.e. 200 dp)
D) FloatingActionButton that sits on top of View B + C. It's anchor on the top right of View C.
I tried a lot of different options for View A, but they don’t seem to work.
LinearLayout: LinearLayout has no notion of a Z index so
FloatActionButton get's cut off.
RelativeLayout: RelativeLayout has no notion of "fill in remaining vertical space" so the MapView's height is not dynamic and needs to be fixed
FrameLayout: Same issue as RelativeLayout.
Also, when the user taps on the FloatingActionButton, I'll need to inject fragment modal into this activity, so it'll be place over this current layout.
Any help will be greatly appreciated. Thank you so much!!!
probably something like -
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="#+id/layout_a"
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:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/layout_c"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_alignParentBottom="true"/>
<com.google.android.gms.maps.MapView
android:id="#+id/layout_b"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#id/layout_c"/>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab_d"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="200dp"
android:layout_marginRight="16dp"
app:fabSize="normal"/>
</RelativeLayout>
I haven't developed for Android in more than a year and I'm a bit rusty with it. I'm trying to setup a kinda simple UI: a bottom bar at the bottom of the screen and a fragment above it (but without filling the whole height). Something like this:
I thought this would be quite simple, but after a while struggling with it I can't manage to make it work without some "hacks".
The bottom bar is also implemented as a Fragment. This is my XML:
<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:orientation="vertical" >
<fragment
android:id="#+id/bottomBar"
android:name="com.mytestpackage.BottomBarFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
<FrameLayout
android:id="#+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#id/bottomBar"
android:layout_alignParentBottom="true" />
</RelativeLayout>
The Fragment in fragmentContainer is dynamically loaded from code. With the code paste above, fragmentContainer is aligned bottom but it's not above bottom bar, they're overlapped. If I remove the alignParentBottom from fragmentContainer, then it's placed in top of the screen.
Like I said, I found two "hacks" to solve it but I don't like them much:
1- Set a padding/margin bottom to fragmentContainer.
2- Use a filler empty layout on top of the screen and set fragmentContainer to be below that one.
Is there any way to achieve the layout I want without having to use some tricks like the ones I said?
Thanks!
Add to the relative layout:
android:gravity="bottom"
Ah, and android:orientation="vertical" is meaningless for RelativeLayout
A simpler solution would be to use a LinearLayout with vertical orientation and gravity bottom instead of the RelativeLayout.
SOLVED: The layout_height parameter was set to Match_parent in the buttonbar definition. Changed to wrap_content.
I'm currently working on a new App which has a series of buttons at the top of the main screen. the "buttonBar" XML defines a linearLayout and is later nested within another linearLayout.
The buttons appear fine and work however if I then put a text view beneath the include statement the text does not appear. I think that it is actually appearing behind the buttons. I assumed that because it was within a parent linearLayout that it would appear after the included (nested) nested layout.
please could someone explain why this is not occurring and point me in the right direction to solve it.
much appreciated,
M
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<include layout="#layout/buttonheader"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:id="#+id/textView1"
android:textColor="#ffffff">
</TextView>
</LinearLayout>
Set height and width of the included layout buttonheader
SO that you can see this included layout in your layout
Margins in group layouts do not seem to work.
For example,
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_margin="40dip"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="I'm a button" />
</LinearLayout>
should display a button with 40p margins on all sides. However, it has 80p margins on the right and bottom.
Am I doing something wrong?
Is this a bug?
A workaround would be to use gravity, but this only works with even margins.
BTW, there is a similar question posted here but has not been answered.
android:padding="40dp" on the LinearLayout or android:layout_margin="40dp" on the Button will give you the effect you want. Padding defines the space between a views edges and its content, layout margin defines extra space on the sides of a view.
The problem is actually the way FrameLayout interprets margins. setContentView() attaches your "main" layout to a FrameLayout, which is the actual root of the view hierarchy (you can see that with Hierarchy Viewer) and is offered to you by the phone.
Margins are managed by the parent layout, so in this case that main FrameLayout. I don't know if it's a feature or a bug, but that's how this layout interprets margins.
So well, the solution was already posted while I was typing: use padding instead.
if you need set margin for a layout, simply wrap it with another linear or relative layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout android:layout_margin="40dip"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="I'm a button" />
</LinearLayout>
</LinearLayout>
Wrapping the Linear Layout with another layout is the best strategy.