I want to achieve this (ribbon over a CardView):
And here's the snippet of my solution:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/testId"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/ribbonParentId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left|top"
android:layout_marginBottom="15dp"
android:background="#drawable/green_ribbon" >
<android.support.v7.widget.AppCompatTextView
android:id="#+id/ribbonId"
style="#style/RibbonStyle"
android:text="#string/ribbon_text" />
</LinearLayout>
<android.support.v7.widget.CardView
android:id="#+id/historicalWeightCardViewId"
style="#style/MyCardViewStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="18dp" >
... Other elements
</android.support.v7.widget.CardView>
And in the RecycleView adapter I bring the ribbon to front by calling.
itemView.findViewById(R.id.ribbonParent2Id).bringToFront();
My solution is working in most devices I tested except Nexus 5 (Android 5.1.1), where ribbon is still (partially) behind the cardview. I'm using AppCompat and targeting >v4.0.
What is the proper way of putting a view over a cardview? Is there another way of achieving the same thing? Why my solution doesn't work for some cases?
How can I make green ribbon to start from the left edge of the screen? Currently there still is a space between screed edge and start of the ribbon.
It is caused by elevation, because CardView on android 21 use true elevation and your LinearLayout has 0 elevation so it is behind the CardView.
To solve this problem, you have 2 options
set android:elevation to your LinearLayout, e.g. android:elevation="10px"
wrap your CardView with a FrameLayout like below
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:id="#+id/historicalWeightCardViewId"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginTop="18dp" >
</android.support.v7.widget.CardView>
</FrameLayout>
<LinearLayout
android:id="#+id/ribbonParentId"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_gravity="left|top"
android:layout_marginBottom="15dp"
android:background="#android:color/holo_red_dark">
<android.support.v7.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/ribbonId"
android:text="abc" />
</LinearLayout>
Related
In my code below, I have a white view with an elevation of 8dp. The blue button has an elevation of 10dp so in theory it should show. However, it doesn't. It only shows the part in which it is not directly over the white view. I know it's something to with the elevation however I do not know exactly what. I have sussed out that it's fine when the white view is =<2, but as soon as I set it higher, the problem occurs.
Here is my code:
<?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">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:layout_width="match_parent"
android:layout_height="#dimen/login_background"
android:background="#color/colorPrimary" />
<View
android:id="#+id/view"
android:layout_width="#dimen/login_container_width"
android:layout_height="#dimen/login_container_height"
android:layout_centerHorizontal="true"
android:layout_marginTop="#dimen/login_container_margin_top"
android:background="#drawable/login_container"
android:elevation="8dp">
</View>
<Button
android:id="#+id/button"
android:layout_width="190dp"
android:layout_height="50dp"
android:layout_marginBottom="52dp"
android:background="#drawable/login_button"
android:elevation="10dp"
android:text="LOGIN"
android:textColor="#color/white"
android:textSize="20sp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
</LinearLayout>
The following reflects this Stack Overflow question and the accepted answer.
Let's consider what you start off with. I don't have access to all your dimensions, etc. to make the following look exactly like your example but the basis is there. Below is the base layout. You can see that the button lies beneath the view even though the view has an elevation of 8dp and the button has an elevation of 10dp.
<LinearLayout 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="match_parent"
android:background="#color/colorPrimaryDark">
<View
android:id="#+id/view"
android:layout_width="match_parent"
android:layout_height="175dp"
android:layout_alignBottom="#+id/button"
android:layout_alignParentEnd="true"
android:layout_alignParentStart="true"
android:layout_margin="30dp"
android:background="#android:color/white"
android:elevation="8dp">
</View>
<Button
android:id="#+id/button"
android:layout_width="190dp"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="52dp"
android:background="#mipmap/ic_launcher"
android:elevation="10dp"
android:text="LOGIN"
android:textColor="#color/white"
android:textSize="20sp" />
</RelativeLayout>
</LinearLayout>
So, why is this? It is because android:elevation="10dp" in the XML for the button isn't really defining the elevation. Instead, the button's elevation is controlled by a "StateListAnimator" that controls the android:elevation and android:translationZ properties." (See accepted answer to above-referenced question.)
If you don't really care for what the StateListAnimator is doing for your layout, you can simply eliminate it by adding android:stateListAnimator="#null" to the XML for the button. Here is what the layout looks like after adding this code. (Please note that the designer may not show the changes immediately; Android Studio 3.0 Beta 6 didn't). So, you may need to refresh the layout to see the changes.
As you can see, the button is now above the view as we expect.
If you do care what StateListAnimator does for you, you will need to define your own and enter its name instead of #null in the XML statement changed above. The answer I reference above has the StateListAnimator that Android presumably uses, so you can take that as a basis and change the elevation to what you prefer. I haven't tried this, but it should work.
Layout with shadow
I would like to create same shadow and layout as shown in above figure i tried http://inloop.github.io/shadow4android/ but i am not able to clear those 9 patch lines on top and left side of image
Using Material design, this can be done elegantly using elevation:
<TextView
android:id="#+id/myview"
...
android:elevation="2dp"
android:background="#drawable/myrect" />
https://developer.android.com/training/material/shadows-clipping.html
I will suggest you to use Cardview for this.
like below you can show shadow.
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:padding="#dimen/_5sdp"
app:cardElevation="#dimen/_3sdp"
android:layout_marginTop="#dimen/_10sdp"
app:cardBackgroundColor="#color/white"
app:cardCornerRadius="#dimen/_3sdp"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:text="Profile"
android:drawableLeft="#drawable/profile"
android:drawablePadding="#dimen/_5sdp"
android:id="#+id/frag_setting_profile_tv"
android:padding="#dimen/_10sdp"
style="#style/textview_primary"
android:layout_height="match_parent" />
</android.support.v7.widget.CardView>
app:cardElevation property show below shadow view .
Sorry if the title isn't really clear but I don't know what the effect is called. It will get clear with some screenshots..
I have a homescreen with a search container on the top and a list of houses at the bottom.
The whole homescreen is a scrollview and when the 'Panden in uw buurt' textview passes the top off the screen I want it to be fixed.
start screen:
what I want to achieve if user scrolls down:
This is my xml layout:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="#+id/quick_search_view"
layout="#layout/view_quick_search"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/quick_search_view"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="#drawable/house1" />
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="#drawable/house2" />
</LinearLayout>
<View
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_below="#+id/quick_search_view"
android:layout_marginLeft="7dp"
android:background="#drawable/triangle_indicator"
android:rotation="180" />
</RelativeLayout>
follow the steps-
Exclude 'Panden in uw buurt' from your "#layout/view_quick_search".[Header also if its not actionBar]
Put it below "#+id/quick_search_view".
set/add Listeners for Scrolling.
OnScroll set visibility of "#+id/quick_search_view" gone/visible OR set
translate animation.
I found the solution : here
The stickyfragment and observableScrollView did the job!
I've got an activity layout specified in an XML file - activity_intro.xml - and I'm trying to create another one that is similar but slightly different - that's going to be activity_instructions.xml.
The Intro activity has a 9patch image at the bottom of the screen that is supposed to stay there and only adjust to different widths of the screens.
The Instructions activity is supposed to contain the same image but above 2 more buttons - all three of these views need to be always located at the bottom of the screen.
activity_intro.xml:
<?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" >
<ScrollView
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:background="#drawable/home_background" >
<LinearLayout
style="#style/Activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ImageView
android:id="#+id/introAnimationImageView"
android:layout_width="152dip"
android:layout_height="176dip"
android:layout_gravity="center_horizontal"
android:contentDescription="#string/intro_animation_content_description"
android:src="#drawable/animation_intro01" />
<TextView
android:id="#+id/introTextViewTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/intro_title"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/introTextViewSubtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/intro_subtitle"
android:textAppearance="?android:attr/textAppearanceMedium" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="#+id/introButtonLoginSignup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="#string/intro_button_label_login_signup" />
<Button
android:id="#+id/introButtonInstructions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_alignRight="#+id/introButtonLoginSignup"
android:text="#string/intro_button_label_instructions" />
<Button
android:id="#+id/introButtonReportAnonymously"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/introButtonLoginSignup"
android:layout_centerHorizontal="true"
android:text="#string/intro_button_label_report_anonymously" />
</RelativeLayout>
</LinearLayout>
</ScrollView>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:contentDescription="#null"
android:scaleType="fitXY"
android:src="#drawable/footer_cityscape" />
</LinearLayout>
Result:
Since I've got working code for Intro, I wanted to make Instructions follow its example but the layout_weight property isn't behaving as expected. First of all, I was only trying to put in the 2 buttons and leave out the image:
<?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" >
<ScrollView
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="0.1"
android:background="#drawable/home_background" >
<LinearLayout
style="#style/Activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/instructionsTextViewTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/instructions_title_1"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold" />
<ImageView
android:id="#+id/instructionsImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="#string/instructions_image_content_description"
android:src="#drawable/forms" />
<TextView
android:id="#+id/instructionsTextViewDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/instructions_description_1"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
</ScrollView>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" >
<Button
android:id="#+id/instructionsButtonPrevious"
style="#style/ButtonPrevious"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:text="#string/instructions_button_label_previous" />
<Button
android:id="#+id/instructionsButtonNext"
style="#style/ButtonNext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:text="#string/instructions_button_label_next" />
</RelativeLayout>
</LinearLayout>
This only worked when I set the layout_weight of the bottom RelativeLayout to 1 (instead of 0) and for the ScrollView 0.1 (instead of 1). If I used the original values the RelativeLayout would take up all the screen. Could anyone explain to me why that is?
I also tried googling the issue and noticed people would suggest to set layout_height to 0dip which I tried but it also didn't work as expected.
Secondly, I tried adding the already mentioned ImageView to the bottom RelativeLayout. This, however, basically displays only the ImageView and not the buttons - or one of the buttons is on top of the image (hiding it). Why is that? Don't I specifically set the buttons to be placed below it?
What should the code look like in order for it to be doing what I expect it?
Further explanation:
Below are images that should help indicate what exactly I want to achieve. The green bits are the ScrollViews - I added them because Android devices tend to have diverse screen sizes. Their purpose is to present the content properly independently of the screen size, i.e. if the screen is small, the user will be able to scroll that part to read the entire text and view the image.
The red bit on the left (Intro) shows the ImageView that is supposed to always be at the bottom of the screen; it'll always be there, visible, and it's the green bit above it that will be movable.
If you take a look at the red bit on the right (Instructions), there's a Next button that's covering the image with the lorry/truck that was visible in the Intro screenshot. Now that's wrong - there should be 2 buttons BELOW the image, as seen on the last screenshot (the 2 blue rectangles).
I have a TextView which I want to pin at the bottom of a landscape activity that is using LinearLayout with vertically arranged elements.
I have set android:gravity="bottom" on the text view, but it still likes to be just below the last element of the LinearLayout exactly what I do not want it to do.
Any suggestions?
You will have to expand one of your upper views to fill the remaining space by setting android:layout_weight="1" on it. This will push your last view down to the bottom.
Here is a brief sketch of what I mean:
<LinearLayout android:orientation="vertical">
<View/>
<View android:layout_weight="1"/>
<View/>
<View android:id="#+id/bottom"/>
</LinearLayout>
where each of the child view heights is "wrap_content" and everything else is "fill_parent".
Update: I still get upvotes on this question, which is still the accepted answer and which I think I answered poorly. In the spirit of making sure the best info is out there, I have decided to update this answer.
In modern Android I would use ConstraintLayout to do this. It is more performant and straightforward.
<ConstraintLayout>
<View
android:id="#+id/view1"
...other attributes elided... />
<View
android:id="#id/view2"
app:layout_constraintTop_toBottomOf="#id/view1" />
...other attributes elided... />
...etc for other views that should be aligned top to bottom...
<TextView
app:layout_constraintBottom_toBottomOf="parent" />
If you don't want to use a ConstraintLayout, using a LinearLayout with an expanding view is a straightforward and great way to handle taking up the extra space (see the answer by #Matthew Wills). If you don't want to expand the background of any of the Views above the bottom view, you can add an invisible View to take up the space.
The answer I originally gave works but is inefficient. Inefficiency may not be a big deal for a single top level layout, but it would be a terrible implementation in a ListView or RecyclerView, and there just isn't any reason to do it since there are better ways to do it that are roughly the same level of effort and complexity if not simpler.
Take the TextView out of the LinearLayout, then put the LinearLayout and the TextView inside a RelativeLayout. Add the attribute android:layout_alignParentBottom="true" to the TextView. With all the namespace and other attributes except for the above attribute elided:
<RelativeLayout>
<LinearLayout>
<!-- All your other elements in here -->
</LinearLayout>
<TextView
android:layout_alignParentBottom="true" />
</RelativeLayout>
I think it will be perfect solution:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- Other views -->
<Space
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<!-- Target view below -->
<View
android:layout_width="match_parent"
android:layout_height="wrap_content">
</LinearLayout>
Step 1 : Create two view inside a linear layout
Step 2 : First view must set to android:layout_weight="1"
Step 3 : Second view will automatically putted downwards
<LinearLayout
android:id="#+id/botton_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<View
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<Button
android:id="#+id/btn_health_advice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
You should put the parameter gravity to bottom not in the textview but in the Linear Layout. Like this:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="bottom|end">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Something"/>
</LinearLayout>
You can also use
android:layout_gravity="bottom"
for your textview
DO LIKE THIS
<LinearLayout
android:id="#+id/LinearLayouts02"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="bottom|end">
<TextView
android:id="#+id/texts1"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_weight="2"
android:text="#string/forgotpass"
android:padding="7dp"
android:gravity="bottom|center_horizontal"
android:paddingLeft="10dp"
android:layout_marginBottom="30dp"
android:bottomLeftRadius="10dp"
android:bottomRightRadius="50dp"
android:fontFamily="sans-serif-condensed"
android:textColor="#color/colorAccent"
android:textStyle="bold"
android:textSize="16sp"
android:topLeftRadius="10dp"
android:topRightRadius="10dp"
/>
</LinearLayout>
try this
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:orientation="vertical" >
<TextView
android:id="#+id/textViewProfileName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>