एंड्रॉइड कैसे लेआउट को फुल स्क्रीन मोड में समायोजित करें जब सॉफ्टकीबोर्ड दिखाई दे


178

सॉफ्टकबोर्ड सक्रिय होने पर मैंने लेआउट को समायोजित करने के लिए बहुत शोध किया है और मैंने इसे सफलतापूर्वक लागू किया है लेकिन समस्या तब आती है जब मैं android:theme="@android:style/Theme.NoTitleBar.Fullscreen"इसे अपनी गतिविधि टैग में प्रकट फ़ाइल में उपयोग करता हूं।

इसके लिए मैंने android:windowSoftInputMode="adjustPan|adjustResize|stateHidden"विभिन्न विकल्पों के साथ उपयोग किया है लेकिन कोई भाग्य नहीं।

उसके बाद मैंने FullScreenप्रोग्रामेटिक रूप से लागू किया और FullScreenसभी के साथ काम करने के लिए विभिन्न लेआउट की कोशिश की ।

मैंने इन कड़ियों को संदर्भित किया है और इस मुद्दे से संबंधित कई पोस्ट देखी हैं:

http://android-developers.blogspot.com/2009/04/updating-applications-for-on-screen.html

http://davidwparker.com/2011/08/30/android-how-to-float-a-row-above-keyboard/

यहाँ xml कोड है:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/masterContainerView"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="#ffffff">

    <ScrollView android:id="@+id/parentScrollView"
        android:layout_width="fill_parent" android:layout_height="wrap_content">

        <LinearLayout android:layout_width="fill_parent"
            android:layout_height="fill_parent" android:orientation="vertical">

            <TextView android:id="@+id/setup_txt" android:layout_width="wrap_content"
                android:layout_height="wrap_content" android:text="Setup - Step 1 of 3"
                android:textColor="@color/top_header_txt_color" android:textSize="20dp"
                android:padding="8dp" android:gravity="center_horizontal" />

            <TextView android:id="@+id/txt_header" android:layout_width="fill_parent"
                android:layout_height="40dp" android:text="AutoReply:"
                android:textColor="@color/top_header_txt_color" android:textSize="14dp"
                android:textStyle="bold" android:padding="10dp"
                android:layout_below="@+id/setup_txt" />

            <EditText android:id="@+id/edit_message"
                android:layout_width="fill_parent" android:layout_height="wrap_content"
                android:text="Some text here." android:textSize="16dp"
                android:textColor="@color/setting_editmsg_color" android:padding="10dp"
                android:minLines="5" android:maxLines="6" android:layout_below="@+id/txt_header"
                android:gravity="top" android:scrollbars="vertical"
                android:maxLength="132" />

            <ImageView android:id="@+id/image_bottom"
                android:layout_width="fill_parent" android:layout_height="wrap_content"
                android:layout_below="@+id/edit_message" />

        </LinearLayout>
    </ScrollView>

    <RelativeLayout android:id="@+id/scoringContainerView"
        android:layout_width="fill_parent" android:layout_height="50px"
        android:orientation="vertical" android:layout_alignParentBottom="true"
        android:background="#535254">

        <Button android:id="@+id/btn_save" android:layout_width="wrap_content"
            android:layout_height="wrap_content" android:layout_alignParentRight="true"
            android:layout_marginTop="7dp" android:layout_marginRight="15dp"
            android:layout_below="@+id/edit_message"
            android:text = "Save" />

        <Button android:id="@+id/btn_cancel" android:layout_width="wrap_content"
            android:layout_height="wrap_content" android:layout_marginTop="7dp"
            android:layout_marginRight="10dp" android:layout_below="@+id/edit_message"
            android:layout_toLeftOf="@+id/btn_save" android:text = "Cancel" />

    </RelativeLayout>
</RelativeLayout>

यहां छवि विवरण दर्ज करें

मैं चाहता हूं कि नीचे के 2 बटन ऊपर की ओर जाएं जब सॉफ्टकीबोर्ड तस्वीर में आता है।

यहां छवि विवरण दर्ज करें


1
मुझे लगता है कि आपको स्क्रॉलव्यू के अंदर और एडिटटेक्स्ट के नीचे बटन जोड़ने होंगे।
बालाजी खडके

मैंने पहले से ही कई विकल्पों की कोशिश की है जो काम नहीं करता है ...
विनीत शुक्ला

1
एक framelayout में उर बटन लगाओ और 1 के लिए framelayout का वजन निर्धारित करो और अंत में केवल android:windowSoftInputMode="adjustPan"मुझे बताओ कि क्या यह काम करता है ..
Sherif elKhatib

@VineetShukla क्या आपने पूर्ण स्क्रीन के साथ कोई काम किया है ??
मुहम्मद बाबर

2
ध्यान दें कि आप का उपयोग नहीं करना चाहिए adjustResizeऔर adjustPanएक ही समय में, के javadoc से android.view.WindowManager.LayoutParams#SOFT_INPUT_ADJUST_RESIZE: "यह {@ @ के साथ नहीं जोड़ा जा सकता है SOFT_INPUT_ADJUST_PAN}"
डेनिस नियाज़ेव

जवाबों:


257

Yghm के वर्कअराउंड के आधार पर, मैंने एक सुविधा वर्ग को कोडित किया जो मुझे एक लाइनर के साथ समस्या को हल करने की अनुमति देता है (नई कक्षा को मेरे स्रोत कोड से जोड़ने के बाद)। एक-लाइनर है:

     AndroidBug5497Workaround.assistActivity(this);

और कार्यान्वयन वर्ग है:


public class AndroidBug5497Workaround {

    // For more information, see https://issuetracker.google.com/issues/36911528
    // To use this class, simply invoke assistActivity() on an Activity that already has its content view set.

    public static void assistActivity (Activity activity) {
        new AndroidBug5497Workaround(activity);
    }

    private View mChildOfContent;
    private int usableHeightPrevious;
    private FrameLayout.LayoutParams frameLayoutParams;

    private AndroidBug5497Workaround(Activity activity) {
        FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
        mChildOfContent = content.getChildAt(0);
        mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            public void onGlobalLayout() {
                possiblyResizeChildOfContent();
            }
        });
        frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
    }

    private void possiblyResizeChildOfContent() {
        int usableHeightNow = computeUsableHeight();
        if (usableHeightNow != usableHeightPrevious) {
            int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
            int heightDifference = usableHeightSansKeyboard - usableHeightNow;
            if (heightDifference > (usableHeightSansKeyboard/4)) {
                // keyboard probably just became visible
                frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
            } else {
                // keyboard probably just became hidden
                frameLayoutParams.height = usableHeightSansKeyboard;
            }
            mChildOfContent.requestLayout();
            usableHeightPrevious = usableHeightNow;
        }
    }

    private int computeUsableHeight() {
        Rect r = new Rect();
        mChildOfContent.getWindowVisibleDisplayFrame(r);
        return (r.bottom - r.top);
    }
}

आशा है कि यह किसी की मदद करता है।


8
धन्यवाद! मुझे पता नहीं क्यों है, लेकिन मैं बदलने के लिए किया था return (r.bottom - r.top); के साथ return r.bottomअन्यथा गतिविधि दृश्य होगा स्थिति पट्टी के आकार से बहुत अधिक धकेल दिया यह मेरे HTC एक मिनी पर काम पाने के लिए,। मैंने अभी तक किसी अन्य डिवाइस पर इसका परीक्षण नहीं किया है। उम्मीद है कि मदद कर सकता है।
Joan

4
हाय जोसेफ जॉनसन, मैंने आपके कोड का उपयोग किया और यह पूरी तरह से काम करता है। लेकिन अब कुछ छोटे उपकरणों पर एक समस्या का सामना करना पड़ रहा है कि यह कीबोर्ड और लेआउट के बीच अंतर (रिक्त स्क्रीन) दिखाता है। क्या आपके पास इस मुद्दे के बारे में कोई विचार है? मैंने भी वापसी की कोशिश की r.bottom।
पंकज

