0

У меня есть макет, как это страницы с видом Пейджер:«Push Up» в ListView, но не бар, когда мягкий вход показан

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="@android:color/black"> 
    <LinearLayout 
     android:id="@+id/bar" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="24dp" 
     android:layout_alignParentTop="true" 
     android:orientation="horizontal" 
     android:gravity="center" 
     android:background="@drawable/background_gray"> 
     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:textSize="16sp" 
      android:paddingTop="15dp" 
      android:paddingBottom="15dp" 
      android:paddingLeft="3dp" /> 
    </LinearLayout> 
    <RelativeLayout 
     android:id="@+id/container_chat_box" 
     android:background="@drawable/conversation_background_gray" 
     android:layout_alignParentBottom="true" 
     android:layout_marginBottom="50dp"> 
     <EditText 
      android:id="@+id/chat_box" 
      style="@style/ConversationChatBox" /> 
    </RelativeLayout> 
    <ListView 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_below="@+id/bar" 
     android:background="@android:color/white" 
     android:stackFromBottom="true" 
     android:transcriptMode="normal" 
     android:layout_above="@id/chat_box" 
     android:paddingBottom="15dp" 
     android:clipToPadding="false" 
     android:divider="@null" 
     android:dividerHeight="0dp" 
     android:listSelector="@android:color/transparent" /> 
</RelativeLayout> 

Это идея о том, как он выглядит:

---------- 
[ bar ] 
[list view] 
[list view] 
[list view] 
[list view] 
[edit text] 

Когда я нажимаю на текст редактирования, я хотел бы бар, чтобы остаться там, где она находится (в верхней части экрана), но представление списка для толкания вверх, так что она выглядит следующим образом:

------------ 
[ bar ] 
[list view] 
[list view] 
[edit text] 
[keyboard ] 

Что я получаю (бар выталкивается вверх и исчезает):

------------ 
[list view] 
[list view] 
[list view] 
[edit text] 
[keyboard ] 

У меня есть это на моем AndroidManifest:

android:windowSoftInputMode="adjustPan"

Я пробовал разные комбинации значений для установки android:windowSoftInputMode, но я либо получить клавиатуру, чтобы она отображалась в текстовом редакторе или весь экран, нажатый вверх.

Есть ли способ сохранить планку на месте, пока список переместится вверх? Заранее спасибо.

+0

Попробуйте установить андроид: layout_height = «match_parent» для ListView – TpoM6oH

+0

Спасибо за ответ. Это не изменило макет. Интересно, связана ли проблема с использованием android: layout_alignParentTop = "true" в линейке Linear Layout. Но я не могу придумать более правильный способ держать панель в верхней части экрана. – Marilia

+0

Я изменил режим мягкого ввода на: android: windowSoftInputMode = "adjustResize" и добавил android: fitsSystemWindows = "true" к внешнему макету. Последовал некоторый код из [этого сообщения] (http://stackoverflow.com/questions/7417123/android-how-to-adjust-layout-in-full-screen-mode-when-softkeyboard-is-visible), и теперь все работает, за исключением черной спины, которая появляется внизу (поскольку обходной путь в сообщении фиксирует только верхнее, левое и правое поля). – Marilia

ответ

0

Я смог решить проблему, хотя до сих пор тестировался только на нескольких телефонах.

Это решение:

1) Изменить режим плавного ввода для андроида: windowSoftInputMode = «adjustResize» и добавить андроид: fitsSystemWindows = «истина» в целях корневой макет.

2) Создал класс CustomInsetsLayout, который расширяет RelativeLayout (код ниже), поэтому я могу контролировать, что происходит с макетом при изменении размера экрана.

3) В этот момент у меня была нежелательная черная полоса в нижней части макета. Этот бар был нижним краем, который должен был быть скрыт под навигационной панелью, но флаги FULLSCREEN, ответственные за это, не работают с adjustResize. Поэтому мне пришлось добавить код в CustomInsetsLayout, чтобы удалить нижнее поле из корневого представления при изменении размера экрана.

Вот как класс CustomInsetsLayout выглядит (ссылки и примечания в описании класса):

package com.playchat.ui.full; 

import android.content.Context; 
import android.graphics.Rect; 
import android.os.Build; 
import android.util.AttributeSet; 
import android.view.WindowInsets; 
import android.widget.RelativeLayout; 

/** 
* http://stackoverflow.com/questions/21092888/windowsoftinputmode-adjustresize-not-working-with-translucent-action-navbar 
* 
* @author Kevin 
*   Date Created: 3/7/14 
* 
* https://code.google.com/p/android/issues/detail?id=63777 
* 
* When using a translucent status bar on API 19+, the window will not 
* resize to make room for input methods (i.e. 
* {@link android.view.WindowManager.LayoutParams#SOFT_INPUT_ADJUST_RESIZE} and 
* {@link android.view.WindowManager.LayoutParams#SOFT_INPUT_ADJUST_PAN} are 
* ignored). 
* 
* To work around this; override {@link #fitSystemWindows(android.graphics.Rect)}, 
* capture and override the system insets, and then call through to FrameLayout's 
* implementation. 
* 
* For reasons yet unknown, modifying the bottom inset causes this workaround to 
* fail. Modifying the top, left, and right insets works as expected. 
*/ 
public class CustomInsetsLayout extends RelativeLayout { 
    private int[] mInsets = new int[4]; 

    public CustomInsetsLayout(Context context) { 
     super(context); 
    } 

    public CustomInsetsLayout(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public CustomInsetsLayout(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    public final int[] getInsets() { 
     return mInsets; 
    } 

    @Override 
    protected final boolean fitSystemWindows(Rect insets) { 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 
      // Intentionally do not modify the bottom inset. For some reason, 
      // if the bottom inset is modified, window resizing stops working. 
      // TODO: Figure out why. 
      mInsets[0] = insets.left; 
      mInsets[1] = insets.top; 
      mInsets[2] = insets.right; 

      insets.left = 0; 
      insets.top = 0; 
      insets.right = 0; 

      if (insets.bottom > 0) { 
       // Remove bottom margin from the root view 
       RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) getLayoutParams(); 
       params.bottomMargin = 0; 
       setLayoutParams(params); 

      } 
     } 

     return super.fitSystemWindows(insets); 
    } 

    @Override 
    public final WindowInsets onApplyWindowInsets(WindowInsets insets) { 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) { 
      if (insets.getSystemWindowInsetBottom() > 0) { 
       // Remove bottom margin from the root view 
       RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) getLayoutParams(); 
       params.bottomMargin = 0; 
       setLayoutParams(params); 

      } 
      mInsets[0] = insets.getSystemWindowInsetLeft(); 
      mInsets[1] = insets.getSystemWindowInsetTop(); 
      mInsets[2] = insets.getSystemWindowInsetRight(); 
      return super.onApplyWindowInsets(insets.replaceSystemWindowInsets(0, 0, 0, 
       insets.getSystemWindowInsetBottom())); 

     } else { 
      return insets; 
     } 
    } 
}