सॉफ्टवेयर कीबोर्ड एंड्रॉइड पर पृष्ठभूमि छवि का आकार बदलता है


133

जब भी सॉफ्टवेयर कीबोर्ड दिखाई देता है, यह बैकग्राउंड इमेज को आकार देता है। नीचे दिए गए स्क्रीनशॉट को देखें:

जैसा कि आप देख सकते हैं, पृष्ठभूमि एक तरह से निचोड़ा हुआ है। कोई भी इस पर प्रकाश डाल सकता है कि पृष्ठभूमि क्यों आकार बदलती है?

मेरा लेआउट इस प्रकार है:

<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>

जवाबों:


190

ठीक है, मैंने इसे इस्तेमाल करके तय किया

android:windowSoftInputMode="stateVisible|adjustPan"

फ़ाइल <Activity >में टैग के अंदर प्रविष्टि manifest। मुझे लगता है कि यह गतिविधि के अंदर स्क्रॉल दृश्य होने के कारण हुआ था।


3
समस्या यह है कि स्क्रॉलिंग है, जब एडजस्टमेंट का उपयोग कर रहे हैं, तो काम नहीं कर रहे हैं ... (यदि आपके पास स्क्रॉलव्यू है), और इससे गुस्सा आता है ...
Ted

4
लेकिन अभी स्क्रोलव्यू काम नहीं कर रहा है। इससे बचने के लिए किसी भी तरह से
थ्रोट है

मुझे स्क्रॉल दृश्य चाहिए। क्या आपके पास स्क्रॉल दृश्य रखने और पृष्ठभूमि को संपीड़ित रखने का एक तरीका है।
राणा रणविजय सिंह 13

4
वह पर्याप्त नहीं है। कम से कम, यदि आप एक स्क्रॉल दृश्य का उपयोग नहीं करते हैं। बहुत बेहतर है यहां एक समाधान है stackoverflow.com/a/29750860/2914140 या stackoverflow.com/a/18191266/2914140
CoolMind

1
यदि आप कीबोर्ड को स्वचालित रूप से प्रदर्शित नहीं करना चाहते हैं तो उपयोग करें: android: windowSoftInputMode = "adjustPan"
satvinder singh

110

मुझे चैट ऐप विकसित करते समय, पृष्ठभूमि की छवि के साथ चैट स्क्रीन पर समान समस्या का सामना करना पड़ा। android:windowSoftInputMode="adjustResize"नरम कीबोर्ड प्रदर्शित होने के बाद उपलब्ध स्थान को फिट करने के लिए मेरी पृष्ठभूमि की छवि को निचोड़ लिया और "समायोजितपैन" ने नरम कीबोर्ड को समायोजित करने के लिए पूरे लेआउट को स्थानांतरित कर दिया। इस समस्या का समाधान एक गतिविधि XML के अंदर लेआउट पृष्ठभूमि के बजाय खिड़की की पृष्ठभूमि सेट कर रहा था। getWindow().setBackgroundDrawable()अपनी गतिविधि में उपयोग करें ।


4
बहुत अच्छा! सबसे बढ़िया उत्तर! एडजस्टमेंट के कारण संपार्श्विक प्रभाव होता है जैसे: कीबोर्ड घटकों को ओवरराइड करता है लेकिन कोई स्क्रॉलबार प्रदर्शित नहीं होता है।

4
@parulb या कोई और जो इसे पढ़ने के लिए होता है, यह तब तक बढ़िया काम करता है (और इसके लिए धन्यवाद) जब तक कि पृष्ठभूमि की छवि प्रासंगिक जानकारी नहीं देती है। समय-समय पर मेरे सामने आने वाली समस्या यह है कि मेरी पृष्ठभूमि में लोगो जैसा कुछ होगा, और छवि के लिए विंडो पृष्ठभूमि को सेट करना एक्शनबार के पीछे के लोगो को छुपाता है। कुछ स्क्रीन के लिए यह कोई समस्या नहीं है, लेकिन कभी-कभी मुझे एक्शनबार (कोई छुपाने वाला) नहीं रखना पड़ता है। एक्शनबार को ध्यान में रखने के लिए विंडो बैकग्राउंड सेट करते समय किसी प्रकार के पैडिंग को कैसे हैंडल किया जाए, इस पर कोई विचार?
zgc7009

