2010-11-26 14 views
107

Cada vez que aparece el teclado del software, cambia el tamaño de la imagen de fondo. Se refieren a la pantalla de abajo:El teclado del software cambia el tamaño de la imagen de fondo en Android

Como se puede ver, el fondo es una especie de exprimido. ¿Alguien puede arrojar luz sobre por qué el fondo cambia de tamaño?

Mi diseño es el siguiente:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:background="@drawable/page_bg" 
    android:isScrollContainer="false" 
> 
    <LinearLayout android:layout_height="wrap_content" 
     android:orientation="horizontal" 
     android:layout_width="fill_parent" 
    > 
     <EditText android:id="@+id/CatName" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:layout_weight="1" 
      android:inputType="textCapSentences" 
      android:lines="1" 
     /> 
     <Button android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="@string/save" 
      android:onClick="saveCat" 
     /> 
    </LinearLayout> 
    <ImageButton 
     android:id="@+id/add_totalk" 
     android:layout_height="wrap_content" 
     android:layout_width="wrap_content" 
     android:background="@null" 
     android:src="@drawable/add_small" 
     android:scaleType="center" 
     android:onClick="createToTalk" 
     android:layout_marginTop="5dp" 
    /> 
</LinearLayout> 

Respuesta

163

Ok me fijo mediante el uso de

android:windowSoftInputMode="stateVisible|adjustPan" 

entrada dentro <Activity > etiqueta en manifest archivo. Creo que fue causado por tener ScrollView dentro de la Actividad.

+2

El problema es que el desplazamiento es, al usar adjustPan, no funciona ... (si tiene un ScrollView), y eso es molesto ... – Ted

+3

Pero la vista de desplazamiento no funciona ahora. para evitarlo –

+0

Necesito la vista de desplazamiento. ¿Tiene una manera de mantener la vista de desplazamiento y mantener el fondo sin comprimir? –

1

añadir esta línea en el archivo AndroidManifest.xml :

android:windowSoftInputMode=adjustUnspecified 

se refieren a this link para obtener más información.

+0

