使用adjustpan

时间:2017-03-02 13:18:27

标签: android android-actionbar android-recyclerview window-soft-input-mode adjustpan

我已经坚持了很长一段时间。我正在尝试开发一个聊天模块。当SoftInputKeyboard覆盖RecyclerView的内容时,我一直陷入这个部分。我几乎尝试了adjustResizeadjustPanstateHiddenstateVisible的所有组合,但根本没有成功。

使用adjustPanActionBar隐藏了2-3个recyclerview个项目。 我附上了截图。任何帮助,不胜感激。

XML

  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/light_grey"
android:fitsSystemWindows="true"
android:focusable="true"
android:focusableInTouchMode="true">

<LinearLayout
    android:id="@+id/listFooter"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_marginTop="8dp"
    android:orientation="horizontal">

    <EditText
        android:id="@+id/messageInput"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:background="@android:color/white"
        android:hint="Write a message"
        android:inputType="textMultiLine"
        android:padding="16dp"
        android:textSize="14sp" />

    <ImageView
        android:id="@+id/sendButton"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:background="@color/colorPrimary"
        android:contentDescription="@null"
        android:padding="12dp"
        android:src="@drawable/ic_send" />
</LinearLayout>

<android.support.v7.widget.RecyclerView
    android:id="@+id/recyclerview_chat_main"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_above="@+id/listFooter"
    android:layout_marginTop="8dp" />
</RelativeLayout>
  • A)AdjustResize

With AdjustResize

  • B)使用AdjustPan

enter image description here

2 个答案:

答案 0 :(得分:1)

显示/隐藏键盘时,android:windowSoftInputMode不会为您滚动内容。

文档说:

  

adjustResize - 活动的主窗口始终调整大小,以便为屏幕上的软键盘腾出空间。

     

adjustPan - 活动的主窗口未调整大小以便为软键盘腾出空间。相反,窗口的内容是   自动平移,以便当前的焦点永远不会被遮挡   键盘和用户可以随时查看他们正在键入的内容。这是   通常不如调整大小,因为用户可能需要   关闭软键盘以进入并与模糊的部分进行交互   窗口。

基本上这意味着adjustResize会使您的rootview更小,并将softKeyboard放在它下面。 adjustPan将根视图的上半部分推出屏幕,为softKeyboard腾出空间。

我建议使用adjustResize,因为它不会将您的工具栏推出屏幕。然后你必须自己滚动内容。说起来容易做起来难,但是有一些方法可以做到这一点。

首先,您必须在recyclerview中获取最后一个可见项目位置。

//class variable
private int lastVisiblePosition = 0;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    //...
    recyclerview_chat_main.addOnScrollListener(new RecyclerView.OnScrollListener()
    {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy)
        {
            super.onScrolled(recyclerView, dx, dy);
            lastVisiblePosition = ((LinearLayoutManager)recyclerView.getLayoutManager()).findLastVisibleItemPosition();
        }
    });
    //...
}

然后你需要做的是在显示SoftKeyboard时滚动到那个项目,问题是当键盘显示时没有内置的方法,幸运的是有人已经在这里解决了这个问题:{{3} }

使用Jaap的答案我们可以添加如下内容:

//class variables
private ViewGroup rootLayout = null;
private ViewTreeObserver.OnGlobalLayoutListener keyboardLayoutListener = null;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    //...
    ViewGroup rootLayout = (ViewGroup)findViewById(android.R.id.content);
    keyboardLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener()
    {
        @Override
        public void onGlobalLayout()
        {
            int heightDiff = rootLayout.getRootView().getHeight() - rootLayout.getHeight();
            int contentViewTop = getWindow().findViewById(Window.ID_ANDROID_CONTENT).getHeight();

            if(heightDiff > contentViewTop)
            {
                recyclerview_chat_main.getLayoutManager().scrollToPosition(lastVisiblePosition);
            }
        }
    };
    rootLayout.getViewTreeObserver().addOnGlobalLayoutListener(keyboardLayoutListener);
    //...
}

最后,当活动被破坏时,不要忘记删除全局侦听器:

@Override
protected void onDestroy()
{
    super.onDestroy();
    if(rootLayout != null && keyboardLayoutListener != null)
        rootLayout.getViewTreeObserver().removeOnGlobalLayoutListener(keyboardLayoutListener);
}

答案 1 :(得分:1)

接受的答案对我不起作用。 这有效:

在清单的活动标签中,添加 android:windowSoftInputMode =“ adjustResize”

在活动的 onCreate 方法中添加以下内容:

View.OnLayoutChangeListener layoutChangeListener = new View.OnLayoutChangeListener()
{
    @Override
    public void onLayoutChange(View v, int left, final int top, int right, final int bottom,
                        int oldLeft, final int oldTop, int oldRight, final int oldBottom)
    {
        if (oldBottom != 0)
        {
            //when softkeyboard opens, the height of layout get's small, and when softkeyboa
            //-rd closes the height grows back(gets larger).We can find the change of height
            // by doing oldBotton - bottom, and the result of subtraction is how much we nee
            //-d to scroll. Change of height is positive if keyboard is opened, and negative
            //if it's closed.
            int pixelsToScrollVertically = oldBottom - bottom;
            recyclerView.scrollBy(0, pixelsToScrollVertically);
        }
    }
};


myAdapter = new MyAdapter();
recyclerView.setAdapter(myAdapter);

recyclerView.addOnLayoutChangeListener(layoutChangeListener);