Draw outside ScrollView - android

I'm using TwoDScrollView, but for sake of simplicity let's say I have a very simple layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rootLayout"
android:background="#android:color/transparent"
android:clickable="true"
android:paddingTop="?attr/actionBarSize"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" >
<View
android:id="#+id/topOverview"
android:background="#cc000000"
android:layout_above="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ScrollView
android:id="#+id/scrollView"
android:fillViewport="true"
android:layout_centerVertical="true"
android:clipChildren="false"
android:layout_width="match_parent"
android:layout_height="100dp">
<ImageView
android:adjustViewBounds="true"
android:src="#drawable/my_photo"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</ScrollView>
<View
android:id="#+id/bottomOverview"
android:background="#cc000000"
android:layout_below="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
So I have a scrollView with ImageView inside (which is bigger ofc). Now I want to also draw what's outside scrollview. I also want to cover this area with 80% alpha-black views (using layout_above and layout_below) as you can see in xml. Thanks to that user will be able see area outside scrollview, but it will look different outside. I've tried clipChildren, but I doesn't work. It's still clipped anyway.
I've achieved this very easily on iOS by just one line of code (plus view above and below scrollView with correct constraints):
scrollView.clipsToBounds = false
It looks like that:
So how can I achieve it on Android? Canvas is too much for this I think. I've also came up with an idea that I can duplicate ImageView outside ScrollView, place it below it and move it as scroll moves. But is there an easier method?

Related

Android: Cover underlying elevated views, and making a flat button

Sorry for the elementary question but I can't find the solution:
When covering a button with a layout without elevation, it emerges over the layout because a button has a depth (negative depth, it points at the viewer).
So, if you have a
<FrameLayout... >
<Button.../>
<FrameLayout
id="#+id/fragmentsContainerOrAnything"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#C00F"
android:clickable="true"
android:focusable="true"
>
</FrameLayout>
</FrameLayout>
The button would show through the FrameLayout.... In this case, literally "out of the blue" because the button has depth and so it emerges over the layout, even though the layout is placed "upon" the button.
The question is:
How do I make the FrameLayout cover the underlying Button without fiddling with its elevation.
How do I make the button flat? Of course I can just set it back to the origins and call it "TextView". But is there a nicer way?
Thanks
Add your button inside FrameLayout
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#C00F"
android:clickable="true"
android:focusable="true" />
</FrameLayout>

scroll ListView inside a LinearLayout which is wrapped in ScrollView

I have an activity which should be scrollable, therefore i surrounded it with a ScrollView. I have two listViews in there, which i do not want to be as large as it would be necessary to display all items.
It would be nice if i could set a maxHeight property, so that in case there are only 2 items no empty space would be present, but if there are 50 items i would only want to see like 5 of them at a time. Unfortunately there is no such property, so i decided to just set the height to a fixed number. Any advice how to do that more properly would be much appreciated.
However the main problem is that, when i try to scroll one of the listViews the whole LinearLayout scrolls down. (I can avoid this if i use another finger to 'hold' the LinearLayout in place while scrolling the list, but that certainly not a solution.)
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_settings"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="app.ballmaschine.pages.SettingsPage">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Some other stuff here -->
<TextView
android:text="Eine Maschine"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="#android:style/TextAppearance.DeviceDefault.Medium"
android:layout_marginTop="8dp" />
<ListView
android:layout_width="match_parent"
android:id="#+id/lvCalibsM1"
android:layout_height="200dp" />
<TextView
android:text="Zwei Maschinen"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="#android:style/TextAppearance.DeviceDefault.Medium"
android:layout_marginTop="8dp" />
<ListView
android:layout_width="match_parent"
android:layout_height="200dp"
android:id="#+id/lvCalibsM2"/>
<!-- Some more stuff here -->
</LinearLayout>
Add this to the ListView
android:scrollbars = "none"
and this in Java Code
listView.setNestedScrollingEnabled(false)
In these cases always try NestedScrollView and also add this line to it
app:layout_behavior="#string/appbar_scrolling_view_behavior"

Trying to size correctly android layouts