2
यूसुफ जॉनसन: मैं जब हम पाठ शीर्ष संपादित करें पर क्लिक करें लेकिन जब हम नीचे edittext पर क्लिक करें सभी डिजाइन ऊपर जाता है अपने विधि अपने काम के ठीक लागू कर दिया है,
रंजीत

3
दुर्भाग्य से यह नेक्सस 7 (2013) पर काम नहीं करता है। यह अभी भी समायोजन सेट के साथ भी पैन करता है।
ले-रॉय स्टेंस ने

4
बहुत बढ़िया जवाब, बहुत बहुत धन्यवाद। यह एक नेक्सस 6 पर काम कर रहा है, लेकिन इसका उपयोग करने के बजाय frameLayoutParams.height = usableHeightSansKeyboard;मुझे इसका उपयोग करना frameLayoutParams.height = usableHeightNow; होगा यदि मैं ऐसा नहीं करता हूं तो कुछ तत्व स्क्रीन के बाहर गिर जाते हैं।
रोबर्टोएलेन्डे

37

चूंकि उत्तर पहले ही चुन लिया गया है और समस्या को बग के रूप में जाना जाता है, इसलिए मैंने सोचा कि मैं "संभावित कार्य लगभग" जोड़ दूंगा।

सॉफ्ट कीबोर्ड दिखाए जाने पर आप फुलस्क्रीन मोड को चालू कर सकते हैं। यह "एडजस्टमेंट" को सही ढंग से काम करने की अनुमति देता है।

दूसरे शब्दों में, मैं अभी भी @android: style / Theme.Black.NoTitleBar.Fullscreen का उपयोग एप्लिकेशन थीम और राज्यविजय के भाग के रूप में करता हूं । गतिविधि विंडो सॉफ्ट इनपुट मोड के भाग के रूप में समायोजित करें। लेकिन उन्हें एक साथ काम करने के लिए मुझे फुलस्क्रीन मोड को चालू करना होगा। कीबोर्ड आने से पहले।

निम्नलिखित कोड का उपयोग करें:

पूर्ण स्क्रीन मोड बंद करें

getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

पूर्ण स्क्रीन मोड चालू करें

getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);

नोट - प्रेरणा से आया: फुलस्क्रीन मोड में शीर्षक छिपाना


1
मैं सराहना करता हूं कि आपने समस्या के लिए समय दिया है, उसके लिए +1। मैं निश्चित रूप से इस दृष्टिकोण का परीक्षण करूंगा और आपको जल्द ही पता चल जाएगा कि यह मेरे लिए काम करता है, धन्यवाद।
विनीत शुक्ला

1
संदिग्ध के रूप में काम कर रहा है! वास्तव में अच्छा समाधान! मेरी तरफ से +1।
माइक


1
कीबोर्ड स्नैप, कीबोर्ड की पृष्ठभूमि को काला बनाता है। तड़क
भड़क वाला

वाह धन्यवाद ... यह AndroidBug5497Workaround द्वारा वर्णित वर्कअराउंड के संयोजन से मेरे लिए वास्तव में अच्छी तरह से काम करता है ... मैंने GitHub के लिए संयुक्त स्रोत अपलोड किया ... github.com/CrandellWS/AndroidBug5497Workaround/blob/master/…
CrandellWS

23

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

जब नरम इनपुट दिखाई देता है, तो सामग्री को पहले उसकी मूल ऊंचाई पर आधारित किया जाता है, और फिर जोसेफ के समाधान द्वारा अनुरोधित लेआउट द्वारा आकार दिया जाता है। आकार और बाद का लेआउट पैनिंग को पूर्ववत नहीं करता है, जिसके परिणामस्वरूप अंतराल होता है। घटनाओं का पूरा क्रम है:

  1. वैश्विक लेआउट श्रोता
  2. पैनिंग
  3. सामग्री का लेआउट (= सामग्री का वास्तविक आकार बदलना)

पैनिंग को अक्षम करना संभव नहीं है, लेकिन सामग्री की ऊंचाई को बदलकर पैन ऑफसेट को 0 से बाध्य करना संभव है। यह श्रोता में किया जा सकता है, क्योंकि यह पैनिंग होने से पहले चलाया जाता है। सामग्री ऊंचाई को उपलब्ध ऊंचाई पर सेट करना एक सहज उपयोगकर्ता अनुभव का परिणाम है, अर्थात कोई झिलमिलाहट नहीं।

मैंने भी ये बदलाव किए। यदि इनमें से कोई भी समस्याएँ आती हैं, तो मुझे बताएं:

  • उपयोग करने के लिए उपलब्ध ऊंचाई का स्विच्ड निर्धारण getWindowVisibleDisplayFrameRectअनावश्यक कचरा का एक छोटा सा रोकने के लिए कैश किया गया है।
  • श्रोता को भी हटा दें। यह उपयोगी है जब आप अलग-अलग अंशों के लिए एक गतिविधि का पुन: उपयोग करते हैं, जिसमें पूर्ण-स्क्रीन आवश्यकताएं होती हैं।
  • दिखाए गए या छिपे हुए कीबोर्ड के बीच अंतर न करें, लेकिन हमेशा सामग्री को दृश्यमान डिस्प्ले फ्रेम ऊंचाई पर सेट करें।

यह नेक्सस 5 पर परीक्षण किया गया है, और छोटे आकार से बड़े तक स्क्रीन आकार के साथ एपीआई स्तर 16-24 चल रहा है।

कोड को कोटलिन में पोर्ट किया गया है, लेकिन जावा में मेरे परिवर्तनों को पोर्ट करना सरल है। मदद की ज़रूरत पड़ने पर मुझे बतायें:

class AndroidBug5497Workaround constructor(activity: Activity) {
    private val contentContainer = activity.findViewById(android.R.id.content) as ViewGroup
    private val rootView = contentContainer.getChildAt(0)
    private val rootViewLayout = rootView.layoutParams as FrameLayout.LayoutParams
    private val viewTreeObserver = rootView.viewTreeObserver
    private val listener = ViewTreeObserver.OnGlobalLayoutListener { possiblyResizeChildOfContent() }

    private val contentAreaOfWindowBounds = Rect()
    private var usableHeightPrevious = 0

    // I call this in "onResume()" of my fragment
    fun addListener() {
        viewTreeObserver.addOnGlobalLayoutListener(listener)
    }

    // I call this in "onPause()" of my fragment
    fun removeListener() {
        viewTreeObserver.removeOnGlobalLayoutListener(listener)
    }

    private fun possiblyResizeChildOfContent() {
        contentContainer.getWindowVisibleDisplayFrame(contentAreaOfWindowBounds)
        val usableHeightNow = contentAreaOfWindowBounds.height()
        if (usableHeightNow != usableHeightPrevious) {
            rootViewLayout.height = usableHeightNow
            // Change the bounds of the root view to prevent gap between keyboard and content, and top of content positioned above top screen edge.
            rootView.layout(contentAreaOfWindowBounds.left, contentAreaOfWindowBounds.top, contentAreaOfWindowBounds.right, contentAreaOfWindowBounds.bottom)
            rootView.requestLayout()

            usableHeightPrevious = usableHeightNow
        }
    }
}

9
यह सबसे अच्छा जवाब लगता है। मैंने यहां java को दिखायाgith.github.com/grennis/2e3cd5f7a9238c59861015ce0a7c5584 । नोट मुझे अपवाद मिल रहे थे कि पर्यवेक्षक जीवित नहीं था, और उसके लिए भी जाँच करनी थी।
ग्रेग

हे भगवान! सभी सिस्टम को पछाड़ दिया गया है कि भूत अंतरिक्ष की तलाश में पदानुक्रम है। मैं एक खाद्य ट्रक के लिए कंप्यूटरों को खोदने के करीब था, लेकिन अंतिम समय में आपका जवाब देखा। यह काम करता है :)
नष्ट कर देता है

