键盘覆盖了屏幕而不是推上布局?

5

我有一个问题,当我在键盘上点击时,屏幕上的内容不会被推上去 - 相反,键盘只是覆盖了我的屏幕上的所有内容(即覆盖了我的ListView)。这是我的布局结构:

<ScrollView>
  <RelativeLayout>
  </RelativeLayout>
</ScrollView>
<ListView>
</ListView>
<LinearLayout>
  <EditText></EditText>
</LinearLayout>

我将我的RelativeLayout放在ScrollView中,因为我认为这样可以使整个布局可滚动,这样就可以将所有布局“向上推”,以便用户在输入响应时查看那些部分。我还在AndroidManifest.xml中添加了以下内容:android:windowSoftInputMode="adjustResize|stateVisible|stateAlwaysHidden" 这里是正在发生的情况的图像:

Image of what is happening

以下是我的代码。任何帮助将不胜感激!

<?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>

编辑:我尝试为ScrollView添加父级LinearLayout。问题现在是: 当我悬停在ListView上时,垂直滚动的ScrollView不应包含另一个垂直滚动的小部件。

<?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>

编辑:我认为最好的解决方案可能是创建一个自定义 ListView... 包含每个 ListView 项目中相同的布局。有关如何实现此操作的任何建议或想法?

编辑:尝试了 @VanillaBoy 的答案。我知道生成的图像是因为我有 marginTop = 225 dp,但即使我将其删除,当我单击我的 EditText 时,它仅显示我的 ListView,而上面的 RelativeLayout 被隐藏了。 Image

编辑:根据 @Fllo 的答案,我仍然能够重现我在此布局中一开始遇到的错误,因此这是我在布局中拥有的内容。如果有帮助,我的 Android Manifest 看起来像这样 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>

@AnswerDroid:我不能将应用栏布局之后的所有内容放入滚动视图中,因为那里有一个ListView,这样会产生两个垂直滚动视图。你还有其他建议吗? - user1871869
@ShreyansSheth 我尝试将所有内容嵌套在一起,但我无法将我的 ListView 嵌入 ScrollView 中,因为这会有 2 个垂直滚动条,这是不允许的。你还有其他想法吗? - user1871869
尝试将此内容粘贴到XML文件中并运行。当然,如果不起作用,那么Ctrl+ Z:P http://ideone.com/C3YxKs。我知道您无法按照这些行动进行操作,但是如果您不嵌套它,则这些特定容器不会可滚动。 - gabbar0x
将文件发送给@ShreyansSheth,然后会出现以下错误提示:java.lang.IllegalStateException: ScrollView can host only one direct child。还有其他建议吗?或者是否可能创建自定义列表视图? - user1871869
@ShreyansSheth 你发布的两个文件完全相同。我已经采纳了Fllo的建议,并将我的修改发布在我的问题中,但是当我在XML文件中悬停在我的ListView元素上时,会出现错误提示:“垂直滚动的ScrollView不应包含另一个垂直滚动的小部件”。 - user1871869
显示剩余9条评论
2个回答

1
在Android中应避免使用内部ListViewScrollView。实际上,这些布局有自己的滚动检测和手势。解决方案是防止列表上的滚动手势或计算高度并默认展开。但这将需要太多工作,而且不符合Android的模式和指南。
与其像我之前的回答所指出的那样,用LinearLayout替换ListView并保留父级的ScrollView,我发现了一个可能的解决方法,其中包括以下步骤:
  • 创建自己的ListView
  • 重写onSizeChanged()方法,在键盘打开时重新绘制ListView
  • 获取lastVisiblePosition并在上述方法中检索其高度
  • 最后,将列表移动到之前的lastVisiblePosition并计算偏移量
  • 此外,为标题图片容器设置一个headerView
  • 还需要在用户打开键盘之前更新子项的高度,因此可以在EditTextonClickListener中更新该值

而且它需要这种布局:

  • 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>
    

嗯,就这些了... 那么,可以开始:

创建一个 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));
}

这就是关于ListView的全部内容。
当用户点击输入框时(感谢将您的“header”图片容器设置为Activity中的headerView),lastItemHeight变量将会被更新。

现在,让我们来看看Activity

设置自定义的ListViewAdapter

// 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并设置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();
                }
            }
        });
    }
});

这就是所有的代码!最后一件事情(哦..结尾在哪里?),这是布局:

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>

哎呀!我终于完成了。我真的希望你能够拥有正确的行为。我进行了测试,它似乎足够好用。
这里是另一种解决方法,使用adjustPan,但您必须将列表保持在底部。而此解决方案可以在调整大小时将任何子元素保持在列表底部。

希望你会喜欢它;)


哇,非常感谢您。您的逻辑完全有道理。不幸的是,我仍然遇到了一开始就遇到的同样问题。我设置了我的 ScrollView fillViewPorts=true,以便我的 container_list 可以扩展。我在 Java 方面逐步按照您的所有说明进行操作,但我认为我的 XML 文件可能有问题?但我不知道哪里出了问题...我已经发布了我所拥有的内容。 - user1871869
奇怪的是我的视图甚至无法滚动...我不知道为什么! - user1871869
我甚至尝试将我的ScrollView更改为NestedScrollView,但似乎无法膨胀它,因为它显示android.view.InflateException: Binary XML file line #2: Error inflating class NestedScrollView - user1871869
是的,这种布局可能会很丑,但可以实现你想要的效果。我之前在使用LinearLayout时也遇到了同样的问题,即缺少滚动事件。最后我找到了一个解决方法,但相比于将ListView替换为LinearLayout,它需要更多的工作。相反,我找到了一种方法来保持你的列表,但不使用ScrollView。@user1871869,你能确认你的最终愿望是在窗口调整大小时保持子项在EditText上方吗?我会编辑我的答案,列出我找到的所有步骤。 - Blo
是的,那正是我的心愿。我在这方面遇到了很多困难,但你所说的确实是我想要的。感谢您帮助我度过这一切,我非常感激。 - user1871869
太好了。非常感谢! - user1871869

1
在你的清单文件中的 Activity 标签下添加这段代码。
<activity .......
....................
android:windowSoftInputMode="adjustResize"/>

我已经将它放入我的活动中了。还有其他建议吗? - user1871869
android:windowSoftInputMode="adjustPan"安卓:窗口软输入模式="调整面板" - Gaurav
我已经尝试过了,但如果我使用adjustPan,那么只有我的ListView显示出来,而我的RelativeLayout则被隐藏了。 - user1871869
@GauravPolekar adjustPan 不同于 adjustResize :“这通常不如调整大小理想,因为用户可能需要关闭软键盘才能访问和与窗口的被遮挡部分进行交互。” - Blo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接