Android Scrollview in RelativeLayout with ButtonBar - android

I'm trying to implement a login view where several EditTexts and a logo are displayed on the screen with a ButtonBar at the bottom, something like this:
alt text http://russellhaering.com/media/addAccount.png
The problem is that on very small screens, especially when they are rotated sideways, the entire main view doesn't fit onto the screen.
I currently have
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#234C59" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingTop="5dip"
android:paddingLeft="15dip"
android:paddingRight="15dip"
android:orientation="vertical" >
<ImageView
android:id="#+id/logo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:layout_centerHorizontal="true"
android:src="#drawable/logo" />
<EditText
android:id="#+id/input_email"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:inputType="textEmailAddress"
android:singleLine="true"
android:hint="Username or email" />
<EditText
android:id="#+id/input_password"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop=""
android:inputType="textPassword"
android:singleLine="true"
android:hint="Password" />
</LinearLayout>
<LinearLayout
android:id="#+id/buttonbar_login"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal"
style="#android:style/ButtonBar" >
<Button
android:id="#+id/button_signup"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Sign Up" />
<Button
android:id="#+id/button_login"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Log In" />
</LinearLayout>
</RelativeLayout>
I've tried encapsulating the first LinnearLayout in a ScrollView that looks like this:
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- Linear Layout Here -->
</ScrollView>
But that introduces two problems:
The ScrollView doesn't scroll, even on screens where the data doesn't all fit
The ButtonBar floats on top of the onscreen keyboard, obscuring even more of the screen when the keyboard comes up.
Everything worked great when I had the buttons inside the ScrollView, but now that I have them in the ButtonBar I'm having a lot of trouble figuring this out.

It turned out that the solution required two steps:
The inability to scroll was a result of the ScrollView being behind the Button Bar. To fix this, I defined the ScrollView below the Button Bar, then used android:layout_above="#id/buttonbar_login" to force the ScrollView to reside entirely above the Button Bar.
Apparently when the onscreen keyboard is opened, if you have a ScrollView it will be resized allowing the Button Bar to float up with the keyboard. To fix this I modified the manifest and added android:windowSoftInputMode="adjustPan" to prevent the ScrollView from resizing.

If your use case supports hiding of the button bar in landscape orientation you can check Resources.getSystem().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE and set the button bar to View.GONE.
You also probably need to set android:windowSoftInputMode="adjustResize" on the <activity> in your manifest file. Android will only put it in adjustResize automatically when the root layout is a ScrollView (iirc).

Related

How to implement this material design feature? (Button floating above keyboard)

Please check this screenshot
How to add buttons like this in android. Is there a library for it or what is it called?
Please note that when keyboard is hidden, this button takes up the space for navigation buttons.
Another question: How to change the size of the blue app bar when keyboard appears or hides?
**UPDATE : ** I can implement a similar layout using borderless buttons in frame layout and setting the gravity to bottom. Then I used android:windowSoftInputMode="adjustResize"
in the manifest file to make it work with keyboard hide/unhide. Still these buttons are not taking the space of navigation buttons. Also still need guidance for change app bar size on keyboard appear.
You can use
1- AppIntro
2- AppTour
Well, I would say that the button is not related in any way with they keyboard. I bet it's just a button inside a FrameLayout with the android:layout_gravity="bottom" property set.
It is a borderless button placed in a container(probably LinearLayout)
container itself is called buttonBar
Borderless button
One design that can be useful is a "borderless" button. Borderless
buttons resemble basic buttons except that they have no borders or
background but still change appearance during different states, such
as when clicked.
To create a borderless button, apply the borderlessButtonStyle style
to the button. For example:
<Button
android:id="#+id/button_send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_send"
android:onClick="sendMessage"
style="?android:attr/borderlessButtonStyle" />
sample for button bar
<LinearLayout android:id="#+id/footer" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:orientation="horizontal"
android:layout_alignParentBottom="true" style="#android:style/ButtonBar">
<Button android:id="#+id/saveButton" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_weight="1"
android:text="#string/menu_done" />
<Button android:id="#+id/cancelButton" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_weight="1"
android:text="#string/menu_cancel" />
</LinearLayout>
Effect of everything else collapsing and this button bar being at top op keyboard can be achieved by keeping your entire view except buttonBar in a scroll view.
Use this as a reference. Insert your layout inside ScrollView.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lines="1"
/>
</LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button"
/>
</LinearLayout>
</LinearLayout>