1
@Greg Ennis जावा पोर्ट के लिए धन्यवाद। बहुत प्रयास और समय बचाया।
इकुन

@GregEnnis, धन्यवाद, आपका समाधान onResume (), onPause (), onDestroy () (GitHub कोड में टिप्पणियां देखें) के साथ काम करता है।
कूलमाइंड

यह मेरे लिए काम कर रहा है, सिवाय इसके कि रिमिलाइंटर कॉल काम नहीं कर रही है। मैंने possiblyResizeChildOfContentकॉल और कॉल दोनों के अंदर ब्रेकपॉइंट्स लगाए हैं removeListener, और मैंने भी removeListenerब्रेकपॉइंट को हिट करने के बाद , possiblyResizeChildOfContentअभी भी कहा जा रहा है। क्या किसी और को भी ये समस्या है?
क्विन

14

यदि आप सिस्टम UI दृष्टिकोण ( https://developer.android.com/training/system-ui/immersive.html ) का उपयोग कर रहे हैं तो मुझे बस एक सरल और विश्वसनीय समाधान मिला ।

यह उस स्थिति में काम करता है जब आप उपयोग कर रहे होते हैं View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN, जैसे यदि आप उपयोग कर रहे हैं CoordinatorLayout

यह काम नहीं करेगा WindowManager.LayoutParams.FLAG_FULLSCREEN(वह जिसे आप थीम के साथ भी सेट कर सकते हैं android:windowFullscreen), लेकिन आप डॉक्स के अनुसारSYSTEM_UI_FLAG_LAYOUT_STABLE (जिसके "समान दृश्य प्रभाव" ) के समान प्रभाव प्राप्त कर सकते हैं और इस समाधान को फिर से काम करना चाहिए।

getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION /* If you want to hide navigation */
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE)

मैंने मार्शमैलो चलाने वाले अपने डिवाइस पर इसका परीक्षण किया है।

कुंजी यह है कि सॉफ्ट कीबोर्ड भी सिस्टम विंडो (जैसे स्टेटस बार और नेविगेशन बार) में से एक है, इसलिए WindowInsetsसिस्टम द्वारा भेजे गए में इसके बारे में सटीक और विश्वसनीय जानकारी होती है।

उपयोग के मामले में जैसे DrawerLayoutकि हम स्टेटस बार के पीछे खींचने की कोशिश कर रहे हैं, हम एक ऐसा लेआउट बना सकते हैं जो केवल शीर्ष इनसेट को अनदेखा करता है, और नीचे के इनसेट को लागू करता है जो सॉफ्ट कीबोर्ड के लिए जिम्मेदार है।

यहाँ मेरा रिवाज है FrameLayout:

/**
 * Implements an effect similar to {@code android:fitsSystemWindows="true"} on Lollipop or higher,
 * except ignoring the top system window inset. {@code android:fitsSystemWindows="true"} does not
 * and should not be set on this layout.
 */
public class FitsSystemWindowsExceptTopFrameLayout extends FrameLayout {

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

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

    public FitsSystemWindowsExceptTopFrameLayout(Context context, AttributeSet attrs,
                                                 int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    public FitsSystemWindowsExceptTopFrameLayout(Context context, AttributeSet attrs,
                                                 int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            setPadding(insets.getSystemWindowInsetLeft(), 0, insets.getSystemWindowInsetRight(),
                    insets.getSystemWindowInsetBottom());
            return insets.replaceSystemWindowInsets(0, insets.getSystemWindowInsetTop(), 0, 0);
        } else {
            return super.onApplyWindowInsets(insets);
        }
    }
}

और इसका उपयोग करने के लिए:

<com.example.yourapplication.FitsSystemWindowsExceptTopFrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- Your original layout here -->
</com.example.yourapplication.FitsSystemWindowsExceptTopFrameLayout>

यह बिना किसी संशोधन के किसी भी उपकरण के लिए सैद्धांतिक रूप से काम करना चाहिए, किसी भी हैक की तुलना में बेहतर है जो एक यादृच्छिक 1/3या 1/4स्क्रीन आकार को संदर्भ के रूप में लेने की कोशिश करता है ।

(इसके लिए एपीआई 16+ की आवश्यकता होती है, लेकिन मैं स्टेटस बार के पीछे ड्राइंग के लिए लॉलीपॉप + पर केवल फुलस्क्रीन का उपयोग कर रहा हूं, इसलिए यह इस मामले में सबसे अच्छा समाधान है।)


@Dipip यह एपीआई 16+ पर काम करता है, बशर्ते कि उपरोक्त शर्तें पूरी हों।
हे जांग

10

कृपया ध्यान दें कि किसी गतिविधि के लिए सेट होने पर android:windowSoftInputMode="adjustResize"काम नहीं करता WindowManager.LayoutParams.FLAG_FULLSCREENहै। आपको दो विकल्प मिले हैं।

  1. या तो अपनी गतिविधि के लिए फ़ुलस्क्रीन मोड को अक्षम करें। फुलस्क्रीन मोड में गतिविधि फिर से आकार में नहीं है। आप इसे xml (गतिविधि के विषय को बदलकर) या जावा कोड में कर सकते हैं। अपने onCreate () विधि में निम्न पंक्तियाँ जोड़ें।

    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);   
    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);`

या

  1. फुलस्क्रीन मोड प्राप्त करने के लिए वैकल्पिक तरीके का उपयोग करें। अपने onCreate () विधि में निम्न कोड जोड़ें।

    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
    View decorView = getWindow().getDecorView();
    // Hide the status bar.
    int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
    decorView.setSystemUiVisibility(uiOptions);`

कृपया ध्यान दें कि विधि -2 केवल एंड्रॉइड 4.1 और इसके बाद के संस्करण में काम करता है।


@AnshulTyagi मेथड -2 केवल एंड्रॉइड 4.1 और इसके बाद के संस्करण में काम करता है।
अभिनव चौहान

4
क्रमशः 5.0 और 4.4.2, नेक्सस 9 और सैमसंग एस 4 पर परीक्षण किया गया, दूसरा तरीका काम नहीं करता है।
रॉबवॉइस

1
दूसरा तरीका बस काम नहीं करता है और मैंने इस पर बहुत समय बर्बाद किया है।
Greg में ग्रेग एनिस २ ''१

धन्यवाद, मेरा दिन बचाना।
डेनी रोहिमात

9

मुझे इस समस्या का भी सामना करना पड़ा और मेरे पास एक काम था, जिसे मैंने एचटीसी वन, गैलेक्सी एस 1, एस 2, एस 3, नोट और एचटीसी सेंसेशन पर चेक किया।

वैश्विक लेआउट श्रोता को अपने लेआउट के मूल दृश्य पर रखें

mRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener(){
            public void onGlobalLayout() {
                checkHeightDifference();
            }
    });

और वहां मैंने ऊंचाई के अंतर को जांचा और यदि स्क्रीन की ऊंचाई का अंतर बड़ा है तो स्क्रीन की ऊंचाई पर एक तिहाई है तो हम मान सकते हैं कि कीबोर्ड खुला है। इस जवाब से लिया ।