1
क्या होगा अगर मैं एक टुकड़ा हूँ इसके साथ कैसे निपटूं? इसके टुकड़ों के लिए काम नहीं कर रहा है
user2056563

User2056563 के लिए: टुकड़ों के लिए बस getActivity () का उपयोग करें। getWindow ()। SetBackgroundDrawable () या getActivity ()। GetWindow ()। setBackgroundDrawableource। ()
Andrei Aulaska

धन्यवाद, इसने स्क्रॉलव्यू के साथ भी काम किया। मुझे नए AppCompat पर यह पसंद आया: getWindow ()। SetBackgroundDrawable (ContextCompat.getDrawable (यह, R.drawable.background));
लुकास एडुआर्डो

34

इस तरह की समस्या से बचने के लिए यहां सबसे अच्छा उपाय है।

चरण 1: एक शैली बनाएं

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

चरण 2: अपनी गतिविधि शैली को AndroidManifestफ़ाइल में सेट करें

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

अच्छा! सबसे सरल उपाय
मतियास एलोरियागा

28

Android के माध्यम से: windowSoftInputMode = "AdjustPan" उपयोगकर्ता को खराब अनुभव दे रहा है क्योंकि इसके माध्यम से पूरी स्क्रीन शीर्ष पर जाती है (ऊपर से ऊपर) तो, निम्नलिखित में से एक सबसे अच्छा उत्तर है।

मैं एक ही समस्या है, लेकिन उसके बाद, मैं @ जी से बहुत बढ़िया जवाब मिला

मेनिफेस्ट में

android:windowSoftInputMode="adjustResize|stateAlwaysHidden"

Xml में

यहां कोई भी पृष्ठभूमि सेट न करें और स्क्रॉल दृश्य के अंतर्गत अपना दृष्टिकोण रखें

जावा में

आपको विंडो को पृष्ठभूमि सेट करने की आवश्यकता है:

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

@ जीम को धन्यवाद।


1
मान्यता के लिए धन्यवाद।
जेम

यदि मैं इसमें स्केल प्रकार का उपयोग करना चाहता हूं तो मुझे क्या करना चाहिए? क्योंकि notch स्क्रीन इमेज के लिए स्ट्रेचिंग है।
नील

14

इसके अतिरिक्त ...

अगर आपके पास आपकी गतिविधि पर एक सूची है तो आपको android:isScrollContainer="false"अपने सूची गुणों में इसे जोड़ने की आवश्यकता है ...

और android:windowSoftInputMode="adjustPan"अपनी गतिविधि में अपनी अभिव्यक्ति xml में जोड़ना न भूलें ...

यदि आप लोग android:windowSoftInputMode="adjustUnspecified"अपने लेआउट पर स्क्रॉल करने योग्य दृश्य का उपयोग कर रहे हैं, तो आपकी पृष्ठभूमि अभी भी सॉफ्ट कीबोर्ड द्वारा आकार परिवर्तन की जाएगी ...

बेहतर होगा कि आप अपनी पृष्ठभूमि को आकार बदलने से रोकने के लिए "एडजस्टमेंट" मूल्य का उपयोग करें ...


2
एंड्रॉइड: windowSoftInputMode = "एडजस्टपैन" कीबोर्ड से पूरे व्यू शिफ्ट करें। आम तौर पर हमारे पास शीर्ष पर स्क्रीन का शीर्षक होता है। इस झंडे का उपयोग करने से यह दृश्य क्षेत्र से बाहर चला जाएगा, जो उपयोगकर्ता के बुरे अनुभव का अनुभव करते हैं।
मणि

@ नीम: तो क्या उपाय है?

जब मैं एक चैट एप्लिकेशन पर काम कर रहा था तो @Copernic को इस समस्या का सामना करना पड़ा। आखिरकार मैंने तय किया कि कृपया मेरे उत्तर को यहां देखें: stackoverflow.com/questions/5307264/…
Gem