Android: How to layout buttons along right/left edge of screen, when in landscape mode

My application is intended to be used in portrait mode. The application itself is locked in landscape mode (in the manifest) because I am working with an OpenCV JavaCameraView.
I would like to position a row of buttons along the bottom edge of the screen (as the user sees it). This is the right-hand side of the screen, as the phone sees it. I've tried using a LinearLayout and playing around with the gravity settings, but this orientates the buttons so that the text is facing according to the landscape orientation; e.g. when the phone is held in portrait mode (as intended), the text is orientated so that the bottom of the text is pointing left (because it has been told it is in landscape mode).
Is there any way I can make the buttons and the LinearLayout ignore the portrait/landscape settings and force them to behave as I would like?
This is my current .xml file for the activity:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:opencv="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<org.opencv.android.JavaCameraView
android:id="#+id/main_activity_surface_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<ImageView
android:id="#+id/recordingIconImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:src="#drawable/circle_red"
android:visibility="invisible" />
<TextView
android:id="#+id/movement"
android:rotation="270"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:text=""
android:textSize="20sp"
android:textStyle="bold"
android:textColor="#FF0000" />
<LinearLayout
android:id="#+id/button_row_linear_layout"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:orientation="vertical" >
<Button
android:id="#+id/button_retry"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:rotation="270"
android:layout_weight="1"
android:onClick="captureButtonPressed"
android:text="Retry" />
<Button
android:id="#+id/button_start"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:rotation="270"
android:layout_weight="1"
android:onClick="captureButtonPressed"
android:text="Start" />
<Button
android:id="#+id/button_next"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:rotation="270"
android:layout_weight="1"
android:onClick="captureButtonPressed"
android:text="Next" />
</LinearLayout>
</RelativeLayout>
***Edit:
Adding images to clarify (as suggested in comments) and have already switched to relative layout on my own, so the .xml is also updated. Image of current state:
As you can see I've got the buttons where I would like them (used android:rotation="270"). Two issues now:
1) The text of the TextView is clipped offscreen. I'm pretty sure this is because the sizing constraints are calculated as if it is not rotated and only after layout occurs is it rotated (this is a guess, but it does appear as if that is what's happening)
2) I can't seem to get the buttons to expand to take up available space inside the linear layout.
Any suggestions would be very welcome!
Cheers.

Android ScrollView is not working