private void checkHeightDifference(){
    // get screen frame rectangle 
    Rect r = new Rect();
    mRootView.getWindowVisibleDisplayFrame(r);
    // get screen height
    int screenHeight = mRootView.getRootView().getHeight();
    // calculate the height difference
    int heightDifference = screenHeight - (r.bottom - r.top);

    // if height difference is different then the last height difference and
    // is bigger then a third of the screen we can assume the keyboard is open
    if (heightDifference > screenHeight/3 && heightDifference != mLastHeightDifferece) {
        // keyboard visiblevisible
        // get root view layout params
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mRootView.getLayoutParams();
        // set the root view height to screen height minus the height difference
        lp.height = screenHeight - heightDifference;
        // call request layout so the changes will take affect
        .requestLayout();
        // save the height difference so we will run this code only when a change occurs.
        mLastHeightDifferece = heightDifference;
    } else if (heightDifference != mLastHeightDifferece) {
        // keyboard hidden
        PFLog.d("[ChatroomActivity] checkHeightDifference keyboard hidden");
        // get root view layout params and reset all the changes we have made when the keyboard opened.
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mRootView.getLayoutParams();
        lp.height = screenHeight;
        // call request layout so the changes will take affect
        mRootView.requestLayout();
        // save the height difference so we will run this code only when a change occurs.
        mLastHeightDifferece = heightDifference;
    }
}

यह शायद बुलेट प्रूफ नहीं है और शायद कुछ उपकरणों पर यह काम नहीं करेगा लेकिन इसने मेरे लिए काम किया और आशा है कि यह आपकी भी मदद करेगा।


1
कुछ समायोजन की आवश्यकता थी, लेकिन यह काम किया। Nexus 7 2013 में मुझे कुछ पिक्सल्स द्वारा कीबोर्ड की ऊँचाई (स्क्रीनहाइट / 3) घटानी पड़ी। अच्छा विचार है, धन्यवाद!
जोआओ सूसा

7

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

    //when the application uses full screen theme and the keyboard is shown the content not scrollable! 
//with this util it will be scrollable once again
//http://stackoverflow.com/questions/7417123/android-how-to-adjust-layout-in-full-screen-mode-when-softkeyboard-is-visible
public class AndroidBug5497Workaround {


    private static AndroidBug5497Workaround mInstance = null;
    private View mChildOfContent;
    private int usableHeightPrevious;
    private FrameLayout.LayoutParams frameLayoutParams;
    private ViewTreeObserver.OnGlobalLayoutListener _globalListener;

    // For more information, see https://code.google.com/p/android/issues/detail?id=5497
    // To use this class, simply invoke assistActivity() on an Activity that already has its content view set.

    public static AndroidBug5497Workaround getInstance (Activity activity) {
        if(mInstance==null)
        {
            synchronized (AndroidBug5497Workaround.class)
            {
                mInstance = new AndroidBug5497Workaround(activity);
            }
        }
        return mInstance;
    }

    private AndroidBug5497Workaround(Activity activity) {
        FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
        mChildOfContent = content.getChildAt(0);
        frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();

        _globalListener = new ViewTreeObserver.OnGlobalLayoutListener()
        {

            @Override
            public void onGlobalLayout()
            {
                 possiblyResizeChildOfContent();
            }
        };
    }

    public void setListener()
    {
         mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(_globalListener);
    }

    public void removeListener()
    {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            mChildOfContent.getViewTreeObserver().removeOnGlobalLayoutListener(_globalListener);
        } else {
            mChildOfContent.getViewTreeObserver().removeGlobalOnLayoutListener(_globalListener);
        }
    }

    private void possiblyResizeChildOfContent() {
        int usableHeightNow = computeUsableHeight();
        if (usableHeightNow != usableHeightPrevious) {
            int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
            int heightDifference = usableHeightSansKeyboard - usableHeightNow;
            if (heightDifference > (usableHeightSansKeyboard/4)) {
                // keyboard probably just became visible
                frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
            } else {
                // keyboard probably just became hidden
                frameLayoutParams.height = usableHeightSansKeyboard;
            }
            mChildOfContent.requestLayout();
            usableHeightPrevious = usableHeightNow;
        }
    }

    private int computeUsableHeight() {
        Rect r = new Rect();
        mChildOfContent.getWindowVisibleDisplayFrame(r);
        return (r.bottom - r.top);
    } 
}

उस कक्षा का उपयोग करता है जहाँ मेरा edittexts स्थित है

@Override
public void onStart()
{
    super.onStart();
    AndroidBug5497Workaround.getInstance(getActivity()).setListener();
}

@Override
public void onStop()
{
    super.onStop();
    AndroidBug5497Workaround.getInstance(getActivity()).removeListener();
}

7

android:fitsSystemWindows="true"लेआउट में जोड़ें , और यह लेआउट आकार बदल जाएगा।


यही मेरे लिए इसका हल है। इसके अलावा सोचा, सुनिश्चित करें कि आपने इसे सही दृश्य पर सेट किया है। यदि आपके पास एक पृष्ठभूमि है जिसे स्टेटस बार के नीचे जाना चाहिए, तो इसे वहां सेट न करें, लेकिन अंदर एक लेआउट पर। संभवत: EditText के दृश्य आदि उस दूसरे लेआउट के अंदर होने चाहिए। इस बात को भी देखें, क्योंकि यह चीजों को और अधिक स्पष्ट करती है: youtube.com/watch?v=_mGDMVRO3iE
Stan

मेरे लिए भी काम किया। @Stan टिप्पणी की बदौलत मैं भी FULLSCREEN थीम के साथ काम करने में सक्षम था, जो उस विशेषता को गतिविधि / खंड लेआउट के बजाय ViewPager पर रखता था।
marcouberti

5

फुलस्क्रीन के साथ काम करने के लिए इसे पाने के लिए:

आयनिक कीबोर्ड प्लगइन का उपयोग करें। यह आपको तब दिखाई देता है जब कीबोर्ड दिखाई देता है और गायब हो जाता है।

OnDeviceReady इन इवेंट श्रोताओं को जोड़ें:

// Allow Screen to Move Up when Keyboard is Present
window.addEventListener('native.keyboardshow', onKeyboardShow);
// Reset Screen after Keyboard hides
window.addEventListener('native.keyboardhide', onKeyboardHide);

तर्क:

function onKeyboardShow(e) {
    // Get Focused Element
    var thisElement = $(':focus');
    // Get input size
    var i = thisElement.height();
    // Get Window Height
    var h = $(window).height()
    // Get Keyboard Height
    var kH = e.keyboardHeight
    // Get Focused Element Top Offset
    var eH = thisElement.offset().top;
    // Top of Input should still be visible (30 = Fixed Header)
    var vS = h - kH;
    i = i > vS ? (vS - 30) : i;
    // Get Difference
    var diff = (vS - eH - i);
    if (diff < 0) {
        var parent = $('.myOuter-xs.myOuter-md');
        // Add Padding
        var marginTop = parseInt(parent.css('marginTop')) + diff - 25;
        parent.css('marginTop', marginTop + 'px');
    }
}

function onKeyboardHide(e) {
  // Remove All Style Attributes from Parent Div
  $('.myOuter-xs.myOuter-md').removeAttr('style');
}

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

