How to adjustPan only one view? - android

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.

Related

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>

Android Scrollview Won't fill parent space

I have a relative layout fills the entire screen. I want to add a scrollview in the middle of it to wrap a bunch of content so that I can make it pan up when the soft keyboard gets displayed. However, as soon as I wrap it in a scrollview, the bottom most layout stops filling the remainder of the screen.
Here is the XML where I have the ScrollView commented out.
<include
android:id="#+id/top_bar_with_save_button"
layout="#layout/top_bar_with_save_button"/>
<FrameLayout
android:id="#+id/log_entry_title_frame"
android:layout_below="#id/top_bar_with_save_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/log_entry_title_frame"
android:layout_alignParentBottom="true">
<!--
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/log_entry_title_frame"
android:orientation="vertical"
android:background="#f00">
<!-- Lots of stuff in here -->
<EditText
android:id="#+id/log_entry_notes"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp"
android:gravity="top|left"/>
</RelativeLayout>
<!--
</ScrollView>
-->
</LinearLayout>
It looks like this:
But as soon as I remove the comment from the ScrollView it immediately compresses like this:
Why does this happen? I need it to fill the entire space on the screen, and I cannot figure out what is happening. Can anyone tell me how to fix this? Thanks!
You need to add the fillViewport="true" attribute to your ScrollView tag. Or you can add it programmatically with scrollView.setFillViewPort(true);. Otherwise, the ScrollView will wrap to its child's content height.
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
... >
layout_height of scrolling container should be "wrap_content".

Draw outside ScrollView

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?

CardView Scroll behavior when keyboard is up

Our app's main content is a RecylerView of CardView's. For signup we require more than just a username/password to create an account so we decided to make the signup flow out of CardView's to match the user experience once they sign up.
To do that I have a single Activity that animates fragments in from the bottom and existing fragments out the top to emulate scrolling. This fake scrolling occurs when the user enters data and hits next to advance. This works pretty well except for one case. When we have a EditText for input the keyboard comes up and covers the 'next' button on the bottom of the screen.
In our user testing we've noticed a high percentage of users trying to scroll the card up to get to the next button instead of dismissing the keyboard.
I've spent a lot of time unsuccessfully trying to get the CardView to scroll up to reveal the button and I'm out of ideas and looking for new ones.
The signup Activity layout only contains a FrameLayout that I load Fragments into. Each fragment that gets loaded has a CardView for the root layout.
In the manifest I have set the activity's windowsSoftInputMode to adjustResize, adjustPan with little success.
activity_signup.xml
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/signUpContent"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
simplified fragment_enter_code.xml
<android.support.v7.widget.CardView
style="#style/CardViewStyle.SignUp"
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="wrap_content"
app:cardCornerRadius="25dp"
app:cardElevation="2dp"
app:cardUseCompatPadding="true"
app:contentPadding="8dp">
<EditText
android:id="#+id/codeEditText"
style="#style/HintedEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Code"
android:inputType="text"/>
<Button
style="#style/NextButton"
android:id="#+id/nextButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:enabled="false"
android:text="#string/next"/>
</android.support.v7.widget.CardView>
When I tried putting the CardView in a ScrollView the cardview layout (with fillViewport true), I get a scrollbar but the card doesn't scroll and the cardview layout gets messed up.
Does anyone know the windowSoftInputMode's well enough to point me in the right direction? Or is the CardView just not going to scroll outside of a Container that is design to hold them?
It feels like the solution to this is in manipulating the activity's view not the fragments.
I ended up creating a new app to just play around with this issue and noticed that if I had a layout that didn't contain a CardView whose root layout was a ScrollView it didn't scroll unless the activities windowSoftInputMode is set to adjustResize and then it will scroll.
I then made a layout with a <ScrollView><CardView><content...></CardView></ScrollView> and the size of the CardView was always the default row size for a card and wouldn't match_parent. I solved that with fillViewPort="true" on the ScrollView but when the keyboard came up it wouldn't scroll.
Turns out the secret sauce was to put a FrameLayout (or anyother layout) in between the CardView and the ScrollView.
You still have to account for the resize of the Layout to prevent your view elements not stacking over each other but Once you do that you now get the view above the soft keyboard to scroll and the ability to reach the rest of the UI with a CardView.
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:fillViewport="true">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardCornerRadius="35dp"
app:cardElevation="2dp"
app:cardUseCompatPadding="true"
app:contentPadding="8dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="200dp"
android:src="#drawable/common_ic_googleplayservices"/>
<EditText
android:id="#+id/input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_below="#id/image"
android:hint="Input"
android:inputType="text"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/input"
android:orientation="vertical"
android:gravity="bottom|center_horizontal">
<Button
android:id="#+id/nextButton"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:enabled="false"
android:text="Next"/>
</LinearLayout>
</RelativeLayout>
</android.support.v7.widget.CardView>
</FrameLayout>
</ScrollView>

Keep ScrollView from taking up too much height

I am trying to keep the ScrollView from taking too much space at the bottom of the screen as it keeps my two buttons from showing. I also don't want to manually set a height for the ScrollView.
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
...
android:orientation="horizontal">
<Button .../>
<TextView .../>
<Button .../>
</LinearLayout>
<ScrollView
android:layout_width="math_parent"
android:layout_height="wrap_content">
<ImageView .../>
<ImageView .../>
<ImageView .../>
</ScrollView>
<LinearLayout
...
android:orientation="horizontal">
<Button .../>
<Button .../>
</LinearLayout>
</LinearLayout>
This is a generalized version of my layout. What is happening is that the ScrollView extends all the way to the bottom of the screen no matter how many items are in it. This causes the two buttons at the bottom of the screen to not be visible.
How can I stop this from happening without manually setting a height for the ScrollView?
I've used android:layout_height="wrap_content" for all my views.
Isn't this supposed to automatically distribute the height of the views to fit the screen's height?
(Wanted to include images, but my rep isn't high enough yet (-_-))
The way I would resolve this today is by using RelativeLayout as a base. Anchor the two LinearLayout's to the top and bottom of the RelLayout respectively. Then I would insert the ScrollView but I would make sure to set it's layout properties as follows:
android:layout_below="topLinearLayout"
android:layout_above="bottomLinearLayout"
Have you tried using layout_weight for the ScrollView. IIRC, if a non-zero weight is set for ONE element (and the corresponding dimension set to 0dp) then it'll fill up the remaining space in that dimension, after setting out the measurements for sibling views (in this case, the LinearLayout on top and bottom of the ScrollView.
Apologies, not got an Android environment to check and it's been a while.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout>
...
Something at the top
...
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
**android:layout_height="0dp"
android:layout_weight="1"**>
<ImageView .../>
<ImageView .../>
<ImageView .../>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
...
buttons
...
</LinearLayout>
</LinearLayout>
Here's an answer with more information about the layout_weight attribute.

Categories

Resources