This is my .xml file where I have used two scrollview,in Input Edittext and onether in output TextView. What is wrong here...It is not working in android device.
Another problem is that when I turn my device it only shows the input text area. The output text area goes down.I want to see the half screen of input and half screen of output area.
How to fix it??
Thanks
<?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="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="35dp"
android:orientation="horizontal" >
<Button
android:id="#+id/test"
android:layout_width="60dp"
android:layout_height="38dp"
android:text="#string/test" />
<Button
android:id="#+id/rdf"
android:layout_width="60dp"
android:layout_height="38dp"
android:text="#string/rdf" />
<Button
android:id="#+id/load"
android:layout_width="75dp"
android:layout_height="38dp"
android:text="#string/load" />
<Button
android:id="#+id/clear"
android:layout_width="60dp"
android:layout_height="38dp"
android:text="#string/clear" />
<Button
android:id="#+id/close"
android:layout_width="fill_parent"
android:layout_height="38dp"
android:text="#string/close" />
</LinearLayout>
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<EditText
android:id="#+id/input"
android:layout_width="0dp"
android:layout_height="175dp"
android:layout_weight="1"
android:background="#fff"
android:ems="10"
android:gravity="top|left"
android:textSize="14dp"
android:inputType="textMultiLine" >
<requestFocus />
</EditText>
</LinearLayout>
</ScrollView>
<Button
android:id="#+id/run"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/run" />
<ScrollView
android:id="#+id/scrollView2"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/output"
android:layout_width="match_parent"
android:layout_height="225dp"
android:background="#fff"
android:text="#string/output"
android:textColor="#1e90ff" />
</LinearLayout>
</ScrollView>
</LinearLayout>
Try setting layout_weight=1 and layout_height=0dp for the two scroll views instead of their
contents.
What is wrong here...It is not working in android device.
That's pretty vague. What were your expectations? What isn't working? In other words, please be a little more specific.
However, based on the layout code given, here are some recommendations:
Avoid hardcoding the size of views. You cannot make assumptions about screen size with the large variety of screen sizes, densities and devices out there. Also, even if you're able to make the layout look nice in portrait mode, it'll probably be not even close to that in landscape.
If you're going to put just a single View in a ScrollView, there's no need to wrap it in a ViewGroup container; just set the View directly, without nesting it again and added an extra layer of complexity to the view hierarchy.
There's no need to wrap a TextView or EditText with a ScrollView, as both views are scrollable by itself.
Regarding your second question: you can prevent Android from extracting all UI components when there's little layout estate left with the keyboard popped up. You'll need to set the IME_FLAG_NO_EXTRACT_UI flag on the EditText, or in xml: android:imeOptions="flagNoExtractUi".
I do like to point out that there's a reason Android has this behaviour by default. In most cases it hardly makes sense to force a tiny part of the UI to be visible, even more as whatever is being typed by the user is probably what really matters.

SoftKeyboard hiding EditText

I have a layout that uses an EditText to let users search a database and populate a ListView. The EditText is about 2/3 of the way from the top of the screen (positioned over an ImageView, and followed by some intro text.)
The problem is that the soft keyboard hides the EditText, so the user can't see what he's typing. (I disabled the auto-suggest.)
I've tried LinearLayout, RelativeLayout, paddings, and different alignments/centerings, but I still can't get it to work right. The EditText is either hidden, gets pushed off the top of the screen, or get "squished" and distorted.
Suggestions???
One possible workaround is to move the EditText to the top of the screen. However, this deviates from the graphic design that I was given.
Another possible workaround is for me to make the soft keyboard open in full screen (not sure how, though). This will still hide the EditText, but then I can re-enable the auto-suggestion so the user can see what he's typing... sort of... because he can only see the suggestions for what he's typing.
Here's my latest attempt. See "introFrame".
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout android:id="#+id/titleContainer"
android:orientation="horizontal" android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:text="#string/title_string"
android:textSize="15sp" android:textColor="#FFFFFF"
android:textStyle="bold" android:paddingLeft="5dp"
android:layout_height="fill_parent" android:layout_width="wrap_content" />
</LinearLayout>
<FrameLayout
android:id="#+id/introFrame"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal" >
<ImageView
android:src="#drawable/main_search_image"
android:scaleType="center"
android:layout_gravity="center"
android:layout_height="wrap_content"
android:layout_width="wrap_content"/>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingTop="140dp" >
<LinearLayout android:id="#+id/introSearchContainer"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical" >
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" >
<EditText android:id="#+id/intro_search_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint=" Enter keyword "
android:imeOptions="actionGo"
android:inputType="textFilter"
android:maxLines="1" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<Button android:id="#+id/intro_search_button"
android:background="#drawable/custom_button_go"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
<TextView
android:text="#string/search_intro"
android:textSize="15sp"
android:textColor="#FFFFFF"
android:layout_height="wrap_content"
android:layout_width="fill_parent" />
</LinearLayout>
</FrameLayout>
<LinearLayout android:id="#+id/listContainer"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView android:id="#+id/itemlist" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:cacheColorHint="#00000000" />
<TextView android:text="No data found" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:gravity="center"
android:textSize="16sp" android:textColor="#FFFFFF" android:id="#+id/android:empty" />
</LinearLayout>
</LinearLayout>
What you're looking for is the Activity's windowSoftInputMode attribute. You set this in your AndroidManifest.xml file, and give it a value such as:
adjustResize: "The activity's main window is always resized to make room for the soft keyboard on screen."
adjustPan: "The activity's main window is not resized to make room for the soft keyboard. Rather, the contents of the window are automatically panned so that the current focus is never obscured by the keyboard and users can always see what they are typing. This is generally less desirable than resizing, because the user may need to close the soft keyboard to get at and interact with obscured parts of the window."
adjustResize will probably work for you, as long as you wrap the layout in a ScrollView. It may have negative effects if you have a bitmap image in the background, as it will be resized as well, in which case you may want to use adjustPan instead.
<activity android:windowSoftInputMode="adjustResize" />
or
<activity android:windowSoftInputMode="adjustPan" />
More information is available at the above link.
What has worked for me is to drop my highest-level LinearLayout in a scrollView (the ScrollView can only have one child). This allowed the entire activity/form to scroll up and not clutter the EditText in focus.
First, I set in my activity:
<activity android:windowSoftInputMode="adjustPan" />
Then I did the ScrollView thing I'm talking about:
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- STUFF -->
</LinearLayout>
</ScrollView>
just use following in manifest...
<activity
android:windowSoftInputMode="adjustPan">
try giving the edit text a layout_weight (i.e. layout_weight=1) , this may have some other effects on your other layout items that you may have to work through, but this may help it stay visible when soft keyboard pops up

