How to disable default scroll behavior of an EditText? - android

The title of question might look similar to other questions but It's not. I have several strange problem that I am not being able to solve it.
I have a xml layout and the structure of that layout looks like below.
LinearLayout
|
ScrollView
|
LinearLayout
|
TextView
EditText(multiLine)
The xml:-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Large Text"/>
<EditText
android:layout_width="match_parent"
android:inputType="textMultiLine"
android:layout_height="match_parent"/>
</LinearLayout>
</ScrollView>
</LinearLayout>
Now let's discuss about problem.
If I keep adding new line to the editText, the editText itself scroll and the TextView which is located above EditText is not scroll. But what I want is EditText not to scroll and leave the job for scrollView so that the textView which is loacated above EditText also scroll along with EditText when new Line is added.
ScrollView behave ok when I press back(usually when the editText is not focused anymore).
Setting to
<ScrollView
...
layout_height="wrap_content">
fix the problem but the desired height then compromised. Same thing happen with Horizontal scrollView also.
Is there any way to solve this problem ? Detailed Answer will be helpful.

Set your EditText's height to wrap_content so it expands instead of scrolling. Set your LinearLayout's height to wrap_content so it's the size of its contents, i.e. the TextView and EditText.
The ScrollView should be whatever height you want for your "window" into the contents layout, the LinearLayout that moves up and down "behind" the ScrollView.
The scrolling happens if that contents layout is too big to display in the visible ScrollView, which is why that contents layout should always be wrap_content (the size of the contents) and never match_parent (the size of the scroll view "window"). If the contents are always the same size as the scroll view, they'll never need to scroll, right?

Related

RelativeLayout not exceeding ScrollView height

I have a ScrollView with a RelativeLayout as its child. This is all nested within a RelativeLayout.
<?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"
android:background="#2fb136">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fpScrollView"
android:fillViewport="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/fpRelativeLayout">
Image of how it looks
Now if I add a margin of 50dp to the ScrollView, the RelativeLayout matches the height of the scroll view and cuts off the button rather than expanding and allowing for scrolling.
Any ideas on how to fix this? I would like the RelativeLayout to actually wrap to the content and not cut it off.
I found a solution. One of the views within the ScrollView was aligned to the horizontally/vertically center which doesn't make sense in the context of a view that changes it size dynamically. This was causing the RelativeLayout within the ScrollView to simply stay the size of the ScrollView rather than wrapping its content.
If your entire layout is scrollable I would suggest making the base layout a ScrollView rather than a RelativeLayout like I did above.

Why does the orientation of a linearlayout determine the centering of a child element?

Why doesn't this center a button both horizontally and vertically on the screen?
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="#FFFFFFFF">
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/red"
android:textColor="#color/white"
android:text="click"
android:layout_gravity="center"/>
</LinearLayout>
layout_gravity specifies alignment for the button within it's parent. But this only centers the button vertically, not horizontally. If I change the orientation of the linearlayout to vertical, the button is centered horizontally, not vertically. I don't see why the orientation matters here because I only have 1 child element.
I know I can achieve this by specifying the gravity in the LinearLayout with android:gravity="true" or using a RelativeLayout and have the Button android:centerInParent="true", but I'd like to know how android came up with the layout in the code above.
P.S. Why does the background color still show as gray if that's the hex code for white?
LinearLayout will only allocate the minimum amount of space needed for a view in the direction of its orientation. That's why you can't seem to center a view in the same direction as the orientation. LinearLayout generally assumes that you want to put multiple things adjacent to each other, not occupy an entire space unconditionally for a single item.
P.S. I see the entire background of the LinearLayout as white in my preview view in Android Studio, so I don't know what you mean in your P.S.
Don't use a linear layout to display items in the middle of the screen, as these are meant to list items in a row. Use a relative layout instead. So your code should look like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="#FFFFFF">
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/red"
android:textColor="#color/white"
android:text="click"
android:layout_centerInParent="true"/>
</RelativeLayout>

Why does view with layout_marginTop set and gravity=bottom placed inside horizontal LinearLayout cause margin to appear at the bottom?