7

मामले में अगर किसी को एक adjustResizeव्यवहार की आवश्यकता है और वह नहीं चाहता है कि उसका ImageViewआकार बदल दिया जाए तो यह एक और समाधान है।

बस ImageViewअंदर ScrollView=> RelativeLayoutसाथ 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
यह एक अच्छा समाधान है अगर आपके पास छवि के अलावा पृष्ठभूमि में अन्य दृश्य हैं .... धन्यवाद
डोमिनिक डिसूजा

4

मुझे अपने ऐप पर काम करते समय मुख्य समस्या का सामना करना पड़ा। सबसे पहले, मैं समस्या को हल करने के लिए @parulb द्वारा प्रदान की गई विधि का उपयोग करता हूं। उसका बहुत धन्यवाद। लेकिन बाद में मैंने देखा कि पृष्ठभूमि की छवि आंशिक रूप से एक्शनबार (और स्टेटसबार मुझे यकीन है) द्वारा चंगा है। यह छोटा सा मुद्दा पहले से ही @ zgc7009 द्वारा प्रस्तावित किया गया है जिसने डेढ़ साल पहले @parulb के उत्तर के नीचे टिप्पणी की थी लेकिन किसी ने उत्तर नहीं दिया।

मैंने एक रास्ता खोजने के लिए एक पूरे दिन काम किया और सौभाग्य से मैं कम से कम इस समस्या को अब अपने सेलफोन पर पूरी तरह से हल कर सकता हूं।

सबसे पहले हमें बैकग्राउंड इमेज में सबसे ऊपर पैडिंग जोड़ने के लिए ड्रॉबल फोल्डर में एक लेयर-लिस्ट संसाधन की आवश्यकता है:

<!-- 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>

दूसरा हमने इस फाइल को पृष्ठभूमि के लिए संसाधन के रूप में सेट किया है जैसा कि ऊपर बताया गया है:

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

मैं Nexus 5 का उपयोग कर रहा हूं। मुझे xml में एक्शनबार की ऊंचाई प्राप्त करने का एक तरीका मिला, लेकिन स्टेटसबार नहीं, इसलिए मुझे शीर्ष पैडिंग के लिए एक निश्चित ऊंचाई 75dp का उपयोग करना होगा। आशा है कि कोई भी इस पहेली का अंतिम टुकड़ा पा सकता है।


3

मैं इसी तरह के मुद्दों का सामना करना पड़ा है, लेकिन यह का उपयोग कर की तरह लगता है adjustPanके साथ android:isScrollContainer="false"अभी भी अपने लेआउट (जो एक LinearLayout नीचे एक RecyclerView था) को ठीक नहीं किया। RecyclerView ठीक था, लेकिन हर बार जब वर्चुअल कीबोर्ड दिखा, तो LinearLayout फिर से समायोजित हो गया।

इस व्यवहार को रोकने के लिए (मैं बस कीबोर्ड को अपने लेआउट पर जाना चाहता था), मैं निम्नलिखित कोड के साथ गया:

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

यह बताता है कि एंड्रॉइड मूल रूप से वर्चुअल लेआउट कहे जाने पर अपने लेआउट को अकेला छोड़ देता है।

संभावित विकल्पों के बारे में अधिक पढ़ना यहां पाया जा सकता है (हालांकि अजीब तरह से पर्याप्त है, ऐसा लगता नहीं है कि इसके लिए कोई प्रविष्टि है adjustNothing)।


3

सभी उपलब्ध उत्तरों का अध्ययन और कार्यान्वयन करने के बाद, मैं यहां एक समाधान जोड़ रहा हूं।

यह उत्तर कोड का संयोजन है:

https://stackoverflow.com/a/45620231/1164529

https://stackoverflow.com/a/27702210/1164529

यहाँ कस्टम AppCompatImageViewवर्ग है जो कोई खिंचाव या स्क्रॉल सॉफ्ट कीबोर्ड नहीं दिखाता है: -

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);
    }
}

अपनी Fragmentकक्षा में पृष्ठभूमि के रूप में उपयोग करने के लिए , मैंने इसे पहले तत्व के रूप में सेट किया FrameLayout

