Fold up a Layout but keep another at the bottom - android

I've got this layout:
Without colors: https://i.stack.imgur.com/OdSda.png
Layout for the tabs (separate xml file)
RelativeLayout 1 surrounding everything else
A, B, C all have their own LinearLayout in RelativeLayout 2
The horizontal line, D (in a LinearLayout) and the "OK" button have their own RelativeLayout 3
And there's RelativeLayout 4 (=footer) for E
What I want to happen if I click on the EditText next to D and the keyboard opens up:
4 stays at the bottom and is hidden behind the keyboard
If there isn't enough space to fully display 3, 2 is collapsed until the keyboard is closed again
What's actually happening:
2 stays where it is
The keyboard covers 3 halfway and I can't see what I'm typing
4 is pushed up and covers D
Two things I've already tried but with both didn't fully work as expected:
I) Add android:windowSoftInputMode="adjustPan" to the manifest:
4 stays at the bottom BUT
Everything else is pushed up, so 2, 3 and the tabs which are then covered half way
II) Add android:windowSoftInputMode="adjustResize" to the manifest: Nothing changes unless I also add android:fitsSystemWindows="true" to the tab fragment's xml:
Now all the padding of the surrounding RelativeLayout 1 is ignored
The EditText next to D is pushed up against 2 but not readable and D and the "OK" button are covered by the keyboard
4 is still pushed up