I've tried to add view with layout_marginTop set and gravity=bottom inside a horizontal LinearLayout and it causes margin to appear at the bottom for no reason.
I'm aware that kind of layout could be build differently but I can't understand why I'm getting such result.
Here is the xml layout:
<?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:background="#ff0000"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginTop="8dp"
android:background="#0000ff"
android:textSize="24sp"
android:text="TEST"/>
</LinearLayout>
And here is the result:
Any ideas with this one?
After digging through the source code, it seems that the root cause of this behavior is the fact that LinearLayout aligns its child Views by their baselines by default. When it measures out the vertical offsets for the child Views, it takes into account the sum of the vertical margins. These offsets are then applied after the "normal" top (y) coordinates are calculated for the child Views.
The upshot of all this is, if you want your TextView aligned right at the bottom, set the LinearLayout's baselineAligned attribute to false.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:background="#ff0000"
android:orientation="horizontal">
...
TextView is set with Its own LAYOUT GRAVITY to bottom, i.e. TextView's whole body is aligned to bottom, it won't make difference if orientation is horizontal, because it is linearLayout it won't work with marginTop when layoutGravity of View is set to Bottom, remove layoutGravity and keep marginTop it will come near to the top with mentioned margin.!
Why it is not on the base.?
because you have given it a margin and when you are giving it some value provided you have given it layoutGravity of Bottom already so it takes the bottom as it base align and gives margin from it.!
Hope i helped you partially if not completely.

Grow LinearLayout inside Scrollview for bigger phones on Android

I have a Scrollview for the complete screen, so in small phones you can scroll and see the complete form.
For big screen/hdpi phones, the screen has enough size so it fits.
The problem is that since its a LinearLayout, all views are at the top, and there is white space at the bottom.
I set the weight on one of the items items inside the linear layout, but it does not grow.
my code:
<ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
HEADER STUFF
</RelativeLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical" >
THIS PART I NEED TO GROW AS MUCH AS POSSIBLE SO THE FOOTER IS AT THE BOTTOM OF THE PAGE.
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/LightBlue"
android:orientation="vertical"
android:paddingBottom="10dp" >
FOOTER STUFF. NEED THIS TO BE AT THE FOOTER IF THE PHONE IS BIG ENOUGH.
</RelativeLayout>
<LinearLayout>
</ScrollView>
Simple answer: In the LinearLayout, change android:layout_height="wrap_content" to android:layout_height="match_parent".
Reason: By wrapping the content, you aren't giving the middle RelativeLayout with the most weight a chance to grow and fill the white space. Changing it to match the parent height gives it its space to blossom, so to speak.
Also, per Indiandroid's comment, you may want to put the ScrollView inside the LinearLayout and around the middle RelativeLayout that hosts the content so that the header and footer are fixed.
EDIT: If you intend to stretch the middle RelativeLayout by using weight in the LinearLayout, you will, after applying my previous part about switching the height to match_parent, have to move to ScrollView inside the LinearLayout around the middle RelativeLayout or it will grow indefinitely. This is because the ScrollView has no vertical bounds and by matching it's height with the LinearLayout, the LinearLayout also has no bounds.

Android: How to automatically display vertical scrollbar?

I created a user form which fits the window in vertical orientation. When the user slides the keyboard the form doesn't fit the screen (horizontal orientation). I tried to add the scrollbar but it is not visible.
I would appreciate if anyone could show how to modify the following layout file in order to display scrollbar when the orientation is set to horizontal.
Thanks!
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:orientation="vertical"
android:scrollbars="vertical"
android:scrollbarAlwaysDrawVerticalTrack="true">
...
</LinearLayout>
Remove the scrollbar attributes and wrap the whole thing in a ScrollView.
You can't replace the LinearLayout with ScrollView because ScrollView only supports one Direct Child and LinearLayout may have many. So the only option i see is to wrap
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:overScrollMode="always"
android:isScrollContainer="true"
android:scrollbarAlwaysDrawVerticalTrack="true"
android:scrollbarStyle="outsideInset"
android:scrollbars="vertical">
You can pick a variety of other attributes. These worked for my implementation. It is the first container in my layout.LinearLayout is a child of this container. Other UI elements are part of LinearLayout
Hope this helps...
Alex

Categories

Resources