I'm struggling on a layout management so I decided to ask here.
I would like to get 3 layouts working in a certain way.
I have 3 views vertically dispatched into a RelativeLayout (let's call them VTop, VMiddle and VBottom).
VBottom is a Button, I want him to stay aligned with the bottom of the screen and to never move or get resized (actually working).
VMiddle is a scroll view. I want this ScrollView to take all possible place between the bottom button (VBottom) and the top most layout (VTop) but never having it height inferior to an specific size.
I would like to have VTop (A linear layout containing some TextViews and other stuffs) wrapping all of its content as long as VMiddle doesn't get smaller that its minimum size.
Actually the code I have is almost working but when I Inflate too much content into VMiddle, it keeps growing towards the top of the screen and VTop completely disappear. I want VMiddle to stay at it minimum size if VTop doesn't have enough space to wrap his content.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/relativeLayout1">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/linearLayout1" <!-- VTop -->
android:layout_above="#+id/eventDetail_RateLayout"
android:layout_alignParentTop="true"
android:layout_margin="10sp"> <!-- LOT OF VIEWS, NEED TO BE WRAPPED AS MUCH AS POSSIBLE -->
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="100px"
android:id="#+id/eventDetail_RateLayout" <!-- Not visible for now, you can ignore it -->
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:minWidth="25px"
android:minHeight="25px"
android:background="#color/common_google_signin_btn_text_light_default"
android:layout_above="#+id/eventDetail_CommentScrollView"
android:visibility="gone" />
<ScrollView
android:id="#+id/eventDetail_CommentScrollView" <!-- VMiddle -->
android:background="#4D4A58"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/eventDetail_commentButton">
<LinearLayout
android:orientation="vertical"
android:minWidth="25px"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/eventDetail_CommentLayout" />
</ScrollView>
<Button
android:text="commenter"
android:id="#+id/eventDetail_commentButton" <!-- VMiddle, this one is doing ok -->
android:background="#666"
android:textColor="#f8f8f8"
android:layout_width="match_parent"
android:layout_height="30sp"
android:layout_alignParentBottom="true" />
</RelativeLayout>
Thanks for your answers.
Try the following code for the ScrollView -
<ScrollView
android:id="#+id/eventDetail_CommentScrollView" <!-- VMiddle -->
android:background="#4D4A58"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_below="#id/linearLayout1"
android:layout_weight="1"
android:layout_above="#+id/eventDetail_commentButton">
...
</ScrollView>
Use this, however the kind of UI you want can be easily achieved using Linear layout and using weight and weightSum properties.. also rename ID of the layout and views accordingly
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/topLayout"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_alignParentTop="true"
android:background="#70AD47"
android:orientation="vertical">
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/btnBottom"
android:layout_below="#+id/topLayout"
android:background="#ED7D31"
android:minHeight="400dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
<Button
android:id="#+id/btnBottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#4472C4"
android:text="Bottom button" />
</RelativeLayout>
1. Add attribute android:layout_below="#id/linearLayout1" and android:layout_above="#id/eventDetail_commentButton" to ScrollView to keep it at middle position.
2. Use ScrollView and its child LinearLayout height android:layout_width="match_parent" although its not necessary.
No matter how big the top and bottom layout, middle scrollview will always fill the middle free spaces. It will never change the height of top and bottom layout.
Here is the working layout:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/relativeLayout1">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/linearLayout1"
android:layout_alignParentTop="true"
android:layout_margin="10sp">
</LinearLayout>
<Button
android:text="commenter"
android:id="#+id/eventDetail_commentButton"
android:background="#666"
android:textColor="#f8f8f8"
android:layout_width="match_parent"
android:layout_height="30sp"
android:layout_alignParentBottom="true" />
<ScrollView
android:id="#+id/eventDetail_CommentScrollView"
android:background="#4D4A58"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/linearLayout1"
android:layout_above="#id/eventDetail_commentButton">
<LinearLayout
android:orientation="vertical"
android:minWidth="25px"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/eventDetail_CommentLayout" />
</ScrollView>
</RelativeLayout>
Hope this will help~
Use android:layout_below="#+id/linearlayout1"
in eventDetail_RateLayout
I'm pretty sure none of the given answers achieve what you're looking for. What you wanna do is not simple because it involves a circular dependency: you basically want your vTop view to wrap and fill any space left by your vMiddle view (android:layout_above="#id/vMiddle") and at the same time you want your vMiddle view to wrap and fill any space left by your vTop view (android:layout_below="#id/vTop").
The only solution I can imagine would be to check and set the view sizes programmatically, I don't think this is doable only by rearranging your layout.
I finally achieved to get something close to what I wanted. I combined layout_above and below and fixed the size of VTop by making the Huge TextView scrollable. I have now VTop and VBottom at a fixed size and VMiddle taking the rest of the place at the center.
Thanks for your fast answers :)

Filling a view that has `wrap_content` as height

So I'm using a RecyclerView, with some cards. I want to get an overlay on the card when it's clicked, which should cover all contents, but not change the size of the view. Hardcoding the size of the card is not possible, since the contents have different dimensions.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!--contents and stuff-->
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000" />
</RelativeLayout>
The example above is pretty much what I'm trying to achieve, but this obviously won't work, since the View's and RelativeLayout's height refer to each other.
How can I make the View cover everything inside the RelativeLayout?
Edit
Clarification: The issue I'm having has nothing to do with clicking, covering or anything like that. I'm having issues with just covering the RelativeLayout.
Credits go to thunder413 for suggesting the FrameLayout in the comments.
Basically, all I had to do was encapsulating the RelativeLayout (as shown in my question) in a FrameLayout, and move the View out of the RelativeLayout into the FrameLayout
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!--contents and stuff-->
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000" />
</FrameLayout>

How to adjustPan only one view?

I have a scrolling background that doesnt work correctly when the software keyboard is on the screen,
so I've put android:windowSoftInputMode="adjustPan" in the manifest.
This prevents the scrolling background from breaking down, but it also prevents the rest of the screen from resizing so filling out the input fields becomes anoying.
Is there a way to apply android:windowSoftInputMode="adjustPan" only on the horizontalscrollview?
<HorizontalScrollView
android:id="#+id/scrollingbackground"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent">
<ImageView
android:id="#+id/bg_image"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#drawable/background_loop"
android:adjustViewBounds="true"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#drawable/background_loop"
android:adjustViewBounds="true"/>
</LinearLayout>
</HorizontalScrollView>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
//the input fields
I've just put an extra linearlayout at the bottom of the scrollview and sized it programmaticly 50% of the height of the screen. So when I use android:windowSoftInputMode="adjustPan" now I can still scroll down enough to see all the elements in the scrollview.
Not the cleanest solution IMO, but it'll do for now.

Categories

Resources