Android Dev: Placing layouts

I'm new to android development... while making my application layout i want a button to remain at the very bottom of the screen while a scroll view is placed above it. I am unable to do this i was using the size of the scroll view as 430dp so that it works but when i change the orientation of the screen this does not work as 400dp is bigger than the screen.
how do i make it so that the button stays at the bottom irresepective of the screen orientation ?
:/
Set the ScrollView's layout_height to fill_parrent and layout_weight to 1 and the Button's height to wrap_content.
You could go with this
android:gravity="bottom"
This should always push your element to the bottom of its container.
But it'd more helpful if you'd post up your layout XML.
Here's a real world example of precisely what you're asking.
In this layout, I have a header at the top, a list view taking all the space below it and a button to clear (cancelled, failed, finished) elements of the list view, then right at the bottom I have a custom control showing a toolbar.
<?xml version="1.0" encoding="utf-8"?><LinearLayout android:id="#+id/layout" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout android:id="#+id/browsePeerHeader"
android:layout_width="fill_parent" android:layout_height="70sp"
android:layout_marginBottom="2sp"
android:layout_gravity="top"
android:background="#drawable/background_barbed_wire"
>
<ImageButton
android:id="#+id/frostwire_sphere"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:src="#drawable/icon"
android:layout_gravity="center_vertical"
android:layout_margin="3sp"
android:background="#00000000"/>
<TextView android:id="#+id/browsePeerTitle" android:textSize="30sp"
android:text="Downloads"
android:textColor="#ffffffff" android:textStyle="bold"
android:shadowColor="#ff000000"
android:shadowDx="1.0"
android:shadowDy="1.0"
android:shadowRadius="4.0"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="10sp"
android:gravity="left|center_vertical"/>
</LinearLayout>
<ListView android:id="#+id/ListViewTransfers"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2sp"
android:layout_marginBottom="2sp"
android:layout_weight="1"></ListView>
<Button android:id="#+id/ButtonClearFinished" margin="2sp"
android:layout_width="fill_parent" android:layout_height="wrap_content"
/>
<com.frostwire.android.views.FrostWireStatusBar
android:id="#+id/FrostWireStatusBar" android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom" /></LinearLayout>
Here's a screenshot
The trick is basically to have the list view use all the space left in the layout that contains it, you don't even have to tell it to fill_parent, just with android:layout_weight="1 it should work.

Categories

Resources