How to allow softkeaybord cover only defined views? - android-layout

My layout has the following structure:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ScrollView
android:id="#+id/login_form"
android:layout_width="match_parent"
android:layout_height="match_parent" >
....
</ScrollView>
<ImageView
android:layout_width="wrap_content"
android:layout_height="90dp"
android:layout_gravity="bottom"
android:baselineAlignBottom="true"
android:src="#drawable/logotyp" />
</LinearLayout>
When softkeyboard appears, ImageView is moved up and ScrollView is resized. I want to make the ImagView was obscured by softkeyboard and ScrollView was still resized. Is it possible?

I think the solution is to monitor for height change events and then set the ImageView visibility to View.GONE when things get smaller.

Related

GridLayout with variable row height in Xamarin

I have a fairly simple Xamarin app with a primary interface that consists of two ImageViews, one overlayed on the other. The images are the same size, and I want them to expand to fill the screen. Except that I want the bottom 100 pixels (about) reserved for a banner ad.
Without the ad, I found this simple. I used a RelativeLayout, set the layout_height and layout_width to match_parent, put both images in it, and set layout_CenterInParent to true for both of them. It works great.
And then I went to put the banner in. I tried using a GridLayout with one column and two rows, putting the prior RelativeLayout inside the top cell and the banner inside the bottom cell. But unless I restrict the height of the RelativeLayout to a fixed height, it expands until the banner is invisible. And I don't want to restrict it to a fixed height, because I want to expand it to the full height minus the banner height.
I realize that there's a basic contradiction between filling a space and restricting the height, but I'm hoping that there's some solution for this.
In css, I can use heights like wh-100 to be the full window height minus 100 pixels. Is there anything similar in Xamarin? Failing that, is there any trick I can use to achieve what I'm trying to do?
<GridLayout
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:minWidth="25px"
android:minHeight="25px"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:rowCount="2"
android:columnCount="1"
android:id="#+id/gridLayout1">
<RelativeLayout
android:minWidth="25px"
android:minHeight="25px"
android:id="#+id/relativeLayout1"
android:layout_width="wrap_content"
android:layout_height="400px"
android:layout_rowWeight="1"
android:background="#ffff44">
<ImageView
android:id="#+id/img1"
android:src="#drawable/img1"
android:layout_centerInParent="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<ImageView
android:id="#+id/img2"
android:src="#drawable/img2"
android:layout_centerInParent="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
<RelativeLayout
android:minWidth="100px"
android:minHeight="100px"
android:layout_height="100px"
android:id="#+id/relativeLayout2"
android:layout_width="wrap_content"
android:background="#ccff44">
<ImageView
android:id="#+id/banner_placeholder"
android:src="#drawable/banner_placeholder"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
Thanks for any help.
At first, if you use the GridLayout , you can set the control's height as the parent's - 100 in the xml. But you can use the row height to set the control's height such as:
<GridLayout
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:minWidth="25px"
android:minHeight="25px"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:rowCount="2"
android:columnCount="1"
android:id="#+id/gridLayout1">
<RelativeLayout
android:minWidth="25px"
android:minHeight="25px"
android:id="#+id/relativeLayout1"
android:layout_width="wrap_content"
android:layout_height="400px"
android:layout_row="0"
android:layout_rowWeight="3"
android:background="#ffff44">
<ImageView
android:id="#+id/img1"
android:src="#drawable/img1"
android:layout_centerInParent="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<ImageView
android:id="#+id/img2"
android:src="#drawable/img2"
android:layout_centerInParent="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
<RelativeLayout
android:minWidth="100px"
android:minHeight="100px"
android:layout_height="100px"
android:layout_row = "1"
android:layout_rowWeight="3"
android:id="#+id/relativeLayout2"
android:layout_width="wrap_content"
android:background="#ccff44">
<ImageView
android:id="#+id/banner_placeholder"
android:src="#drawable/banner_placeholder"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
This will set the first RelativeLayout's height as 3/4 of the parent and the second as the 1/4.
If you still want to set the first RelativeLayout's height as parent's - 100, you can use the ConstraintLayout instead of the GridLayout. And you need to install the package named Xamarin.AndroidX.ConstraintLayout at first.
And then:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<RelativeLayout
android:id="#+id/layout1"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_width="match_parent"
android:layout_height="100dp"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp" // in the ConstraintLayout the odp means use the rest area in the parent
app:layout_constraintBottom_toTopOf="#+id/layout1"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
In addition, the ConstraintLayout is the most using layout in the native android, it can design many effects which is hard for the other layouts to implement.

Wrapping two ScrollViews into a LinearLayout

