Android: cambie el tamaño solo de las partes de la vista con el teclado suave en la pantalla

Tengo una vista con un campo Edittext sobre un ImageView. Cuando aparece el teclado, quiero que la ventana cambie de tamaño para que EditText ya no esté oculto por el teclado. En el archivo AndroidManifest, declare android:windowSoftInputMode="adjustResize" y la pantalla android:windowSoftInputMode="adjustResize" tamaño, pero el problema es que quiero que ImageView no se vuelva a clasificar según el tamaño. ¿Cómo puedo hacer que ImageView no se vea afectado?

¿Puedo inflar un diseño adicional solo con ImageView o el tamaño aún lo afectará? enter image description here

    La solución completa implica algunos puntos clave

    • Use RelativeLayout , para que las Views puedan configurarse para superponerse entre sí
    • Alinee EditText con la parte inferior de Windows usando android:layout_alignParentBottom="true"
    • Use android:windowSoftInputMode="adjustResize" en su manifiesto, de modo que la parte inferior de la Window cambie cuando aparezca el teclado (como mencionó)
    • Coloque ImageView dentro de ScrollView para que ImageView pueda ser más grande que Window , y desactive el desplazamiento en ScrollView usando ScrollView#setEnabled(false)

    Aquí está el archivo de diseño

           

    Aquí está mi actividad

     package com.so3; import android.app.Activity; import android.os.Bundle; import android.widget.ScrollView; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ScrollView sv = (ScrollView)findViewById(R.id.scroll); sv.setEnabled(false); } } 

    Mi AndroidManifiesto

     < ?xml version="1.0" encoding="utf-8"?>           

    Capturas de pantalla de mi solución

    captura de pantalla 1captura de pantalla 2

     final View activityRootView = findViewById(R.id.mainScroll); activityRootView.getViewTreeObserver().addOnGlobalLayoutListener( new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { int heightView = activityRootView.getHeight(); int widthView = activityRootView.getWidth(); if (1.0 * widthView / heightView > 1) { Log.d("keyboarddddd visible", "no"); relativeLayoutForImage.setVisibility(View.GONE); relativeLayoutStatic.setVisibility(View.GONE); //Make changes for Keyboard not visible } else { Log.d("keyboarddddd visible ", "yes"); relativeLayoutForImage.setVisibility(View.VISIBLE); relativeLayoutStatic.setVisibility(View.VISIBLE); //Make changes for keyboard visible } } }); 

    Para mí, no quería suponer que las alturas de los teclados son una medida determinada. Cualquiera que sea su punto de vista sobre cómo hacer un onTouchListener y luego hacer esto:

      setOnTouchListener(new OnTouchListener() { Runnable shifter=new Runnable(){ public void run(){ try { int[] loc = new int[2]; //get the location of someview which gets stored in loc array findViewById(R.id.someview).getLocationInWindow(loc); //shift so user can see someview myscrollView.scrollTo(loc[0], loc[1]); } catch (Exception e) { e.printStackTrace(); } }} }; Rect scrollBounds = new Rect(); View divider=findViewById(R.id.someview); myscollView.getHitRect(scrollBounds); if (!divider.getLocalVisibleRect(scrollBounds)) { // the divider view is NOT within the visible scroll window thus we need to scroll a bit. myscollView.postDelayed(shifter, 500); } }); 

    // esencialmente hacemos un ejecutable que se desplaza a una nueva ubicación de alguna vista que QUIERES que aparezca en la pantalla. ejecuta ese ejecutable solo si no está dentro de los límites de scrollviews (no está en la pantalla). De esta forma, cambia la vista de desplazamiento a la vista de referencia (en mi caso, ‘someview’, que era un divisor de línea).

    En mi opinión, la forma más fácil de hacerlo es esta combinación de los dos cambios :

     android:windowSoftInputMode="adjustResize" 

    en tu AndroidManifest.xml

    +

     getWindow().setBackgroundDrawable(your_image_drawable); 

    en su actividad en el método @onCreate ()

    Esto funciona para mi.

    La mejor solución es usar un DialogFragment

    Mostrar diálogo

     DialogFragment.show(getSupportFragmentManager(), DialogFragment.TAG); 

    Pantalla completa

     @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { Dialog dialog = new Dialog(getActivity(), R.style.MainDialog) { //set the style, the best code here or with me, we do not change @Override public void onBackPressed() { super.onBackPressed(); getActivity().finish(); } }; return dialog; } 

    Estilo

      

    Actividad de diseño

     < ?xml version="1.0" encoding="utf-8"?>    

    Fragmento de diálogo de diseño

     < ?xml version="1.0" encoding="utf-8"?>       

    Agregar ScrollView hacía que mi imagen se desplazara, lo que quería evitar, así que usé esta calculadora samples-keyboardheight y en la posición recalculada en el teclado onKeyboardHeightChanged de la parte inferior de Edittext colocada sobre el teclado y usé esta bandera en Manifest.

     android:windowSoftInputMode="adjustNothing|stateHidden" 

    Aquí está KeyboardHeightProvider :

     import android.app.Activity; import android.content.res.Configuration; import android.graphics.Point; import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.WindowManager.LayoutParams; import android.widget.PopupWindow; /** * The keyboard height provider, this class uses a PopupWindow * to calculate the window height when the floating keyboard is opened and closed. */ public class KeyboardHeightProvider extends PopupWindow { /** The tag for logging purposes */ private final static String TAG = "sample_KeyboardHeightProvider"; /** The keyboard height observer */ private KeyboardHeightObserver observer; /** The cached landscape height of the keyboard */ private int keyboardLandscapeHeight; /** The cached portrait height of the keyboard */ private int keyboardPortraitHeight; /** The view that is used to calculate the keyboard height */ private View popupView; /** The parent view */ private View parentView; /** The root activity that uses this KeyboardHeightProvider */ private Activity activity; /** * Construct a new KeyboardHeightProvider * * @param activity The parent activity */ public KeyboardHeightProvider(Activity activity) { super(activity); this.activity = activity; LayoutInflater inflator = (LayoutInflater) activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); this.popupView = inflator.inflate(R.layout.popupwindow, null, false); setContentView(popupView); setSoftInputMode(LayoutParams.SOFT_INPUT_ADJUST_RESIZE | LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); parentView = activity.findViewById(android.R.id.content); setWidth(0); setHeight(LayoutParams.MATCH_PARENT); popupView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { if (popupView != null) { handleOnGlobalLayout(); } } }); } /** * Start the KeyboardHeightProvider, this must be called after the onResume of the Activity. * PopupWindows are not allowed to be registered before the onResume has finished * of the Activity. */ public void start() { if (!isShowing() && parentView.getWindowToken() != null) { setBackgroundDrawable(new ColorDrawable(0)); showAtLocation(parentView, Gravity.NO_GRAVITY, 0, 0); } } /** * Close the keyboard height provider, * this provider will not be used anymore. */ public void close() { this.observer = null; dismiss(); } /** * Set the keyboard height observer to this provider. The * observer will be notified when the keyboard height has changed. * For example when the keyboard is opened or closed. * * @param observer The observer to be added to this provider. */ public void setKeyboardHeightObserver(KeyboardHeightObserver observer) { this.observer = observer; } /** * Get the screen orientation * * @return the screen orientation */ private int getScreenOrientation() { return activity.getResources().getConfiguration().orientation; } /** * Popup window itself is as big as the window of the Activity. * The keyboard can then be calculated by extracting the popup view bottom * from the activity window height. */ private void handleOnGlobalLayout() { Point screenSize = new Point(); activity.getWindowManager().getDefaultDisplay().getSize(screenSize); Rect rect = new Rect(); popupView.getWindowVisibleDisplayFrame(rect); // REMIND, you may like to change this using the fullscreen size of the phone // and also using the status bar and navigation bar heights of the phone to calculate // the keyboard height. But this worked fine on a Nexus. int orientation = getScreenOrientation(); int keyboardHeight = screenSize.y - rect.bottom; if (keyboardHeight == 0) { notifyKeyboardHeightChanged(0, orientation); } else if (orientation == Configuration.ORIENTATION_PORTRAIT) { this.keyboardPortraitHeight = keyboardHeight; notifyKeyboardHeightChanged(keyboardPortraitHeight, orientation); } else { this.keyboardLandscapeHeight = keyboardHeight; notifyKeyboardHeightChanged(keyboardLandscapeHeight, orientation); } } /** * */ private void notifyKeyboardHeightChanged(int height, int orientation) { if (observer != null) { observer.onKeyboardHeightChanged(height, orientation); } } public interface KeyboardHeightObserver { void onKeyboardHeightChanged(int height, int orientation); } } 

    popupwindow.xml:

     < ?xml version="1.0" encoding="utf-8"?>  

    Aquí está MainActivity.java :

     import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.view.ViewGroup; public class MainActivity extends AppCompatActivity implements KeyboardHeightProvider.KeyboardHeightObserver { private KeyboardHeightProvider keyboardHeightProvider; private ViewGroup relativeView; private float initialY; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); keyboardHeightProvider = new KeyboardHeightProvider(this); relativeView = findViewById(R.id.bottomEditor); relativeView.post(() -> initialY = relativeView.getY()); View view = findViewById(R.id.activitylayout); view.post(() -> keyboardHeightProvider.start()); } @Override public void onKeyboardHeightChanged(int height, int orientation) { if(height == 0){ relativeView.setY(initialY); relativeView.requestLayout(); }else { float newPosition = initialY - height; relativeView.setY(newPosition); relativeView.requestLayout(); } } @Override public void onPause() { super.onPause(); keyboardHeightProvider.setKeyboardHeightObserver(null); } @Override public void onResume() { super.onResume(); keyboardHeightProvider.setKeyboardHeightObserver(this); } @Override public void onDestroy() { super.onDestroy(); keyboardHeightProvider.close(); } } 

    activity_main.xml :

     < ?xml version="1.0" encoding="utf-8"?>        

    PD: el código de cálculo de altura del teclado se copia de siebeprojects

    Aquí está la aplicación de ejemplo de demostración de implementación.

    La solución que funcionó para mí fue en AndroidManifest.xml en esa etiqueta de actividad que acabo de poner

     android:windowSoftInputMode="stateHidden|adjustResize|adjustNothing" 

    Todo listo … Espero que esto funcione para ti.

      final View activityRootView = findViewById(R.id.mainScroll); activityRootView.getViewTreeObserver().addOnGlobalLayoutListener( new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { int heightView = activityRootView.getHeight(); int widthView = activityRootView.getWidth(); if (1.0 * widthView / heightView > 1) { Log.d("keyboarddddd visible", "no"); relativeLayoutForImage.setVisibility(View.GONE); relativeLayoutStatic.setVisibility(View.GONE); //Make changes for Keyboard not visible //relativeLayoutForImage.setVisibility(View.VISIBLE); //relativeLayoutStatic.setVisibility(View.VISIBLE); } else { Log.d("keyboarddddd visible ", "yes"); relativeLayoutForImage.setVisibility(View.VISIBLE); relativeLayoutStatic.setVisibility(View.VISIBLE); //Make changes for keyboard visible // relativeLayoutForImage.setVisibility(View.GONE); //relativeLayoutStatic.setVisibility(View.GONE); } } });