तर्क में टाइमआउट जोड़ते हुए कहते हैं कि 300ms को भी प्रदर्शन का अनुकूलन करना चाहिए (क्योंकि इससे कीबोर्ड का समय दिखाई देगा।


3

मैंने जोसेफ जॉनसन की कक्षा की कोशिश की, और यह काम किया, लेकिन मेरी जरूरतों को पूरा नहीं किया। Android का अनुकरण करने के बजाय: windowSoftInputMode = "AdjustResize", मुझे Android का अनुकरण करने की आवश्यकता थी: windowSoftInputMode = "adjustPan"।

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

package some.package.name;

import some.package.name.JavaScriptObject;

import android.app.Activity;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;

//-------------------------------------------------------
// ActivityPanner Class
//
// Convenience class to handle Activity attributes bug.
// Use this class instead of windowSoftInputMode="adjustPan".
//
// To implement, call enable() and pass a reference
// to an Activity which already has its content view set.
// Example:
//      setContentView( R.layout.someview );
//      ActivityPanner.enable( this );
//-------------------------------------------------------
//
// Notes:
//
// The standard method for handling screen panning
// when the virtual keyboard appears is to set an activity
// attribute in the manifest.
// Example:
// <activity
//      ...
//      android:windowSoftInputMode="adjustPan"
//      ... >
// Unfortunately, this is ignored when using the fullscreen attribute:
//      android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
//
//-------------------------------------------------------
public class ActivityPanner {

    private View contentView_;
    private int priorVisibleHeight_;

    public static void enable( Activity activity ) {
        new ActivityPanner( activity );
    }

    private ActivityPanner( Activity activity ) {
        FrameLayout content = (FrameLayout)
            activity.findViewById( android.R.id.content );
        contentView_ = content.getChildAt( 0 );
        contentView_.getViewTreeObserver().addOnGlobalLayoutListener(
            new ViewTreeObserver.OnGlobalLayoutListener() {
                public void onGlobalLayout() { panAsNeeded(); }
        });
    }

    private void panAsNeeded() {

        // Get current visible height
        int currentVisibleHeight = visibleHeight();

        // Determine if visible height changed
        if( currentVisibleHeight != priorVisibleHeight_ ) {

            // Determine if keyboard visiblity changed
            int screenHeight =
                contentView_.getRootView().getHeight();
            int coveredHeight =
                screenHeight - currentVisibleHeight;
            if( coveredHeight > (screenHeight/4) ) {
                // Keyboard probably just became visible

                // Get the current focus elements top & bottom
                // using a ratio to convert the values
                // to the native scale.
                float ratio = (float) screenHeight / viewPortHeight();
                int elTop = focusElementTop( ratio );
                int elBottom = focusElementBottom( ratio );

                // Determine the amount of the focus element covered
                // by the keyboard
                int elPixelsCovered = elBottom - currentVisibleHeight;

                // If any amount is covered
                if( elPixelsCovered > 0 ) {

                    // Pan by the amount of coverage
                    int panUpPixels = elPixelsCovered;

                    // Prevent panning so much the top of the element
                    // becomes hidden
                    panUpPixels = ( panUpPixels > elTop ?
                                    elTop : panUpPixels );

                    // Prevent panning more than the keyboard height
                    // (which produces an empty gap in the screen)
                    panUpPixels = ( panUpPixels > coveredHeight ?
                                    coveredHeight : panUpPixels );

                    // Pan up
                    contentView_.setY( -panUpPixels );
                }
            }
            else {
                // Keyboard probably just became hidden

                // Reset pan
                contentView_.setY( 0 );
            }

            // Save usabale height for the next comparison
            priorVisibleHeight_ = currentVisibleHeight;
        }
    }

    private int visibleHeight() {
        Rect r = new Rect();
        contentView_.getWindowVisibleDisplayFrame( r );
        return r.bottom - r.top;
    }

    // Customize this as needed...
    private int viewPortHeight() { return JavaScriptObject.viewPortHeight(); }
    private int focusElementTop( final float ratio ) {
        return (int) (ratio * JavaScriptObject.focusElementTop());
    }
    private int focusElementBottom( final float ratio ) {
        return (int) (ratio * JavaScriptObject.focusElementBottom());
    }

}

लगता है कि मुझे क्या चाहिए, क्या आप एक पूरा नमूना जोड़ सकते हैं? आपके काम के लिए धन्यवाद!
vilicvane

मैं एक पूरी परियोजना पोस्ट नहीं कर रहा था। मैंने जो प्रदान किया है वह आपको एक बहुत लंबा रास्ता देगा, हालांकि पूरी तरह से काम करने वाले समाधान की ओर। आपको अपने आप को परिभाषित करने की क्या आवश्यकता है: एक "जावास्क्रिप्टऑब्जेक्ट" क्लास बनाएं और इसे अपने वेबव्यू में एक जेएस इंटरफेस के रूप में इंजेक्ट करें (उस के लिए वेबव्यू प्रलेखन देखें)। एक अच्छा मौका है जो आपने पहले ही कर लिया है कि अगर कुछ ऐसा लिखा जाए जो व्यापक रूप से वेबव्यू का उपयोग करे। फोकस घटनाओं को सुनने और फोकस तत्व स्थिति के बारे में अपने JavaScriptObject वर्ग में डेटा खिलाने के लिए जावास्क्रिप्ट को वेबव्यू में जोड़ें।
बुविविज

2

वास्तव में सॉफ्ट कीबोर्ड की उपस्थिति Activityकिसी भी तरह से प्रभावित नहीं करती है, चाहे windowSoftInputModeमैं किसी भी FullScreenमोड में हूं ।

हालाँकि मुझे इस प्रॉपर्टी पर अधिक दस्तावेज़ नहीं मिले, लेकिन मुझे लगता है कि इस FullScreenमोड को गेमिंग एप्लिकेशन के लिए डिज़ाइन किया गया था जिसे सॉफ्ट कीबोर्ड के अधिक उपयोग की आवश्यकता नहीं है। यदि आपकी गतिविधि एक गतिविधि है जिसमें नरम कीबोर्ड के माध्यम से उपयोगकर्ता के संपर्क की आवश्यकता होती है, तो कृपया गैर-पूर्णस्क्रीन थीम का उपयोग करके पुनर्विचार करें। आप किसी NoTitleBarथीम का उपयोग करके टाइटलबार को बंद कर सकते हैं । आप सूचना पट्टी क्यों छिपाना चाहेंगे?


2

बस के रूप में रखना android:windowSoftInputMode="adjustResize"। क्योंकि यह का केवल एक ही बाहर रखने के लिए दिया जाता है "adjustResize"और "adjustPan"(विंडो समायोजन मोड या तो adjustResize या adjustPan साथ निर्दिष्ट किया जाता है। यह सलाह दी जाती है कि आप हमेशा एक या अन्य निर्दिष्ट करें)। आप इसे यहां देख सकते हैं: http://developer.android.com/resources/articles/on-screen-inputs.html

यह मेरे लिए पूरी तरह से काम करता है।


मुझे कोई समस्या नहीं हो रही है ... मैंने आपका XML भी आज़माया है। यह भी काम करता है..मैं ओएस संस्करण 2.2 का उपयोग कर रहा हूं
बालाजी खडके

मैंने केवल फुल स्क्रीन मोड के साथ प्रयास किया है ... अपने नेक्सस वन और नेक्सस एस पर इसका परीक्षण कर रहा हूं .... यह काम करता है।
बालाजी खडके

1
मैंने गैलेक्सी एस, एचटीसी वाइल्डफायर, एचटीसी हीरो, मोटोरोला डीइज़ और सोनी एक्सपीरिया के साथ कोशिश की है। किसी एक डिवाइस पर काम नहीं कर रहा है।
विनीत शुक्ला


2

मैं वर्तमान में इस दृष्टिकोण का उपयोग कर रहा हूं और यह एक आकर्षण की तरह काम करता है। चाल हम ऊपर और नीचे 21 पर अलग-अलग तरीकों से कीबोर्ड की ऊंचाई प्राप्त करते हैं और फिर इसे हमारी गतिविधि में हमारे मूल दृश्य के निचले पैडिंग के रूप में उपयोग करते हैं। मैंने मान लिया कि आपके लेआउट को एक शीर्ष पैडिंग की आवश्यकता नहीं है (स्थिति बार के नीचे जाती है) लेकिन यदि आप ऐसा करते हैं, तो मुझे अपना उत्तर अपडेट करने के लिए सूचित करें।

MainActivity.java

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        RelativeLayout mainLayout = findViewById(R.id.main_layout);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            ViewCompat.setOnApplyWindowInsetsListener(mainLayout , new OnApplyWindowInsetsListener() {
                @Override
                public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
                    v.setPadding(0, 0, 0, insets.getSystemWindowInsetBottom());
                    return insets;
                }
            });
        } else {
            View decorView = getWindow().getDecorView();
            final View contentView = mainLayout;
            decorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    Rect r = new Rect();
                    //r will be populated with the coordinates of your view that area still visible.
                    decorView.getWindowVisibleDisplayFrame(r);

                    //get screen height and calculate the difference with the useable area from the r
                    int height = decorView.getContext().getResources().getDisplayMetrics().heightPixels;
                    int diff = height - r.bottom;

                    //if it could be a keyboard add the padding to the view
                    if (diff != 0) {
                        // if the use-able screen height differs from the total screen height we assume that it shows a keyboard now
                        //check if the padding is 0 (if yes set the padding for the keyboard)
                        if (contentView.getPaddingBottom() != diff) {
                            //set the padding of the contentView for the keyboard
                            contentView.setPadding(0, 0, 0, diff);
                        }
                    } else {
                        //check if the padding is != 0 (if yes reset the padding)
                        if (contentView.getPaddingBottom() != 0) {
                            //reset the padding of the contentView
                            contentView.setPadding(0, 0, 0, 0);
                        }
                    }
                }
            });
        }
    }