I am struggling to find a solution for one of the Android Studio (Kotlin) class problems by Google: how to add another image that scrolls down with the first ScrollView. I created a LinearLayout that has two ScrollViews within it. The first ScrollView has a large amount of text which scrolls down perfectly. However, in the second ScrollView, for the image above the text, it does not scroll down with the text.
Here is a view of the Design element of the activity_main (the green bar below the star is ImageView1 which is in the second ScrollView):
Here is the code for the ScrollViews in my activity_main:
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<ScrollView
android:id="#+id/bio_scroll2"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srcCompat="#android:drawable/button_onoff_indicator_on" />
</ScrollView>
<ScrollView
android:id="#+id/bio_scroll"
android:layout_width="match_parent"
android:layout_height="463dp">
<TextView
android:id="#+id/bio_text"
style="#style/NameStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lineSpacingMultiplier="1.2"
android:text="#string/bio" />
</ScrollView>
</LinearLayout>
Some guidance will be greatly appreciated.
The reason I told you to use only one ScrollView is that you don't need two. You can use any number of views in a Scrollview, just make sure the child of ScrollView is a Layout. You can use any layout and then put whatever you have in that layout. That's how ScrollView is used.
As the official docs of ScrollView state :
Scroll view may have only one direct child placed within it.
To add multiple views within the scroll view, make the direct child
you add a view group, for example LinearLayout, and place additional
views within that LinearLayout.
So, change your code as :
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ScrollView
android:id="#+id/bio_scroll2"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srcCompat="#android:drawable/button_onoff_indicator_on" />
<TextView
android:id="#+id/bio_text"
style="#style/NameStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lineSpacingMultiplier="1.2"
android:text="#string/bio" />
</LinearLayout>
</ScrollView>
</LinearLayout>
Furthermore, You can remove the root LinearLayout if you don't want to add any other view in it and that will make the ScrollView the root layout.
Also, the height as match_parent doesn't work in ScrollView and it works only as wrap_content or any fix size so if you want to make it take the full height of its parent, you've to use android:fillViewport="true" in ScrollView's tag and height of its parent should be match_parent.

LinearLayout - Positioning Views

I have this layout.
<RelativeLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/numbers_root"
android:orientation="vertical"
android:gravity="top"
>
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/numbersList"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="116dp"
android:clipToPadding="false"
tools:layout_height="100dp"
></ListView>
<ExpandableListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/subcategory_expandable"
>
</ExpandableListView>
</LinearLayout>
</RelativeLayout>
But the problem is that the ExpandableListView is always centered on screen despite gravity="top" in the parent Layout. What I want is to have it start exactly where the ListView ends. Any idea what might be causing this?
Should I use a scrollview instead of linearlayout?
Here is a screenshot to clarify:
I want the expandable listview to appear below the listview.
I think the issue is that you're paddingBottom="116dp" on the ListView is pushing the ExpandableListView down.

TextView expands layout but webview does not

I've got a layout with a textview with some buttons at the bottom. The textview is set to expand to fill the space. This is fine. However, when I change the textview to a webview, the webview does not expand to fill the space. What's wrong?
This is working fine:
<?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="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
>
<!-- height set to fill because background is black and we want
the light background -->
<TextView
style="#style/subtopicView"
android:id="#+id/subtopic_content"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</ScrollView>
<include layout="#layout/include_html_view_footer" />
</LinearLayout>
This is not, but the only change is the textview to a webview and all other values remain the same.
<?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="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
>
<!-- height set to fill because background is black and we want
the light background -->
<WebView
style="#style/subtopicView"
android:id="#+id/subtopic_content"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</ScrollView>
<include layout="#layout/include_html_view_footer" />
</LinearLayout>
the include is simply this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#color/tintedColour"
android:orientation="horizontal"
android:paddingBottom="#dimen/spacer"
android:paddingTop="#dimen/spacer" >
<Button
android:id="#+id/PrevPage"
style="?android:attr/buttonStyleSmall"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/previous" />
<Button
android:id="#+id/NextPage"
style="?android:attr/buttonStyleSmall"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/next" />
<Button
android:id="#+id/Copy"
style="?android:attr/buttonStyleSmall"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/copyclipboard" />
</LinearLayout>
Thanks for any help.
It's generally a bad idea to nest scrollable elements like you have done by including a WebView inside a ScrollView. Touch events will be unpredictable, and it would probably be a better idea to drop the ScrollView altogether.
That said, the height of your WebView is set to fill_parent. However, the ScrollView is simultaneously trying to minimize the size of its children. As Romain Guy writes in a blog post on this topic:
In attempt to achieve this effect, I have seen several Android developers try to set the height of the view inside the scroll view to fill_parent. Doing so does not work and leads to the following result:
To understand this result, you must remember that android:layout_height=”fill_parent” means “set the height to the height of the parent.” This is obviously not what you want when using a ScrollView. After all, the ScrollView would become useless if its content was always as tall as itself.
By setting android:fillViewport="true", the scroll view’s child expands to the height of the ScrollView. (When the child is taller than the ScrollView, the attribute has no effect.)

Scrollview doesn't scroll to the margin at the bottom

I have a simple layout as follows :
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#D23456" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="#FFFFFF" >
<ImageView
android:layout_width="match_parent"
android:layout_height="800dp"
android:src="#drawable/ic_launcher" />
</LinearLayout>
</ScrollView>
The background of the scrollview is pink and linear layout inside has the android icon image with a height of 800dp (that doesnt fit to the screen) . What I'm expecting to see is that imageview floats in a background of pink with a margin of 10dp in every sides (top,bottom,left,right).But when I scroll to the bottom, the scrollview doesn't scroll to the margin, so the bottom of the scroll is the imageview not the pink margin.
How can I prevent this? This makes the user think the page hasn't ended yet and makes him want to scroll more.
I later found out that ,a similar situation has already been answered in the following thread https://stackoverflow.com/a/16885601/1474471 by #olefevre.
Adding an extra LinearLayout that surrounds the current LinearLayout with a padding and removing the inner LinearLayout's layout-margin solved the problem:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#D23456"
android:padding="10dp" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFFFF" >
<ImageView
android:layout_width="match_parent"
android:layout_height="800dp"
android:src="#drawable/ic_launcher" />
</LinearLayout>
</LinearLayout>
</ScrollView>
The solution posted by #Mehmet Katircioglu works well, but you can solve the problem simply changing the android:layout_margin to android:padding, without none extra view. Like this:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#D23456"
android:padding="10dp" >
<!-- Your content (ImageView, buttons...) -->
<LinearLayout/>
use android:fillViewport="true" on the ScrollView may do it.
example in this thread.

Resources