I have a problem where when I click on my keyboard, the contents of my screen doesn't get pushed up--rather the keyboard simply overlaps everything (namely covers my ListView
) on my screen. This is the structure of my layout:
<ScrollView>
<RelativeLayout>
</RelativeLayout>
</ScrollView>
<ListView>
</ListView>
<LinearLayout>
<EditText></EditText>
</LinearLayout>
I nested my RelativeLayout
in a ScrollView
because I thought that would make my entire layout scrollable, which would "push up" all the layouts so that the user can view those parts while typing his or her response. I also have in my AndroidManifest.xml: android:windowSoftInputMode="adjustResize|stateVisible|stateAlwaysHidden"
Here is an image of what is happening:
And here is my code. Any help would be appreciated!
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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="match_parent" android:fitsSystemWindows="true"
xmlns:fresco="http://schemas.android.com/tools"
android:id="@+id/comments_coordinator_layout">
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/comments_appbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/comments_coordinator_layout"
>
<RelativeLayout
android:layout_marginTop="?attr/actionBarSize"
android:id="@+id/view_post"
android:layout_width="match_parent"
android:paddingRight="5dp"
android:paddingLeft="5dp"
android:orientation="horizontal"
android:layout_height="175dp"
android:background="#e6e6e6">
<com.facebook.drawee.view.SimpleDraweeView
android:layout_marginTop="15dp"
android:id="@+id/poster_picture"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_marginLeft="10dp"
fresco:placeholderImage="@mipmap/blank_prof_pic"
fresco:roundedCornerRadius="5dp"
/>
<TextView
android:layout_marginLeft="5dp"
android:layout_marginTop="15dp"
android:layout_toRightOf="@id/poster_picture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:textStyle="bold"
android:id="@+id/poster_name"/>
<TextView
android:layout_alignParentRight="true"
android:layout_marginTop="15dp"
android:layout_toRightOf="@id/poster_name"
android:layout_marginLeft="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:id="@+id/post_date"/>
<TextView
android:layout_marginLeft="5dp"
android:layout_toRightOf="@id/poster_picture"
android:layout_below="@id/poster_name"
android:textSize="20sp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/view_status" />
</RelativeLayout>
</ScrollView>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_marginTop="225dp"
android:id="@+id/lv_comments_feed"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/send_message">
</ListView>
<LinearLayout
android:id="@+id/send_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:layout_alignParentBottom="true"
android:orientation="horizontal" >
<EditText
android:id="@+id/write_comment"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:layout_weight="5"
android:gravity="top|left"
android:hint="Comment back!"
android:inputType="textMultiLine"
android:scrollHorizontally="false" />
<Button
android:id="@+id/send_comment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:gravity="center"
android:text="send"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
EDIT: My attempt to add in a parent LinearLayout
for ScrollView
. Issue is now:
The vertically scrolling ScrollView should not contain another vertically scrolling widget
when I hover over ListView
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" android:fitsSystemWindows="true"
xmlns:fresco="http://schemas.android.com/tools"
android:id="@+id/comments_coordinator_layout">
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/comments_appbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/comments_coordinator_layout"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_marginTop="?attr/actionBarSize"
android:id="@+id/view_post"
android:layout_width="match_parent"
android:paddingRight="5dp"
android:paddingLeft="5dp"
android:orientation="horizontal"
android:layout_height="175dp"
android:background="#e6e6e6">
<com.facebook.drawee.view.SimpleDraweeView
android:layout_marginTop="15dp"
android:id="@+id/poster_picture"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_marginLeft="10dp"
fresco:placeholderImage="@mipmap/blank_prof_pic"
fresco:roundedCornerRadius="5dp"
/>
<TextView
android:layout_marginLeft="5dp"
android:layout_marginTop="15dp"
android:layout_toRightOf="@id/poster_picture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:textStyle="bold"
android:id="@+id/poster_name"/>
<TextView
android:layout_alignParentRight="true"
android:layout_marginTop="15dp"
android:layout_toRightOf="@id/poster_name"
android:layout_marginLeft="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:id="@+id/post_date"/>
<TextView
android:layout_marginLeft="5dp"
android:layout_toRightOf="@id/poster_picture"
android:layout_below="@id/poster_name"
android:textSize="20sp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/view_status" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_marginTop="225dp"
android:id="@+id/lv_comments_feed"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/send_message">
</ListView>
<LinearLayout
android:id="@+id/send_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:layout_alignParentBottom="true"
android:orientation="horizontal" >
<EditText
android:id="@+id/write_comment"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:layout_weight="5"
android:gravity="top|left"
android:hint="Comment back!"
android:inputType="textMultiLine"
android:scrollHorizontally="false" />
<Button
android:id="@+id/send_comment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:gravity="center"
android:text="send"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</ScrollView>
</android.support.design.widget.CoordinatorLayout>
EDIT: I think the best solution may be to create a custom ListView
... that contains the same layout that is in each ListView
item. Any suggestions or ideas on how to implement this?
EDIT: Tried @VanillaBoy's answer. I know the image produced is because I have marginTop = 225 dp
but even if I remove it, when I click on my EditText
, it only shows my ListView
and my RelativeLayout
above is hidden
EDIT: As per @Fllo's answer, I am still able to reproduce the error I had in the beginning with this layout, and so here is what I have in my layout. Also if it helps my Android Manifest looks like this android:windowSoftInputMode="adjustResize|stateAlwaysHidden">
.
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" android:fitsSystemWindows="true"
xmlns:fresco="http://schemas.android.com/tools"
android:id="@+id/comments_coordinator_layout">
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/comments_appbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/comments_coordinator_layout"
android:fillViewport="true"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_marginTop="?attr/actionBarSize"
android:id="@+id/view_post"
android:layout_width="match_parent"
android:paddingRight="5dp"
android:paddingLeft="5dp"
android:orientation="horizontal"
android:layout_height="175dp"
android:background="#e6e6e6">
<com.facebook.drawee.view.SimpleDraweeView
android:layout_marginTop="15dp"
android:id="@+id/poster_picture"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_marginLeft="10dp"
fresco:placeholderImage="@mipmap/blank_prof_pic"
fresco:roundedCornerRadius="5dp"
/>
<TextView
android:layout_marginLeft="5dp"
android:layout_marginTop="15dp"
android:layout_toRightOf="@id/poster_picture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:textStyle="bold"
android:id="@+id/poster_name"/>
<TextView
android:layout_alignParentRight="true"
android:layout_marginTop="15dp"
android:layout_toRightOf="@id/poster_name"
android:layout_marginLeft="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:id="@+id/post_date"/>
<TextView
android:layout_marginLeft="5dp"
android:layout_toRightOf="@id/poster_picture"
android:layout_below="@id/poster_name"
android:textSize="20sp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/view_status" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:id="@+id/container_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/send_message">
</LinearLayout>
<LinearLayout
android:id="@+id/send_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:layout_alignParentBottom="true"
android:orientation="horizontal" >
<EditText
android:id="@+id/write_comment"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:layout_weight="5"
android:gravity="top|left"
android:hint="Comment back!"
android:inputType="textMultiLine"
android:scrollHorizontally="false" />
<Button
android:id="@+id/send_comment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:gravity="center"
android:text="send"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</ScrollView>
</android.support.design.widget.CoordinatorLayout>
Using an inner ListView
with ScrollView
should be avoided in Android. Indeed, these layouts have their own scroll detections and gestures. The solutions are to prevent the scroll gesture on the list or to calculate the height and expand it by default. But this will make too much work and don't respect the Android pattern and guidelines.
Instead of replace ListView
by LinearLayout
and keep the parent's ScrollView
, as my old answer pointed out, I found a possible workaround, which has these steps:
ListView
onSizeChanged()
which redraws the ListView
when keyboard is openinglastVisiblePosition
and retrieve its height in the previous methodlastVisiblePosition
and calculate the offsetheaderView
for the header picture containeronClickListener
of the
EditText
And it needs this kind of layouts:
layout's activity:
<CoordinatorLayout>
<AppBarLayout>
...
</AppBarLayout>
<RelativeLayout>
<CustomListView />
<LinearLayout>
...
</LinearLayout>
</RelativeLayout>
</CoordinatorLayout>
header's layout (which will be above the list):
<RelativeLayout>
<SimpleDraweeView />
<TextView />
...
</RelativeLayout>
Hum, that's all... So, good to go:
Listview
:public class CustomListView extends ListView {
// last height item variable (updated from Activity)
public int lastItemHeight = 0;
public CustomListView(Context context) {
super(context, null);
}
public CustomListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
onSizeChanged()
:@Override
protected void onSizeChanged(int w, final int h, int oldw, int oldh) {
// save last position visible before resize
final int lastPosition = super.getLastVisiblePosition();
// call super SizeChanged method
super.onSizeChanged(w, h, oldw, oldh);
// after resizing, show the last visible item at the bottom of new listview's height, above the edit text
// see : http://developer.android.com/reference/android/widget/AbsListView.html#setSelectionFromTop(int, int)
super.setSelectionFromTop(lastPosition, (h - lastItemHeight));
}
That's all for the ListView
.
The lastItemHeight
variable will be updated when the user clicks on the input (below the list, thanks to setting your "header" picture container as a headerView
in your Activity
).
Now, let see the Activity
:
ListView
and your Adapter
:// get custom listview element
final CustomListView list = (CustomListView) findViewById(R.id.container_list);
// example items child
ArrayList<String> items = new ArrayList<>();
for (int n=0; n<25; ++n) items.add("Blablabla n."+n);
// example adapter
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, R.layout.item_list_text_simple, android.R.id.text1, items);
HeaderView
and set the Adapter
:// prepare the header content with picture
View header = getLayoutInflater().inflate(R.layout.test_header_image, null);
// set datas to the header elements (example)
Uri uri = Uri.parse("https://raw.githubusercontent.com/facebook/fresco/gh-pages/static/fresco-logo.png");
SimpleDraweeView draweeView = (SimpleDraweeView) header.findViewById(R.id.poster_picture);
draweeView.setImageURI(uri);
// add the header to listview
list.addHeaderView(header, null, false);
// set the adapter
list.setAdapter(adapter);
EditText.setOnClickListener
:// when the user clicks on EditText...
editMessage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// set a new Thread
list.post(new Runnable() {
@Override
public void run() {
// get last position of child
int lastPosition = list.getLastVisiblePosition() - 1;
// if the list can give the view's last child
if (list.getChildAt(lastPosition) != null) {
// update the height of the last child in custom listview
list.lastItemHeight = list.getChildAt(lastPosition).getHeight();
}
}
});
}
});
That's all for the code! And the last thing (Ow.. where is the end?), here's the layouts:
Activity
:<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/comments_coordinator_layout"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent">
<android.support.v7.widget.Toolbar ... />
</android.support.design.widget.AppBarLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize">
<com.package.name.CustomListView
android:id="@+id/container_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/send_message"/>
<LinearLayout
android:id="@+id/send_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:layout_alignParentBottom="true"
android:orientation="horizontal" >
<EditText ... />
<Button ... />
</LinearLayout>
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
ListView
:<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fresco="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/view_post"
android:layout_width="match_parent"
android:layout_height="225dp"
android:paddingRight="5dp"
android:paddingLeft="5dp"
android:orientation="horizontal"
android:background="#e6e6e6">
<com.facebook.drawee.view.SimpleDraweeView ... />
<TextView ... />
<TextView ... />
<TextView ... />
</RelativeLayout>
Aw! I've finally finished. I really hope you will be able to have the right behaviour. I tested it, and it seems to work good enough.
Here's another workaround with adjustPan
, but you have to keep your list starting at the bottom. Whereas this solution keeps any child at the bottom of the list when it's resize.
Hope you'll enjoy it ;)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With