...
}

आईडी के साथ अपने मूल दृश्य को संबोधित करना न भूलें:

activity_main.xml

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/main_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

आशा है कि यह किसी की मदद करता है।


1
समझ में नहीं आ रहा है, क्यों यह जवाब अभी भी शीर्ष में नहीं है। कि अन्य लोग गड़बड़ करते हैं, फ्लैश करते हैं, लेकिन यह एक शानदार है, खासकर यदि आपके पास 5+ एपी है।
एंटोन शुकेंको

1

केवल तभी उपयोग करें android:windowSoftInputMode="adjustResize|stateHiddenजब आप एडजस्टमेंट का उपयोग करते हैं तब यह रिसाइज़िंग प्रॉपर्टी को निष्क्रिय कर देता है


मैंने इसका उपयोग भी किया है .... कृपया आप इसे पूर्ण स्क्रीन मोड में कर रहे हैं और आप किस डिवाइस पर परीक्षण कर रहे हैं?
विनीत शुक्ला

HTC नेक्सस एक, ठीक है मैं पूरी स्क्रीन नहीं जोड़ूंगा
मोहम्मद अजहरुद्दीन शेख

क्या आप getWindow () का उपयोग कर सकते हैं। requestFeature (Window.FEATURE_NO_TITLE); विषय का उपयोग करते हुए onCreate ()?
मोहम्मद अजहरुद्दीन शेख

10
उपरोक्त कोड पूर्ण स्क्रीन के बिना ठीक काम कर रहा है लेकिन xml से या कोड से पूर्ण स्क्रीन जोड़ रहा है ... यह काम नहीं कर रहा है ... कृपया प्रश्न को ध्यान से पढ़ें।
विनीत शुक्ला

1

मैंने इस्तेमाल किया जोसेफ जॉनसन ने AndroidBug5497Workaround क्लास बनाया, लेकिन सॉफ्टकीबोर्ड और दृश्य के बीच काली जगह मिल रही है। मैंने इस लिंक ग्रेग एनिस को संदर्भित किया । उपरोक्त में कुछ बदलाव करने के बाद यह मेरा अंतिम काम कोड है।

 public class SignUpActivity extends Activity {

 private RelativeLayout rlRootView; // this is my root layout
 private View rootView;
 private ViewGroup contentContainer;
 private ViewTreeObserver viewTreeObserver;
 private ViewTreeObserver.OnGlobalLayoutListener listener;
 private Rect contentAreaOfWindowBounds = new Rect();
 private FrameLayout.LayoutParams rootViewLayout;
 private int usableHeightPrevious = 0;

 private View mDecorView;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_sign_up);
  mDecorView = getWindow().getDecorView();
  contentContainer =
   (ViewGroup) this.findViewById(android.R.id.content);

  listener = new OnGlobalLayoutListener() {
   @Override
   public void onGlobalLayout() {
    possiblyResizeChildOfContent();
   }
  };

  rootView = contentContainer.getChildAt(0);
  rootViewLayout = (FrameLayout.LayoutParams)
  rootView.getLayoutParams();

  rlRootView = (RelativeLayout) findViewById(R.id.rlRootView);


  rlRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
   @Override
   public void onGlobalLayout() {
    int heightDiff = rlRootView.getRootView().getHeight() - rlRootView.getHeight();
    if (heightDiff > Util.dpToPx(SignUpActivity.this, 200)) {
     // if more than 200 dp, it's probably a keyboard...
     //  Logger.info("Soft Key Board ", "Key board is open");

    } else {
     Logger.info("Soft Key Board ", "Key board is CLOSED");

     hideSystemUI();
    }
   }
  });
 }

 // This snippet hides the system bars.
 protected void hideSystemUI() {
  // Set the IMMERSIVE flag.
  // Set the content to appear under the system bars so that the 
  content
  // doesn't resize when the system bars hide and show.
  mDecorView.setSystemUiVisibility(
   View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
 }
 @Override
 protected void onPause() {
  super.onPause();
  if (viewTreeObserver.isAlive()) {
   viewTreeObserver.removeOnGlobalLayoutListener(listener);
  }
 }

 @Override
 protected void onResume() {
  super.onResume();
  if (viewTreeObserver == null || !viewTreeObserver.isAlive()) {
   viewTreeObserver = rootView.getViewTreeObserver();
  }
  viewTreeObserver.addOnGlobalLayoutListener(listener);
 }

 @Override
 protected void onDestroy() {
  super.onDestroy();
  rootView = null;
  contentContainer = null;
  viewTreeObserver = null;
 }
 private void possiblyResizeChildOfContent() {
  contentContainer.getWindowVisibleDisplayFrame(contentAreaOfWindowBounds);

  int usableHeightNow = contentAreaOfWindowBounds.height();

  if (usableHeightNow != usableHeightPrevious) {
   rootViewLayout.height = usableHeightNow;
   rootView.layout(contentAreaOfWindowBounds.left,
    contentAreaOfWindowBounds.top, contentAreaOfWindowBounds.right, contentAreaOfWindowBounds.bottom);
   rootView.requestLayout();

   usableHeightPrevious = usableHeightNow;
  } else {

   this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
  }
 }
}

1

https://stackoverflow.com/a/19494006/1815624 पर आधारित और इसे बनाने की इच्छा ...

अद्यतन विचार


से उत्तर मिला रहा है

प्रासंगिक कोड:

        if (heightDifference > (usableHeightSansKeyboard / 4)) {

            // keyboard probably just became visible
            frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
        } else {

            // keyboard probably just became hidden
            if(usableHeightPrevious != 0) {
                frameLayoutParams.height = usableHeightSansKeyboard;
                activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
                activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

            }

पूर्ण स्रोत https://github.com/CrandellWS/AndroidBug5497Workaround/blob/master/AndroidBug5497Workaround.java पर

पुराना विचार

कीबोर्ड खोलने से पहले कंटेनरों की ऊंचाई का एक स्थिर मूल्य बनाएं। कीबोर्ड खुलने के आधार पर कंटेनर की ऊंचाई सेट करें usableHeightSansKeyboard - heightDifferenceऔर इसे बंद होने पर सहेजे गए मूल्य पर वापस सेट करें।

if (heightDifference > (usableHeightSansKeyboard / 4)) {
                // keyboard probably just became visible
                frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
                int mStatusHeight = getStatusBarHeight();
                frameLayoutParams.topMargin = mStatusHeight;
                ((MainActivity)activity).setMyMainHeight(usableHeightSansKeyboard - heightDifference);

                if(BuildConfig.DEBUG){
                    Log.v("aBug5497", "keyboard probably just became visible");
                }
            } else {
                // keyboard probably just became hidden
                if(usableHeightPrevious != 0) {
                    frameLayoutParams.height = usableHeightSansKeyboard;
                    ((MainActivity)activity).setMyMainHeight();    
                }
                frameLayoutParams.topMargin = 0;

                if(BuildConfig.DEBUG){
                    Log.v("aBug5497", "keyboard probably just became hidden");
                }
            }

मेनऐक्टिविटी में विधियाँ

public void setMyMainHeight(final int myMainHeight) {

    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            ConstraintLayout.LayoutParams rLparams =  (ConstraintLayout.LayoutParams) myContainer.getLayoutParams();
            rLparams.height = myMainHeight;

            myContainer.setLayoutParams(rLparams);
        }

    });

}