Todavía está sucediendo incluso después de hacer esto. Esto se está volviendo frustrante :( –

14

sólo para ... Además

si tienes una vista de lista de su actividad u necesidad de añadir este android:isScrollContainer="false" en las propiedades de vista de lista ...

y no se olvide de añadir en su android:windowSoftInputMode="adjustPan" xml manifiesta en su actividad ...

si ustedes utilizando android:windowSoftInputMode="adjustUnspecified" con vista desplazable en su diseño, su fondo todavía se cambie el tamaño del teclado suave ...

sería mejor si usa el valor "adjustPan" para evitar que su fondo cambie de tamaño ...

+2

android: windowSoftInputMode = "adjustPan" hace que toda la vista cambie con el teclado. Generalmente tenemos un título de la pantalla en la parte superior. Al usar esta bandera, también saldrá del área visible, lo que hará que la experiencia del usuario sea mala. – Gem

+0

@Gem: ¿cuál es la solución? – Copernic

+0

@Copernic Me enfrenté a este problema hace mucho tiempo cuando estaba trabajando en una aplicación de chat. Eventualmente lo arreglé, por favor remita mi respuesta aquí: http://stackoverflow.com/questions/5307264/how-to-prevent-soft-keyboard-from-resizing-background-image/23651818#23651818 – Gem

96

Me enfrenté al mismo problema al desarrollar una aplicación de chat, pantalla de chat con una imagen de fondo. android:windowSoftInputMode="adjustResize" exprimí mi imagen de fondo para que se ajustara al espacio disponible después de que se visualizara el teclado virtual y "adjustPan" cambió toda la distribución para ajustar el teclado virtual. La solución a este problema fue establecer el fondo de la ventana en lugar de un fondo de diseño dentro de un XML de actividad. Use getWindow().setBackgroundDrawable() en su actividad.

+2

¡Muy bien! ¡La mejor respuesta! adjustPan causa efectos colaterales como: El teclado anula los componentes pero no se muestran barras de desplazamiento. – CelinHC

+3

@parulb o cualquier otra persona que lea esto, funciona muy bien (y gracias por ello) siempre que la imagen de fondo no contenga información relevante. El problema que encuentro de vez en cuando es que mi fondo contendrá algo así como un logotipo, y establecer el fondo de la ventana en la imagen oculta el logotipo detrás de la barra de acciones. Para ciertas pantallas esto no es un problema, pero a veces estoy obligado a mantener la barra de acciones (sin ocultar). ¿Alguna idea sobre cómo manejar algún tipo de relleno mientras configura el fondo de la ventana para tener en cuenta a ActionBar? – zgc7009

+0

¿Qué pasa si estoy teniendo un fragmento de cómo tratar con él? no funciona para los fragmentos – user2056563

4

En caso de que si alguien necesita un comportamiento adjustResize y no quería que su ImageView a ser redimensionada Aquí hay otra solución:

ImageView Sólo hay que poner en el interior ScrollView => RelativeLayout con ScrollView.fillViewport = true.

<ScrollView 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:fillViewport="true"> 

    <RelativeLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"> 

     <FrameLayout 
      android:layout_width="100dp" 
      android:layout_height="100dp"> 

      <ImageView 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:scaleType="fitXY" 
       android:src="@drawable/gift_checked" /> 
     </FrameLayout> 
    </RelativeLayout> 
</ScrollView> 
+1

Esta es una buena solución en caso de que tenga otras vistas en el fondo que no sean una imagen .... Gracias –

19

Aquí está la mejor solución para evitar ese tipo de problema. Paso 1: crear un estilo

<style name="ChatBackground" parent="AppBaseTheme"> 
     <item name="android:windowBackground">@drawable/bg_chat</item> 
    </style> 

Paso 2: Fija tu estilo actividad en el AndroidManifest archivo

<activity 
      android:name=".Chat" 
      android:screenOrientation="portrait" 
      android:theme="@style/ChatBackground" > 
+1

¡Lo único que funcionó para mí! thnx – Reyske

+0

¡agradable! La solución más simple –

+0

funciona perfectamente para mí – Amit

22

a través de Android: windowSoftInputMode = "adjustPan" dar mala experiencia del usuario, ya través de que toda la pantalla va por la parte superior (desplazarse hacia arriba) Entonces, seguir es una de las mejores respuestas.

Tengo mismo problema pero después de eso, me encontré con answeres impresionantes de la @Gem

en el manifiesto

android:windowSoftInputMode="adjustResize|stateAlwaysHidden" 

En xml

Dont Conjunto cualquier fondo aquí y mantener su vista en ScrollView

En Java

Deberá ajustar el fondo de pantalla:

getWindow().setBackgroundDrawableResource(R.drawable.bg_wood) ; 

Gracias a @Gem.

+0

Gracias por el reconocimiento. – Gem

4

Me encontré con el problema principal al trabajar en mi aplicación. Al principio, utilizo el método provisto por @parulb para resolver el problema. Agradézcale mucho Pero más tarde noté que la imagen de fondo está parcialmente oculta por la barra de acciones (y la barra de estado estoy seguro). Este pequeño problema ya ha sido propuesto por @ zgc7009, quien comentó a continuación la respuesta de @parulb hace un año y medio, pero nadie contestó.

Trabajé todo un día para encontrar una forma y, afortunadamente, al menos ahora puedo resolver este problema perfectamente en mi teléfono móvil.

Primero necesitamos un recurso de capa-lista en la carpeta estirable para agregar relleno en la parte superior de la imagen de fondo:

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

<layer-list 
    xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:top="75dp"> 
     <bitmap android:src="@drawable/bg" /> 
    </item> 
</layer-list> 

En segundo lugar hemos creado este archivo como recurso para el fondo como se mencionó anteriormente:

getWindow().setBackgroundDrawableResource(R.drawable.my_background); 

Estoy usando Nexus 5. Encontré una manera de obtener la altura de la barra de acciones en xml pero no en la barra de estado, así que tengo que usar una altura fija de 75dp para el relleno superior. Espero que cualquiera pueda encontrar la última pieza de este rompecabezas.

1

Sufrí problemas similares, pero parece que usar adjustPan con android:isScrollContainer="false" aún no solucionó mi diseño (que era un RecyclerView debajo de un LinearLayout). The RecyclerView estaba bien, pero cada vez que aparecía el teclado virtual, el LinearLayout se reajustaba.

Para evitar este comportamiento (Yo simplemente quería tener el teclado ir por encima de mi diseño), fui con el siguiente código:

<activity 
     android:name=".librarycartridge.MyLibraryActivity" 
     android:windowSoftInputMode="adjustNothing" /> 

Esto le dice a Android para dejar básicamente su diseño solo cuando el teclado virtual es llamado.

Se pueden encontrar más lecturas sobre las posibles opciones here (aunque, curiosamente, no parece que haya una entrada para adjustNothing).

0

Me enfrenté con el mismo promlem y ninguna solución me satisfizo porque utilicé el fragmento como una capa sobre otro fragmento, así que getActivity().getWindow().setBackgroundDrawable() no funcionó para mí. Mi solución fue anular FrameLayout con lógica para manejar el teclado que aparece y cambiar el mapa de bits sobre la marcha. Esa es mi FrameLayout (Kotlin):

`FlexibleFrameLayout clase: FrameLayout {

var backgroundImage: Drawable? = null 
    set(bitmap) { 
     field = bitmap 
     invalidate() 
    } 
private var keyboardHeight: Int = 0 
private var isKbOpen = false 

private var actualHeight = 0 

constructor(context: Context) : super(context) { 
    init() 
} 

constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet) { 
    init() 
} 

fun init() { 
    setWillNotDraw(false) 
} 

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec) 
    val height = MeasureSpec.getSize(heightMeasureSpec) 
    if (actualHeight == 0) { 
     actualHeight = height 
     return 
    } 
    //kb detected 
    if (actualHeight - height > 100 && keyboardHeight == 0) { 
     keyboardHeight = actualHeight - height 
     isKbOpen = true 
    } 
    if (actualHeight - height < 50 && keyboardHeight != 0) { 
     isKbOpen = false 
    } 
    if (height != actualHeight) { 
     invalidate() 
    } 
} 

override fun onDraw(canvas: Canvas) { 
    if (backgroundImage != null) { 
     if (backgroundImage is ColorDrawable) { 
      backgroundImage!!.setBounds(0, 0, measuredWidth, measuredHeight) 
      backgroundImage!!.draw(canvas) 
     } else if (backgroundImage is BitmapDrawable) { 
      val scale = measuredWidth.toFloat()/backgroundImage!!.intrinsicWidth.toFloat() 
      val width = Math.ceil((backgroundImage!!.intrinsicWidth * scale).toDouble()).toInt() 
      val height = Math.ceil((backgroundImage!!.intrinsicHeight * scale).toDouble()).toInt() 
      val kb = if (isKbOpen) keyboardHeight else 0 
      backgroundImage!!.setBounds(0, 0, width, height) 
      backgroundImage!!.draw(canvas) 
     } 
    } else { 
     super.onDraw(canvas) 
    } 
} 

}`

Luego utiliza como si fuera un FrameLayout habitual y en mi fragmento de llamada frameLayout.backgroundImage = Drawable.createFromPath(path)

espero que ayuda

Cuestiones relacionadas