Za każdym razem, gdy pojawia się klawiatura programowa, zmienia rozmiar obrazu tła. Zobacz poniższy zrzut ekranu:
Jak widać, tło jest jakby ściśnięte. Każdy może rzucić światło na to, dlaczego zmienia się rozmiar tła?
Mój układ wygląda następująco:
<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>
android
view
android-linearlayout
Andreas Wong
źródło
źródło
Napotkałem ten sam problem podczas tworzenia aplikacji do czatu, ekranu czatu z obrazem tła.
android:windowSoftInputMode="adjustResize"
ścisnąłem mój obraz tła, aby dopasować się do dostępnego miejsca po wyświetleniu miękkiej klawiatury, a „adjustPan” przesunął cały układ w górę, aby dostosować klawiaturę ekranową. Rozwiązaniem tego problemu było ustawienie tła okna zamiast tła układu wewnątrz pliku XML działania. UżyjgetWindow().setBackgroundDrawable()
w swojej działalności.źródło
Oto najlepsze rozwiązanie, aby uniknąć tego rodzaju problemów.
Krok 1: Utwórz styl
<style name="ChatBackground" parent="AppBaseTheme"> <item name="android:windowBackground">@drawable/bg_chat</item> </style>
Krok 2: Ustaw swój styl aktywności w
AndroidManifest
pliku<activity android:name=".Chat" android:screenOrientation="portrait" android:theme="@style/ChatBackground" >
źródło
W systemie Android: windowSoftInputMode = "adjustPan", co powoduje złe wrażenia użytkownika, ponieważ cały ekran przechodzi na górę (przesunięcie na górę). Oto jedna z najlepszych odpowiedzi.
Mam ten sam problem, ale potem znalazłem niesamowite odpowiedzi z @Gem
W Manifest
android:windowSoftInputMode="adjustResize|stateAlwaysHidden"
W xml
Nie ustawiaj tła tutaj i zachowaj widok pod ScrollView
W Javie
Musisz ustawić tło na okno:
getWindow().setBackgroundDrawableResource(R.drawable.bg_wood) ;
Dzięki @Gem.
źródło
tylko jako dodatek ...
jeśli masz widok listy swojej aktywności, musisz dodać go
android:isScrollContainer="false"
we właściwościach widoku listy ...i nie zapomnij dodać
android:windowSoftInputMode="adjustPan"
do swojego manifestu xml podczas swojej aktywności ...jeśli korzystasz
android:windowSoftInputMode="adjustUnspecified"
z przewijalnego widoku w swoim układzie, twoje tło będzie nadal zmieniane za pomocą miękkiej klawiatury ...byłoby lepiej, gdybyś użył wartości „adjustPan”, aby zapobiec zmianie rozmiaru tła ...
źródło
W przypadku, gdy ktoś potrzebuje
adjustResize
zachowania i nie chce,ImageView
aby jego rozmiar został zmieniony, tutaj jest inne obejście.Po prostu włóż do
ImageView
środkaScrollView
=> zaRelativeLayout
pomocą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>
źródło
Podczas pracy nad moją aplikacją napotkałem główny problem. Na początku używam metody dostarczonej przez @parulb, aby rozwiązać problem. Dziękuję mu bardzo. Ale później zauważyłem, że obraz tła jest częściowo ukryty przez pasek akcji (i jestem pewien, że pasek stanu). Ten mały problem jest już proponowany przez @ zgc7009, który skomentował poniżej odpowiedź @parulb półtora roku temu, ale nikt nie odpowiedział.
Pracowałem cały dzień, aby znaleźć sposób i na szczęście teraz mogę przynajmniej idealnie rozwiązać ten problem na moim telefonie komórkowym.
Najpierw potrzebujemy zasobu listy warstw w folderze do rysowania, aby dodać dopełnienie u góry do obrazu tła:
<!-- 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>
Po drugie ustawiliśmy ten plik jako zasób tła, jak wspomniano powyżej:
getWindow().setBackgroundDrawableResource(R.drawable.my_background);
Używam Nexusa 5. Znalazłem sposób na uzyskanie wysokości paska akcji w XML, ale nie paska stanu, więc muszę użyć stałej wysokości 75dp dla górnego wypełnienia. Mam nadzieję, że każdy znajdzie ostatni element tej układanki.
źródło
Miałem podobne problemy, ale wydaje się, że użycie
adjustPan
zandroid:isScrollContainer="false"
nadal nie naprawiło mojego układu (który był RecyclerView poniżej LinearLayout). RecyclerView był w porządku, ale za każdym razem, gdy pojawiała się klawiatura wirtualna, LinearLayout ponownie dostosowywany.Aby zapobiec temu zachowaniu (po prostu chciałem, aby klawiatura przeszła przez mój układ), zastosowałem następujący kod:
<activity android:name=".librarycartridge.MyLibraryActivity" android:windowSoftInputMode="adjustNothing" />
To mówi Androidowi, aby zasadniczo zostawił twój układ w spokoju, gdy wywoływana jest wirtualna klawiatura.
Więcej informacji na temat możliwych opcji można znaleźć tutaj (choć, co dziwne, nie wydaje się, że istnieje wpis dla
adjustNothing
).źródło
Po przestudiowaniu i wdrożeniu wszystkich dostępnych odpowiedzi, tutaj dodaję rozwiązanie.
Ta odpowiedź to kombinacja kodu z:
https://stackoverflow.com/a/45620231/1164529
https://stackoverflow.com/a/27702210/1164529
Oto
AppCompatImageView
klasa niestandardowa, która nie pokazywała rozciągania ani przewijania klawiatury programowej: -public class TopCropImageView extends AppCompatImageView { public TopCropImageView(Context context) { super(context); setScaleType(ImageView.ScaleType.MATRIX); } public TopCropImageView(Context context, AttributeSet attrs) { super(context, attrs); setScaleType(ImageView.ScaleType.MATRIX); } public TopCropImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); setScaleType(ImageView.ScaleType.MATRIX); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); computeMatrix(); } @Override protected boolean setFrame(int l, int t, int r, int b) { computeMatrix(); return super.setFrame(l, t, r, b); } private void computeMatrix() { if (getDrawable() == null) return; Matrix matrix = getImageMatrix(); float scaleFactor = getWidth() / (float) getDrawable().getIntrinsicWidth(); matrix.setScale(scaleFactor, scaleFactor, 0, 0); setImageMatrix(matrix); } }
Aby użyć go jako tła dla mojej
Fragment
klasy, ustawiłem go jako pierwszy element naFrameLayout
.<FrameLayout 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"> <complete.package.TopCropImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@mipmap/my_app_background" /> <!-- Enter other UI elements here to overlay them on the background image --> <FrameLayout>
źródło
Dodaj tę linię w pliku AndroidManifest.xml :
android:windowSoftInputMode=adjustUnspecified
skorzystaj z tego linku, aby uzyskać więcej informacji.
źródło
Po prostu użyj w swoim
onCreate()
kodzie:protected void onCreate(Bundle savedInstanceState) { ... getWindow().setBackgroundDrawableResource(R.drawable.your_image_resource); ... }
i wyeliminuj tę linię w swoim xml:
android:background="@drawable/background"
Przeczytaj więcej na:
http://developer.android.com/reference/android/view/Window.html
dzięki za: Adrian Cid Almaguer
źródło
Miałem do czynienia z tym problemem, gdy mój obraz tła znajdował się tylko
ImageView
wewnątrz aFragment
, a jego rozmiar został zmieniony przez klawiaturę.Moje rozwiązanie brzmiało: używając niestandardowego
ImageView
z tej odpowiedzi SO , edytowanej tak, aby była kompatybilna zandroidx
.import android.content.Context; import android.graphics.Matrix; import android.util.AttributeSet; import androidx.appcompat.widget.AppCompatImageView; /** * Created by chris on 7/27/16. */ public class TopCropImageView extends AppCompatImageView { public TopCropImageView(Context context) { super(context); setScaleType(ScaleType.MATRIX); } public TopCropImageView(Context context, AttributeSet attrs) { super(context, attrs); setScaleType(ScaleType.MATRIX); } public TopCropImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); setScaleType(ScaleType.MATRIX); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); recomputeImgMatrix(); } @Override protected boolean setFrame(int l, int t, int r, int b) { recomputeImgMatrix(); return super.setFrame(l, t, r, b); } private void recomputeImgMatrix() { if (getDrawable() == null) return; final Matrix matrix = getImageMatrix(); float scale; final int viewWidth = getWidth() - getPaddingLeft() - getPaddingRight(); final int viewHeight = getHeight() - getPaddingTop() - getPaddingBottom(); final int drawableWidth = getDrawable().getIntrinsicWidth(); final int drawableHeight = getDrawable().getIntrinsicHeight(); if (drawableWidth * viewHeight > drawableHeight * viewWidth) { scale = (float) viewHeight / (float) drawableHeight; } else { scale = (float) viewWidth / (float) drawableWidth; } matrix.setScale(scale, scale); setImageMatrix(matrix); } }
źródło
Moim rozwiązaniem jest zastąpienie tła okna tym z układu, a następnie ustawienie tła układu na null. W ten sposób zachowuję obraz w oknie podglądu XML:
Więc zachowaj tło w układzie i dodaj do niego identyfikator. Następnie w działaniu onCreate () umieść ten kod:
ConstraintLayout mainLayout = (ConstraintLayout)findViewById(R.id.mainLayout); getWindow().setBackgroundDrawable(mainLayout.getBackground()); mainLayout.setBackground(null);
źródło
Po prostu dodaj swoją aktywność
getWindow().setBackgroundDrawable(R.drawable.your_image_name);
źródło
Miałem ten sam problem wcześniej, ale żadne rozwiązanie nie działało dla mnie tak długo, ponieważ używałem a
Fragment
, a takżegetActivity().getWindow().setBackgroundDrawable()
nie było dla mnie rozwiązaniem.Rozwiązaniem, które u mnie zadziałało, jest zastąpienie
FrameLayout
logiką obsługi klawiatury, która powinna się pojawić i zmienić bitmapę w podróży.Oto mój kod FrameLayout (Kotlin):
class FlexibleFrameLayout : 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) } } }
Użyłem go jak zwykłego tła FrameLayout.
frameLayout.backgroundImage = Drawable.createFromPath(path)
Mam nadzieję, że to pomoże.
źródło
Możesz opakować LinearLayout za pomocą FrameLayout i dodać ImageView z Background:
<FrameLayout> <ImageView android:background="@drawable/page_bg" android:id="@+id/backgroundImage" /> <LinearLayout> .... </LinearLayout> </FrameLayout>
I możesz ustawić jego wysokość podczas tworzenia aktywności / fragmentu (aby zapobiec skalowaniu po otwarciu klawiatury). Trochę kodu w Kotlinie z Fragmentu:
activity?.window?.decorView?.height?.let { backgroundImage.setHeight(it) }
źródło
jeśli ustawisz obraz jako windowbackground i interfejs użytkownika utknie. wtedy może istnieć możliwość, że używasz do rysowania, który znajduje się w jednym folderze do rysowania, jeśli tak, musisz wkleić go w drawable-nodpi lub drawable-xxxhdpi.
źródło