int mainHeight = 0;
public void setMyMainHeight() {

    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            ConstraintLayout.LayoutParams rLparams =  (ConstraintLayout.LayoutParams) myContainer.getLayoutParams();
            rLparams.height = mainHeight;

            myContainer.setLayoutParams(rLparams);
        }

    });

}

उदाहरण कंटेनर XML

<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
        <android.support.constraint.ConstraintLayout
            android:id="@+id/my_container"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintHeight_percent=".8">

यदि आवश्यक हो तो इसी तरह मार्जिन जोड़ा जा सकता है ...

एक अन्य विचार यह है कि इस पर एक उदाहरण पाडिंग का उपयोग किया जा सकता है:

https://github.com/mikepenz/MaterialDrawer/issues/95#issuecomment-80519589


1

1) KeyboardHeightHelper बनाएं:

public class KeyboardHeightHelper {

    private final View decorView;
    private int lastKeyboardHeight = -1;

    public KeyboardHeightHelper(Activity activity, View activityRootView, OnKeyboardHeightChangeListener listener) {
        this.decorView = activity.getWindow().getDecorView();
        activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
            int keyboardHeight = getKeyboardHeight();
            if (lastKeyboardHeight != keyboardHeight) {
                lastKeyboardHeight = keyboardHeight;
                listener.onKeyboardHeightChange(keyboardHeight);
            }
        });
    }

    private int getKeyboardHeight() {
        Rect rect = new Rect();
        decorView.getWindowVisibleDisplayFrame(rect);
        return decorView.getHeight() - rect.bottom;
    }

    public interface OnKeyboardHeightChangeListener {
        void onKeyboardHeightChange(int keyboardHeight);
    }
}

2) अपनी गतिविधि को पूर्ण स्क्रीन होने दें:

activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);

3) कीबोर्ड ऊंचाई में बदलाव के लिए सुनो और अपने विचार के लिए नीचे पैडिंग जोड़ें:

View rootView = activity.findViewById(R.id.root); // your root view or any other you want to resize
KeyboardHeightHelper effectiveHeightHelper = new KeyboardHeightHelper(
        activity, 
        rootView,
        keyboardHeight -> rootView.setPadding(0, 0, 0, keyboardHeight));

इसलिए , हर बार कीबोर्ड स्क्रीन पर दिखाई देगा - आपके विचार के लिए नीचे की पैडिंग बदल जाएगी, और सामग्री को फिर से व्यवस्थित किया जाएगा।


0

आप चाहते हैं कि नीचे की पट्टी दृश्य के निचले हिस्से से चिपके रहे, लेकिन जब कीबोर्ड प्रदर्शित होता है, तो उन्हें कीबोर्ड के ऊपर रखा जाना चाहिए, है ना?

आप इस कोड स्निपेट को आज़मा सकते हैं:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    ...>

    <RelativeLayout
        android:id="@+id/RelativeLayoutTopBar"
    ...>
    </RelativeLayout>

    <LinearLayout
        android:id="@+id/LinearLayoutBottomBar"
        android:layout_alignParentBottom = true
        ...>
    </LinearLayout>

    <LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="390dp"
    android:orientation="vertical" 
    android:layout_above="@+id/LinearLayoutBottomBar"
    android:layout_below="@+id/RelativeLayoutTopBar"> 

    <ScrollView 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp"
        android:id="@+id/ScrollViewBackground">

            ...

        </ScrollView>
     </LinearLayout>
  </RelativeLayout>

बॉटमबार व्यू के निचले हिस्से पर चिपके रहेंगे और स्क्रॉल व्यू वाले लाइनलेयआउट को टॉप / बॉटम बार और कीबोर्ड के प्रदर्शित होने के बाद व्यू के बायीं ओर ले जाया जाएगा। मुझे बताएं कि क्या यह आपके लिए भी काम करता है।


1
बहुत अजीब है क्योंकि यह कई बार मेरे ऐप्स में काम करता है। वैसे, RelativeLayout में कोई अभिविन्यास नहीं है ताकि आप अपने कोड में इन विशेषताओं को हटा सकें। मैंने अभी पहचाना कि मैं कोड स्निपेट को लाइन में काट सकता हूं: Android: Layout_below = "@ + id / scoringContainerView" जो आपको अपने
स्क्रॉलव्यू में

पूर्ण स्क्रीन? क्या आप शीर्ष पर एक लेआउट के बिना मतलब है?
बंजै Sep६

नहीं ..... मेरा मतलब है कोई स्टेटस बार जो बैटरी लाइफ, डिवाइस के लिए कनेक्टिविटी आदि को दिखाता है ....
विनीत शुक्ला

नहीं, मेरे ऐप में स्टेटसबार दिखाई दे रहा है। क्या आप अपने लेआउट के क्रम को बदलने की कोशिश कर सकते हैं, जिसका अर्थ है कि आपने अपने लेआउट के लिए कोड को दूसरे कोड के ऊपर के बटनों के साथ रखा है और फिर पुनः प्रयास करें? हो सकता है कि आपको
बजे

1
कृपया प्रश्न को ध्यान से पढ़ें ...... मैंने उल्लेख किया है कि मुझे फुलस्क्रीन मोड से परेशानी हो रही है ......
विनीत शुक्ला

0

आपके उत्तर के लिए धन्यवाद जोसेफ। हालांकि, विधि में संभवतःResResizeChildOfContent (), भाग

else {
            // keyboard probably just became hidden
            frameLayoutParams.height = usableHeightSansKeyboard;
        }

मेरे लिए काम नहीं कर रहा था, क्योंकि देखने का निचला हिस्सा छिप गया था। इसलिए मुझे एक वैश्विक वैरिएबल रिस्टोरहाइट लेना था, और कंस्ट्रक्टर में, मैंने आखिरी लाइन डाली

restoreHeight = frameLayoutParams.height;

और फिर मैंने पूर्व उल्लिखित भाग को बदल दिया

else {
            // keyboard probably just became hidden
            frameLayoutParams.height = restoreHeight;
        }

लेकिन मुझे नहीं पता कि आपके कोड ने मेरे लिए काम क्यों नहीं किया। यह बहुत मदद करेगा, अगर कोई इस पर प्रकाश डाल सकता है।


0

मैं केवल स्थिति पट्टी को छिपाने के लिए पूर्ण स्क्रीन मोड का उपयोग कर रहा था। हालांकि, मैं चाहता हूं कि कीबोर्ड दिखाए जाने पर ऐप आकार बदल दे। अन्य सभी समाधान (पोस्ट की उम्र के कारण होने की संभावना) मेरे उपयोग के लिए जटिल या संभव नहीं थे (PhoneGap Build के बोरी के लिए जावा कोड बदलने से बचना चाहते हैं)।

पूर्ण स्क्रीन का उपयोग करने के बजाय, मैंने एंड्रॉइड के लिए गैर-फुलस्क्रीन होने के लिए अपने कॉन्फ़िगर को संशोधित किया:

            <preference name="fullscreen" value="false" />

और cordova-plugin-statusbarकमांड लाइन के माध्यम से जोड़ा गया :

cordova plugin add cordova-plugin-statusbar

जब एप्लिकेशन लोड हो जाता है, तो मैं खुद को छिपाने के लिए प्लगइन पर एक विधि कहता हूं, जैसे:

    if (window.cordova && window.cordova.platformId == 'android' && window.StatusBar)
        window.StatusBar.hide();

यह एक आकर्षण की तरह काम करता है। केवल वास्तविक नकारात्मक पक्ष यह है कि ऐप लोड होने के दौरान स्थिति पट्टी संक्षिप्त रूप से दिखाई देती है। मेरी जरूरतों के लिए, यह एक मुद्दा नहीं था।