<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>


1

बस अपने onCreate()इस कोड में उपयोग करें :

protected void onCreate(Bundle savedInstanceState) {
...   
 getWindow().setBackgroundDrawableResource(R.drawable.your_image_resource);
...
}

और अपने xml में इस पंक्ति को समाप्त करें:

android:background="@drawable/background"

पर और अधिक पढ़ें:

http://developer.android.com/reference/android/view/Window.html

इसके लिए धन्यवाद: एड्रियन सिड अल्मागुएर


1

मुझे इस समस्या का सामना करना पड़ा, जब मेरी पृष्ठभूमि की छवि बस एक ImageViewअंदर Fragmentथी, और इसे कीबोर्ड द्वारा आकार दिया गया था।

मेरा समाधान था: इस SO उत्तरImageView से कस्टम का उपयोग करना , जिसके साथ संगत होना संपादित किया गया ।androidx

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);
    }

}

यह उपरोक्त कोड के साथ अब और नहीं फैलता है लेकिन यह अभी भी थोड़ा ऊपर / नीचे wrt सॉफ्ट कीबोर्ड को स्क्रॉल करता है।
हरप्रीत


0

मैंने पहले भी इसी समस्या का सामना किया था लेकिन मेरे लिए कोई समाधान इतने लंबे समय तक काम नहीं किया क्योंकि मैं एक का उपयोग कर रहा था Fragment, और getActivity().getWindow().setBackgroundDrawable() मेरे लिए भी कोई समाधान नहीं था।

समाधान जो मेरे लिए काम करता है वह FrameLayoutकीबोर्ड को संभालने के लिए एक तर्क के साथ ओवरराइड करना है जो कि दिखना चाहिए और जाने पर बिटमैप को बदलना चाहिए।

यहाँ मेरा फ्रेम -आउट कोड (कोटलिन) है:

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)
        }
    }
}

और मैंने इसे एक सामान्य फ्रेमलैट की पृष्ठभूमि की तरह इस्तेमाल किया।

frameLayout.backgroundImage = Drawable.createFromPath(path)

आशा करता हूँ की ये काम करेगा।


0

आप फ्रेमलाइन के साथ अपने रेखीयआउट को रैप कर सकते हैं और ImageView को पृष्ठभूमि के साथ जोड़ सकते हैं:

<FrameLayout>

  <ImageView 
    android:background="@drawable/page_bg"
    android:id="@+id/backgroundImage" />

  <LinearLayout>
    ....
  </LinearLayout>
</FrameLayout>

और जब आप गतिविधि / विखंडन बना रहे हों (खुले कीबोर्ड से स्केलिंग से बचाव के लिए) तो आप इसे ऊँचाई पर सेट कर सकते हैं। कोटलिन में कुछ कोड फ्रैगमेंट से:

activity?.window?.decorView?.height?.let {
        backgroundImage.setHeight(it)
}

0

यदि आप विंडोबैकग्राउंड और यूआई के रूप में छवि सेट कर रहे हैं, तो अटक जाने वाली है। तब संभावना हो सकती है कि आप ड्रॉएबल का उपयोग कर रहे हैं जो एकल ड्रॉएबल फ़ोल्डर में है, यदि हाँ, तो आपको इसे ड्रॉएबल-नोड्पी या ड्रॉएबल-एक्सएक्सएचडीपीआई में पेस्ट करना होगा।


0

मेरा समाधान लेआउट की एक के साथ खिड़की की पृष्ठभूमि को बदलना है, फिर लेआउट पृष्ठभूमि को शून्य में सेट करें। इस तरह मैं छवि को XML पूर्वावलोकन विंडो में रखता हूं:

इसलिए पृष्ठभूमि को लेआउट में रखें और इसके लिए एक आईडी जोड़ें। फिर गतिविधि में onCreate () इस कोड को डालें:

    ConstraintLayout mainLayout = (ConstraintLayout)findViewById(R.id.mainLayout);
    getWindow().setBackgroundDrawable(mainLayout.getBackground());
    mainLayout.setBackground(null);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.