I managed to find a way! :) A big thanks goes to Umair for giving me the tip with the ScrollView and testing different things too!
First of all, this is how the overall layout is built now:
Surrounding RelativeLayout 1 (nothing special, no android:fitsSystemWindows="true" - the ScrollView seems to disable that anyway!)
new ScrollView
new RelativeLayout (ScrollView can only contain a single element!)
RelativeLayout 2
LinearLayout A (TextView + EditText)
LinearLayout B (TextView + EditText)
LinearLayout C (TextView + EditText)
"Save" Button
RelativeLayout 3
LinearLayout D (TextView + EditText + "OK" Button)
RelativeLayout 4 (TextView E)
Manifest:
<activity android:name=".MainActivity"
android:windowSoftInputMode="adjustResize"
....
Code for RelativeLayout 4:
Before:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom">
<TextView
android:id="#+id/textE"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/E"
android:textSize="20sp"/>
</RelativeLayout>
After:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
android:layout_below="#id/ScrollViewABCD"
android:gravity="bottom">
<TextView
android:id="#+id/textE"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/E"
android:textSize="20sp"/>
</RelativeLayout>
I'm not sure if android:layout_gravity="bottom" is actually needed anymore (android:gravity="bottom" is to have the text at the bottom!) but I haven't noticed any changes without it either.
android:layout_alignParentBottom="true" is the important part here because without it, Relative Layout 4 would be simply below the ScrollView but this little extra makes it use up all the space it can, while still keeping it as far south as possible. Plus, you can still use margins to create some empty space between the ScrollView and RL 4 (even though you're only going to see it in the Preview window in Android Studio).
What this does:
The ScrollView is usable
The keyboard is always below the ScrollView
If there isn't enough space to display the ScrollView AND the keyboard, the former becomes scrollable
RelativeLayout 4 is always hidden behind the keyboard
The tabs stay where they are
The padding of RelativeLayout 1 doesn't get ignored (like it would with android:fitsSystemWindows="true")

So here's what I came up with: No matter how hard I tried keyboard on my devices/emulators was always at the bottom of layout 3I checked devices with height starting from 4.7 inches min. And if you put adjust:resize in manifest file it will always show last layout on top of keyboard . But if you put adjust:nothing then your bottom layout won't show up even if you want to write something on it. If you put adjust:adjutPan then it will push your layout on top like you said. Now come to the keyboard part:
If you want to take height or check that either your keyboard is covering your layout or not then you need to take height of your screen and keyboard and find out the difference. Take a look at this question.
How to check visibility of software keyboard in Android?
On the bases of that result you can show or hide your layout.
Note: if you want your requirements as it is then you will have to design your custom layout.

Related

BottomSheetDialogFragment behaviour when showing keyboard [duplicate]

This question already has answers here:
Bottomsheet with edit text moved up by keyboard
(2 answers)
Closed 2 years ago.
I am using a BottomSheetDialogFragment which contains:
- A RecyclerView with a list of comments made by users
- A EditText at the bottom, where users can write a new comment and post it
When the user taps on the EditText, the keyboard shows up from the bottom.
What i want is the keyboard to push ONLY the EditText, so that the user can see what he's typing, but not push the whole BottomSheetDialogFragment.
You can see the desirable behaviour in the Facebook app for example.
I have tried setting different values for setSoftInputMode but all i can achieve is either to move the whole BottomSheetDialogFragment, or to move nothing (leaving the EditText covered).
The easiest way to do this is to not use a BottomSheetDialogFragment but instead to use a regular fragment that covers the entire window or an activity. Fragment or Activity; whichever you prefer doesn't matter as long as you're taking up the whole screen.
When the on-screen keyboard appears, the activity window (by default) resizes to make way for the on-screen keyboard.
Since a BottomSheetDialogFragment has it's gravity set to bottom, when the activity window resizes, it pushes the bottom sheet and all of it's contents upwards.
Here's an example of the simplest layout that can achieve what you're going for
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<View
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="#80000000" />
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
First is a view with a constant height which imitates the dark area outside of a dialog. No matter how the window resizes this will always be 80dp.
Second is the RecyclerView which resizes based on the remaining available space the LinearLayout has. Pay attention to the attribute android:layout_weight.
Third is EditText which has a constant height of wrap_content. Again No matter how the window resizes this will always be the same height. Since the RecyclerView will take up as much space as it can, this EditText will remain at the bottom of the screen.
Once the window resizes due to the on-screen keyboard appearing, the LinearLayout will resize and recalculate it's children's sizes. Since the View and the EditText has a constant height it will have to make the RecyclerView smaller making it appear like the EditText moved upwards.
You don't have to use a LinearLayout to do this, you can achieve the same effect with any other layout. The key point here is to use a layout that takes up the whole screen.

How to stop a textview pushing layout off of screen

I am building a app and I just need some help with the attached screen shot.
Currently I have 5 Plain Textfields with the last 2 being textMultilines. I have a Relativelayout with a button placed at the bottom for the user to press submit. The problem is when the textViews above are filled in, especially the multiline ones, it will push the Relativelayout and button off the screen.
How can I stop this from happening
Picture of layout
Either You should fix the height of multi lines text or you can simply use Scroll View and put all the text view and button in same relative layout
You can make them Scrollable by adding ScrollView around them.
like
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
//all your views here
</LinearLayout>
</ScrollView>

Android buttons are cut off (LinearLayout horizontal)

In my app I am calling API to get list of people with some informations (address, phone numbers etc.). Under every phone number, I am creating programatically 3 buttons (add to contacts, edit and call). Problem is, that last button is cut off (small screen). I am using Linear Layout horizontal.
Is there any way to control size of screen and if needed, put last button to second line? When I rotate screen to landscape, I have enough space, so buttons should stay in one line.
Now, I am using horizontalScrollView with visible scrollbar. It's working, but I am not very satisfied with it.
Thanks for help.
I'm not really sure if you can do that with LinearLayout. But you could do that using FlowLayout. Check this link: https://github.com/ultimate-deej/FlowLayout-for-Android.
This layout moves the buttons to the next line if there is no space for them on the screen.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weight="1" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weight="1" />
</LinearLayout>
the weight attribute will automatically adjust your button size
make sure you set width to match parent for all buttons.
Best to create a new variant of the listitem layout for smaller screenshots:
layout-w200dp/listitem.xml : layout with 3 buttons on one line
layout/listitem.xml : layout with buttons on separate lines
Android will then choose the multiline layout when the current available width is smaller than 200dp. (Note that you can still tweak the 200 to a different value)
Alternatively you can also use an alternatieve linearlayout which does the wrapping for you: Flowlayout
This is probably more complicated to achieve that you wan't it to be but the best shot is to use some adapter based solution:
GridView - this is the old solution, better go for the 2nd
RecyclerView with StaggeredLayoutManager setup to your needs
Simple solution is using android:layout_weight="1" and android:layout_width="0dp" as params for each button in your LinearLayout but then they will fit the whole screen and take the same percent of the width, and if the screen is too small buttons might get cut off.

View without Activity - Placement and Layout

I am using the Code from JawsWare - Overlay View to create a View that lays above everything.
This works fine, but I failed to adapt the given layout to my needs.
What I want: Two Phases.
First Phase: A button in the upper left corner that is always there above all other apps.
When this button is pressed, we enter the Second Phase:
The button is replaced by two images which are to be horizontally aligned at a certain distance from the top, again floating above everything else.
I have to admit that I dont really understand Android Layouting, but I've tried fiddling with a RelativeLayout and an ImageView but it seems buggy.
Additionally, I encountered a very strange behaviour: Even if the Image is only about 200x200 px in the upper left corner, nearly the whole screen is "blocked" by the View (it receives all TouchEvents, even though there shouldt be anything). It seems that if I position the Layout using Margins to float in the middle of the screen, everything to the left and top of the visible button is also receiving touch events and not letting them pass through to the underlying app (even though there is no visible content).
Any ideas to why this happens and how to circumvent that?
Secondly: How can I achieve the two layouts from earlier?
Edit 1: My Layout. (please keep in mind that I just copied this and then did what I thought was right)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="0dp"
android:onClick="overlayTextClicked"
android:padding="0dp"
android:id="#+id/overlay_layout_id"
>
<ImageView
android:id="#+id/imageview_info"
android:layout_width="200px"
android:layout_height="200px"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:scaleType="fitXY"
android:src="#drawable/picture_010512233437384578"
android:contentDescription=""/>
<TextView
android:id="#+id/textview_info"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:text="info"
android:textColor="#FFF"
android:orientation="vertical"
android:textAppearance="?android:attr/textAppearanceSmall" />
</RelativeLayout>
Afterwards I am trying to set the RelativeLayouts Gravity to TOP | CENTER_VERTICAL with a Top-Margin of 200px.
I believe what's going on here is your TextView is filling out the entire screen.
wrap_content bounds the size of a View with its content. match_parent fills a view to as big as it can get (i.e., whatever size the container is bound to).
So in this case, your RelativeLayout is does not have a max size it's bound to. Your TextView is going to try to get as big as it can get, so it's going to fill the screen. Likewise, the RelativeLayout is going to blow up to that size to wrap around the TextView.
Also, RelativeLayout doesn't really respond to Gravity well. That is used in LinearLayout and FrameLayout containers a lot, but RelativeLayout relational rules like "CENTER_IN_PARENT" are going to override whatever Gravity you set (if you set Gravity.RIGHT and "CENTER_IN_PARENT", then one has to win out I guess).

Snapping elements / conditional layouts

Sorry for the extremely bad title, I have no other idea what to call this question. What I'm trying to do is this: have a RelativeLayout which has two children:
one with layout_centerInParent="true"
one with layout_alignParentBottom="true"
However, when the device is in landscape mode, element (1) appears slightly over or under element (2). But, element (1) has enough space above it to appear above element (2). How could I make the layout so that if the screen is too small to center element (1) and make both elements not overlap, then align element (1) above (as in layout_above) element (2)?
This should work to give you a layout where the text1 item fills the available space above text2, and is centered vertically and horizontally in that space; and text2 is on the bottom, centered horizontally.
<LinearLayout
android:orientation="vertical"
android:layout_height="fill_parent"
android:layout_width="fill_parent">
<TextView
android:id="#android:id/text1"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="Centered"
android:gravity="center_vertical|center_horizontal"
/>
<TextView
android:id="#android:id/text2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Bottom"
android:gravity="center_horizontal"
/>
</LinearLayout>
The important parts are android:layout_weight, combined with android:gravity.
Alright here's a leftfield suggestion that might work if your element (1) isn't too resource intensive.
Have two versions of element (1), the first with layout_centerInParent="true" and the second with layout_above="#id\element2". Default them both to android:visibility="invisible". In your onCreate Post a Runnable that inspects the Y dimension of both elements, and sets View.VISIBLE on the element with the smallest value.
New idea:
This is another idea that's sort of a workaround in that it's not very elegant, but it's very simple. Put element (1) in its own < LinearLayout > configured like so:
<LinearLayout android:layout_width="fill_parent"
android:layout_height="fill_parent" // More on this line below
android:layout_alignParentTop="true"
android:layout_above="#id/element2"
android:gravity="center">
That linear layout will always span from the top of screen to just above element (2), and since its gravity is "center", element (1) will always be in the middle of whatever space is available for it. Note: The line android:layout_height="..." is required, but doesn't seem to actually do anything. Whether it's fill_parent or wrap_content, its height is overridden by the lines anchoring its top to the ParentTop and its bottom to element(2). However, not having the line makes it crash with a Runtime exception.
Original, not very good idea:
Another less-than-ideal solution is to use two layout files. Put the portrait layout xml in your layout folder and the landscape layout in a new folder called layout-land. Android then automatically selects the right one based on the orientation of the phone. I think you could use layout-port, but putting the portrait one in just layout makes sure it knows which one to use by default.

Categories

Resources