0

मैंने स्टैकऑवरफ्लो से सभी संभावित उत्तरों की कोशिश की है, आखिरकार एक हफ्ते की लंबी खोज के बाद मैंने हल किया। मैंने समन्वय लेआउट का उपयोग किया है और मैंने इसे रेखीय लयआउट के साथ बदल दिया है और मेरी समस्या ठीक हो गई है। मुझे नहीं पता कि संभवतः समन्वय लेआउट में बग या कुछ भी मेरी गलती है।


0

मैंने कई समाधानों की कोशिश की जिसमें जोसेफ जॉनसन और जोहान स्ट्यूट्स शामिल हैं। लेकिन परिणामस्वरूप मुझे सभी मामलों में कुछ उपकरणों (जैसे लेनोवो s820) पर सामग्री और कीबोर्ड के बीच एक सफेद स्थान मिला। इसलिए मैंने उनके कोड में कुछ बदलाव किए और आखिरकार काम करने का हल मिल गया।

जब कीबोर्ड दिखाई दे रहा है तो सामग्री के शीर्ष पर मार्जिन जोड़ने पर आधारित मेरा विचार।

contentContainer.getWindowVisibleDisplayFrame(contentAreaOfWindowBounds);
    int usableHeightNow = contentAreaOfWindowBounds.height();

    if (usableHeightNow != usableHeightPrevious) {

        int difference = usableHeightNow - usableHeightPrevious;

        if (difference < 0 && difference < -150) {
            keyboardShowed = true;
            rootViewLayout.topMargin -= difference + 30;
            rootViewLayout.bottomMargin += 30;
        }
        else if (difference < 0 && difference > -150){
            rootViewLayout.topMargin -= difference + 30;
        }
        else if (difference > 0 && difference > 150) {
            keyboardShowed = false;
            rootViewLayout.topMargin = 0;
            rootViewLayout.bottomMargin = 0;
        }

        rootView.requestLayout();

        Log.e("Bug Workaround", "Difference: " + difference);

        usableHeightPrevious = usableHeightNow;
}

जैसा कि आप देख सकते हैं, मैं अंतर में 30 पीएक्स जोड़ता हूं क्योंकि स्क्रीन के शीर्ष और मार्जिन के साथ सामग्री क्षेत्र के बीच एक छोटा सा सफेद स्थान है। और मुझे नहीं पता कि यह ऐसा प्रतीत होता है इसलिए मैंने फैसला किया कि बस मार्जिन को छोटा कर दें और अब यह ठीक उसी तरह से काम करता है जिसकी मुझे जरूरत थी।


0

आज पूर्ण स्क्रीन के मुद्दे पर समायोजन नहीं कर रहा है android sdk के लिए वास्तविक है।

मुझे मिले जवाबों से:
समाधान - लेकिन समाधान में चित्र मुद्दे पर यह दिखाया गया है:

क्या मुझे इसका समाधान मिला और एक अनावश्यक कार्रवाई को हटा दें:

this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);

तो, कोटलिन पर मेरा निश्चित समाधान कोड देखें:

class AndroidBug5497Workaround constructor(val activity: Activity) {

    private val content = activity.findViewById<View>(android.R.id.content) as FrameLayout

    private val mChildOfContent = content.getChildAt(0)
    private var usableHeightPrevious: Int = 0
    private val contentContainer = activity.findViewById(android.R.id.content) as ViewGroup
    private val rootView = contentContainer.getChildAt(0)
    private val rootViewLayout = rootView.layoutParams as FrameLayout.LayoutParams

    private val listener = {
        possiblyResizeChildOfContent()
    }

    fun addListener() {
        mChildOfContent.apply {
            viewTreeObserver.addOnGlobalLayoutListener(listener)

        }
    }

    fun removeListener() {
        mChildOfContent.apply {
            viewTreeObserver.removeOnGlobalLayoutListener(listener)
        }
    }

    private fun possiblyResizeChildOfContent() {
        val contentAreaOfWindowBounds = Rect()
        mChildOfContent.getWindowVisibleDisplayFrame(contentAreaOfWindowBounds)
        val usableHeightNow = contentAreaOfWindowBounds.height()

        if (usableHeightNow != usableHeightPrevious) {
            rootViewLayout.height = usableHeightNow
            rootView.layout(contentAreaOfWindowBounds.left,
                    contentAreaOfWindowBounds.top, contentAreaOfWindowBounds.right, contentAreaOfWindowBounds.bottom);
            mChildOfContent.requestLayout()
            usableHeightPrevious = usableHeightNow
        }
    }
}

मेरे बग फिक्सिंग कार्यान्वयन कोड:

 class LeaveDetailActivity : BaseActivity(){

    private val keyBoardBugWorkaround by lazy {
        AndroidBug5497Workaround(this)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

    }

    override fun onResume() {
        keyBoardBugWorkaround.addListener()
        super.onResume()
    }

    override fun onPause() {
        keyBoardBugWorkaround.removeListener()
        super.onPause()
    }
}

0

उपयोग न करें:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

क्योंकि बुरा काम करता है। इसके बजाय, उपयोग करें:

fun setFullScreen(fullScreen: Boolean) {
        val decorView = getWindow().getDecorView()
        val uiOptions : Int
        if(fullScreen){
            uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN // this hide statusBar
            toolbar.visibility = View.GONE // if you use toolbar
            tabs.visibility = View.GONE // if you use tabLayout
        } else {
            uiOptions = View.SYSTEM_UI_FLAG_VISIBLE // this show statusBar
            toolbar.visibility = View.VISIBLE
            tabs.visibility = View.VISIBLE
        }
        decorView.setSystemUiVisibility(uiOptions)
    }

-1

मेरे मामले में, यह मुद्दा तब शुरू हुआ जब मैंने अपने कॉर्डोवा एप्लिकेशन में क्रॉसस्वाक जोड़ दिया। मेरा ऐप फुलस्क्रीन और एंड्रॉइड में उपयोग नहीं किया गया है: windowSoftInputMode = "समायोजना"।

मेरे पास पहले से ही अनुप्रयोग में आयनिक कीबोर्ड प्लगइन था, इसलिए यह पता लगाना कि क्या कीबोर्ड ऊपर या नीचे था, इसके लिए आसान धन्यवाद:

// Listen for events to when the keyboard is opened and closed
window.addEventListener("native.keyboardshow", keyboardUp, false);
window.addEventListener('native.keyboardhide', keyboardDown, false);

function keyboardUp()
{
    $('html').addClass('keyboardUp');
}

function keyboardDown()
{
    $('html').removeClass('keyboardUp');
}

मैंने ऊपर दिए गए सभी सुधारों की कोशिश की, लेकिन जो सरल रेखा मेरे लिए इसे समाप्त कर रही थी, वह थी सीएसएस:

&.keyboardUp {
        overflow-y: scroll;
}

आशा है कि यह आपके द्वारा इस पर बिताए गए कुछ दिनों को बचाता है। :)


मैं कॉर्डोवा के साथ-साथ एंड्रॉइड के साथ क्रॉसवॉक का उपयोग कर रहा हूं: windowSoftInputMode = "adjustPan"। हालाँकि, यह काम नहीं कर रहा है। मैं देखता हूं कि html तत्व में क्लास को जोड़ा जा रहा है, लेकिन स्क्रीन पर css का कोई प्रभाव नहीं है। क्या आपके पास कुछ अन्य सेटिंग है जो स्क्रीन को स्थानांतरित करने की अनुमति देती है?
darewreck

मुझे ऐड ट्रांसफ़ॉर्म सेट करना है: इसके लिए ट्रांसलाइ (0px) काम करना है। हालाँकि, स्क्रॉल बिल्कुल काम नहीं करता है। कोई विचार?
darewreck
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.