windowSoftInputMode = “AdjustResize” tidak berfungsi dengan tindakan tembus / navbar

129

Saya memiliki masalah dengan actionbar / navbar tembus di Android KitKat baru (4.4) dan windowSoftInputMode="adjustResize".

Normaly mengubah InputMode untuk menyesuaikanResize, aplikasi harus mengubah ukuran sendiri ketika keyboard ditampilkan ... tetapi di sini tidak akan! Jika saya menghapus garis untuk efek transparan, ukurannya berfungsi.

Jadi jika keyboard terlihat, ListView saya ada di bawahnya dan saya tidak dapat mengakses beberapa item terakhir. (Hanya dengan menyembunyikan keyboard secara manual)

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="XYZ"
android:versionCode="23"
android:versionName="0.1" >

<uses-sdk
    android:minSdkVersion="9"
    android:targetSdkVersion="19" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/Theme.XYZStyle" >
    <activity
        android:name="XYZ"
        android:label="@string/app_name"
        android:windowSoftInputMode="adjustResize" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest>

values-v19 / styles.xml

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

<style name="Theme.XYZStyle" parent="@style/Theme.AppCompat.Light">
    <item name="android:windowTranslucentStatus">true</item>
    <item name="android:windowTranslucentNavigation">true</item>
</style>

</resources>

fragment.xml

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

<ListView
    android:id="@+id/listView_contacts"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    android:divider="@null"
    android:dividerHeight="0dp"
    android:drawSelectorOnTop="true"
    android:fastScrollAlwaysVisible="true"
    android:fastScrollEnabled="true"
    android:paddingBottom="@dimen/navigationbar__height" >
</ListView>

</RelativeLayout>

Adakah ide untuk memperbaikinya?

fabianbru
sumber

Jawaban:

184

Anda kehilangan properti berikut:

android:fitsSystemWindows="true"

di root RelativeLayoutdari fragmen tata letak xml.

Memperbarui:

Tahun lalu ada pembicaraan menarik oleh Chris Bane yang menjelaskan dengan sangat rinci bagaimana ini bekerja:

https://www.youtube.com/watch?v=_mGDMVRO3iE

pablisco
sumber
5
Saya kira itu sesuatu dengan kebijakan layar penuh
Felix.D
1
Kamulah orangnya! Saya masalah ini terjadi pada saya hanya pada versi Lollipop, dan itu memperbaikinya.
David
6
@ David Ini belum diperbaiki, masih membobol perangkat marshmallow, jika Anda membuka dialog dan mencoba menggulir maka softkeboard akan memblokir pengguliran
Bytecode
5
Berhasil, tetapi bertentangan dengan kustomisasi bilah alat dan statusbar saya
Ninja
2
berfungsi tetapi kemudian bilah status tidak tembus lagi. Saya ingin tata letak untuk menutupi seluruh layar.
htafoya
34

Ada laporan bug terkait di sini . Saya telah menemukan solusi yang, dari pengujian terbatas, tampaknya melakukan trik tanpa dampak. Tambahkan implementasi kustom root Anda ViewGroup(saya hampir selalu menggunakan FrameLayout, jadi ini yang saya uji dengan) dengan logika di bawah ini. Kemudian, gunakan tata letak khusus ini sebagai pengganti tata letak root Anda, dan pastikan Anda mengatur android:fitsSystemWindows="true". Anda kemudian dapat memanggil getInsets()kapan saja setelah tata letak (misalnya menambahkan OnPreDrawListener) untuk menyesuaikan sisa tata letak Anda dengan memperhitungkan insets sistem, jika diinginkan.

import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.FrameLayout;
import org.jetbrains.annotations.NotNull;

/**
 * @author Kevin
 *         Date Created: 3/7/14
 *
 * https://code.google.com/p/android/issues/detail?id=63777
 * 
 * When using a translucent status bar on API 19+, the window will not
 * resize to make room for input methods (i.e.
 * {@link android.view.WindowManager.LayoutParams#SOFT_INPUT_ADJUST_RESIZE} and
 * {@link android.view.WindowManager.LayoutParams#SOFT_INPUT_ADJUST_PAN} are
 * ignored).
 * 
 * To work around this; override {@link #fitSystemWindows(android.graphics.Rect)},
 * capture and override the system insets, and then call through to FrameLayout's
 * implementation.
 * 
 * For reasons yet unknown, modifying the bottom inset causes this workaround to
 * fail. Modifying the top, left, and right insets works as expected.
 */
public final class CustomInsetsFrameLayout extends FrameLayout {
    private int[] mInsets = new int[4];

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

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

    public CustomInsetsFrameLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public final int[] getInsets() {
        return mInsets;
    }

    @Override
    protected final boolean fitSystemWindows(@NotNull Rect insets) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            // Intentionally do not modify the bottom inset. For some reason, 
            // if the bottom inset is modified, window resizing stops working.
            // TODO: Figure out why.

            mInsets[0] = insets.left;
            mInsets[1] = insets.top;
            mInsets[2] = insets.right;

            insets.left = 0;
            insets.top = 0;
            insets.right = 0;
        }

        return super.fitSystemWindows(insets);
    }
}

Karena fitSystemWindows sudah tidak digunakan lagi, silakan merujuk ke jawaban di bawah ini untuk menyelesaikan solusinya.

Kevin Coppock
sumber
1
Sebenarnya SOFT_INPUT_ADJUST_PAN tampaknya TIDAK diabaikan menurut pengalaman saya - itu akan memindahkan seluruh layar ke atas, termasuk bilah sistem dan menggeser keyboard di bawah tampilan fokus.
sealskej
Terima kasih - Anda benar tentang SOFT_INPUT_ADJUST_PAN. Saya menggunakan ini di fragmen saya: getActivity (). GetWindow (). SetSoftInputMode (WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
Simon
Itulah satu-satunya cara saya dapat melakukan penyesuaianResize untuk aktivitas (diperlukan untuk menggulir tampilan saat menampilkan keyboard), fitSystemWindows disetel benar sehingga gulir benar-benar terjadi pada> = Lollipop dan memiliki statusBar yang tembus cahaya. Terima kasih banyak.
Lucas
ini adalah solusi aktual
martyglaubitz
Butuh waktu untuk menampilkan dan menyembunyikan keyboard, bahkan butuh waktu untuk mendorong tata letak ke atas. Ada Solusi?
Vanjara Sweta
28

Jawaban @kcoppock sangat membantu, tetapi fitSystemWindows sudah tidak digunakan lagi di API level 20

Jadi sejak API 20 (KITKAT_WATCH) Anda harus menimpa onApplyWindowInsets

@Override
public final WindowInsets onApplyWindowInsets(WindowInsets insets) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
        return super.onApplyWindowInsets(insets.replaceSystemWindowInsets(0, 0, 0,
                insets.getSystemWindowInsetBottom()));
    } else {
        return insets;
    }
}
Victor91
sumber
Di kelas apa kita harus mengganti ini?
Ben-J
@ Ben-J di kelas yang memperluas kelas asli
Victor91
Saya tidak tahu mengapa Anda mengatur elemen array mInsets sementara itu tidak digunakan, tetapi berfungsi
Buckstabue
1
Alih-alih memeriksa versi Anda, Anda dapat menggunakanViewCompat.setOnApplyWindowInsetsListener
repitch
Saya tidak bisa mendapatkan ini berfungsi, tetapi dispatchApplyWindowInsetssebaliknya (kode yang sama) bekerja untuk saya
petter
11

Ini berfungsi agar saya memiliki bilah status transparan dan sesuaikanResifikasi dalam fragmen:

  1. Buat RelativeLayout khusus seperti yang dikatakan @ Victor91 dan @kcoppock.

  2. Gunakan CustomRelativeLayout sebagai tata letak induk untuk fragmen Anda.

  3. Nyatakan tema dengan android: windowTranslucentStatus = true

  4. Kegiatan wadah harus dideklarasikan dalam Manifest dengan android: windowSoftInputMode = "AdjustResize" dan gunakan tema yang dideklarasikan

  5. Silakan Gunakan cocokSystemWindows pada tata letak root fragmen!

    public class CustomRelativeLayout extends RelativeLayout {
    
        private int[] mInsets = new int[4];
    
        public CustomRelativeLayout(Context context) {
            super(context);
        }
    
        public CustomRelativeLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public CustomRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        public CustomRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
            super(context, attrs, defStyleAttr, defStyleRes);
        }
    
        @Override
        public final WindowInsets onApplyWindowInsets(WindowInsets insets) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
                mInsets[0] = insets.getSystemWindowInsetLeft();
                mInsets[1] = insets.getSystemWindowInsetTop();
                mInsets[2] = insets.getSystemWindowInsetRight();
                return super.onApplyWindowInsets(insets.replaceSystemWindowInsets(0, 0, 0,
                        insets.getSystemWindowInsetBottom()));
            } else {
                return insets;
            }
        }
    }

Kemudian dalam xml,

<com.blah.blah.CustomRelativeLayout 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:fitsSystemWindows="true">
</com.blah.blah.CustomRelativeLayout>
Herman
sumber
1
Ini adalah jawaban terbaik sejauh ini, dan saya sedang mencari solusi beberapa saat sekarang. Ini berfungsi dengan baik, tetapi Anda harus menambahkan beberapa bantalan tambahan ke bilah alat, tanpa itu bilah alat Anda akan tumpang tindih statusbar
Paulina
Bagaimana dengan windowTranslucentNavigation? dapatkah kamu membantu dengan itu
V-rund Puro-hit
10

Jika Anda ingin menyesuaikan insets dan Anda menargetkan level API> = 21 Anda dapat melakukannya tanpa harus membuat grup tampilan kustom. Dengan hanya mengaturfitsSystemWindows pelapis akan diterapkan ke tampilan wadah Anda secara default, yang mungkin tidak Anda inginkan.

Pemeriksaan versi dibuat dalam metode ini dan hanya perangkat> = 21 yang akan menjalankan kode di dalam lambda. Contoh Kotlin:

ViewCompat.setOnApplyWindowInsetsListener(container) { view, insets ->
  insets.replaceSystemWindowInsets(0, 0, 0, insets.systemWindowInsetBottom).apply {
    ViewCompat.onApplyWindowInsets(view, this)
  }
}

Pastikan tata letak Anda masih menetapkan fitsSystemWindowsbendera, jika tidak pendengar inset jendela tidak akan dipanggil.

<FrameLayout
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    />

Sumber-sumber ini sangat membantu:

https://medium.com/google-developers/why-would-i-want-to-fitssystemwindows-4e26d9ce1eec https://medium.com/@azizbekian/windowinsets-24e241d4afb9

Victor Rendina
sumber
1
Ini masih tetap merupakan pendekatan terbaik, karena Anda dapat menerapkan ini adalah Anda BaseFragment, bersama view.fitsSystemWindows = truedan itu hanya berfungsi tanpa perubahan pada tata letak XML aktual atau Lihat subkelas.
Bogdan Zurac
5

Saya memiliki masalah yang sama, Aktivitas Saya memiliki ScrollView sebagai tampilan root dan dengan statusbar transparan diaktifkan tidak mengubah ukuran dengan benar ketika keyboard menunjukkan ... dan secara konsisten layar tidak menggulir menyembunyikan tampilan input.

Solusi: Memindahkan semuanya (tata letak dan logika aktivitas) di dalam Fragmen baru. Kemudian ubah Kegiatan hanya untuk menyertakan Fragmen ini. Sekarang semuanya berjalan seperti yang diharapkan!

Ini adalah tata letak aktivitas:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"

    android:id="@+id/contentView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true" />
araks
sumber
Bekerja seperti pesona bagi saya
seperti
2

Berdasarkan solusi Joseph Johnson di Android Cara menyesuaikan tata letak dalam Mode Layar Penuh ketika papan tombol terlihat

panggil ini onCreate()setelah setContentView()aktivitas Anda.

AndroidBug5497Workaround.assistActivity(this);

litte berbeda dari yang asli ganti return (r.bottom - r.top);dengan return r.bottom;incomputeUsableHeight()

untuk beberapa alasan, saya harus mengatur fitsSystemWindowsatribut aktivitas saya false.

solusi ini menyelamatkan saya. ini bekerja dengan baik untuk saya. semoga dapat membantu anda

kelas implementasi adalah:

public class AndroidBug5497Workaround {

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

}
Loyea
sumber
2

Seharusnya tidak bekerja dengan bilah status transparan; pengaturan yang memaksa jendela ke mode layar penuh yang tidak bekerja dengan adjustResize.

Anda bisa menggunakan AdjustPan atau menggunakan properti fitsSystemWindows. Saya sarankan membaca tentang fitur ini, ia memiliki efek samping yang signifikan:

https://medium.com/google-developers/why-would-i-want-to-fitssystemwindows-4e26d9ce1eec

TenangGeoffrey
sumber
0

AndroidBug5497Workaround.java berhati-hati dengan kebocoran memori. perlu kode di bawah ini

getViewTreeObserver().removeOnGlobalLayoutListener(listener);

Sampel saya menggunakan RxJava yang secara otomatis memanggil removeOnGlobalLayoutListener () ketika onPause () dalam siklus hidup Activity

public class MyActivity extends RxAppCompatActivity {
    // ...

protected void onStart(){
    super.onStart();

        TRSoftKeyboardVisibility
            .changes(this) // activity
            .compose(this.<TRSoftKeyboardVisibility.ChangeEvent>bindUntilEvent(ActivityEvent.PAUSE))
            .subscribe(keyboardEvent -> {
                FrameLayout content = (FrameLayout) findViewById(android.R.id.content);
                View firstChildView = content.getChildAt(0);
                firstChildView.getLayoutParams().height = keyboardEvent.viewHeight();
                firstChildView.requestLayout();

                // keyboardEvent.isVisible      = keyboard visible or not
                // keyboardEvent.keyboardHeight = keyboard height
                // keyboardEvent.viewHeight     = fullWindowHeight - keyboardHeight
            });
   //...
}





package commonlib.rxjava.keyboard;

import android.app.Activity;
import android.view.View;
import android.widget.FrameLayout;
import kr.ohlab.android.util.Assert;
import rx.Observable;

public class TRSoftKeyboardVisibility {

    public static Observable<ChangeEvent> changes(Activity activity) {
        Assert.notNull(activity, "activity == null");
        FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
        View childOfContent = content.getChildAt(0);
        return Observable.create(
            new TRSoftKeyboardVisibilityEventOnSubscribe(childOfContent));
    }

    public static final class ChangeEvent {
        private final int keyboardHeight;
        private final boolean visible;
        private final int viewHeight;

        public static ChangeEvent create(boolean visible, int keyboardHeight,
            int windowDisplayHeight) {
            return new ChangeEvent(visible, keyboardHeight, windowDisplayHeight);
        }

        private ChangeEvent(boolean visible, int keyboardHeight, int viewHeight) {
            this.keyboardHeight = keyboardHeight;
            this.visible = visible;
            this.viewHeight = viewHeight;
        }

        public int keyboardHeight() {
            return keyboardHeight;
        }

        public boolean isVisible() {
            return this.visible;
        }

        public int viewHeight() {
            return viewHeight;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof ChangeEvent)) return false;

            ChangeEvent that = (ChangeEvent) o;

            if (keyboardHeight != that.keyboardHeight) return false;
            if (visible != that.visible) return false;
            return viewHeight == that.viewHeight;
        }

        @Override
        public int hashCode() {
            int result = keyboardHeight;
            result = 31 * result + (visible ? 1 : 0);
            result = 31 * result + viewHeight;
            return result;
        }

        @Override
        public String toString() {
            return "ChangeEvent{" +
                "keyboardHeight=" + keyboardHeight +
                ", visible=" + visible +
                ", viewHeight=" + viewHeight +
                '}';
        }
    }
}


package commonlib.rxjava.keyboard;

import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;
import kr.ohlab.android.util.Assert;
import rx.Observable;
import rx.Subscriber;
import rx.android.MainThreadSubscription;
import timber.log.Timber;

public class TRSoftKeyboardVisibilityEventOnSubscribe
    implements Observable.OnSubscribe<TRSoftKeyboardVisibility.ChangeEvent> {
    private final View mTopView;
    private int mLastVisibleDecorViewHeight;
    private final Rect mWindowVisibleDisplayFrame = new Rect();

    public TRSoftKeyboardVisibilityEventOnSubscribe(View topView) {
        mTopView = topView;
    }

    private int computeWindowFrameHeight() {
        mTopView.getWindowVisibleDisplayFrame(mWindowVisibleDisplayFrame);
        return (mWindowVisibleDisplayFrame.bottom - mWindowVisibleDisplayFrame.top);
    }

    private TRSoftKeyboardVisibility.ChangeEvent checkKeyboardVisibility() {
        int windowFrameHeightNow = computeWindowFrameHeight();
        TRSoftKeyboardVisibility.ChangeEvent event = null;
        if (windowFrameHeightNow != mLastVisibleDecorViewHeight) {
            int mTopViewHeight = mTopView.getHeight();
            int heightDiff = mTopViewHeight - windowFrameHeightNow;
            Timber.e("XXX heightDiff=" + heightDiff);
            if (heightDiff > (mTopViewHeight / 4)) {
                event = TRSoftKeyboardVisibility.ChangeEvent.create(true, heightDiff, windowFrameHeightNow);
            } else {
                event = TRSoftKeyboardVisibility.ChangeEvent.create(false, 0, windowFrameHeightNow);
            }
            mLastVisibleDecorViewHeight = windowFrameHeightNow;
            return event;
        }

        return null;
    }

    public void call(final Subscriber<? super TRSoftKeyboardVisibility.ChangeEvent> subscriber) {
        Assert.checkUiThread();

        final ViewTreeObserver.OnGlobalLayoutListener listener =
            new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    TRSoftKeyboardVisibility.ChangeEvent event = checkKeyboardVisibility();
                    if( event == null)
                        return;
                    if (!subscriber.isUnsubscribed()) {
                        subscriber.onNext(event);
                    }
                }
            };

        mTopView.getViewTreeObserver().addOnGlobalLayoutListener(listener);

        subscriber.add(new MainThreadSubscription() {
            @Override
            protected void onUnsubscribe() {
                mTopView.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
            }
        });
    }
}
ohlab
sumber
0

Saya punya masalah.

Saya mengatur windowDrawsSystemBarBackgrounds ke 'true' dan aplikasi saya akan ditampilkan di bawah bilah status.

Itu tema aktivitas saya.

<item name="android:windowTranslucentStatus" tools:targetApi="KITKAT">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>

dan saya mendapat bantuan dari blog jianshu . Anda dapat membaca kode tetapi teks seperti saya. Saya menambahkan beberapa kode lagi.

public final class ZeroInsetsFrameLayout extends FrameLayout {
    private int[] mInsets = new int[4];

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

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

    public ZeroInsetsFrameLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public final int[] getInsets() {
        return mInsets;
    }

    @Override
    public WindowInsets computeSystemWindowInsets(WindowInsets in, Rect outLocalInsets) {
        outLocalInsets.left = 0;
        outLocalInsets.top = 0;
        outLocalInsets.right = 0;

        return super.computeSystemWindowInsets(in, outLocalInsets);
    }

    @Override
    protected final boolean fitSystemWindows(@NonNull Rect insets) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            // Intentionally do not modify the bottom inset. For some reason,
            // if the bottom inset is modified, window resizing stops working.
            // TODO: Figure out why.

            mInsets[0] = insets.left;
            mInsets[1] = insets.top;
            mInsets[2] = insets.right;

            insets.left = 0;
            insets.top = 0;
            insets.right = 0;
        }

        return super.fitSystemWindows(insets);
    }
}

Ini adalah tata letak fragmen saya.

<com.dhna.widget.ZeroInsetsFrameLayout 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"
    android:fitsSystemWindows="true"
    android:background="@color/white">

    <!-- your xml code -->

</ZeroInsetsFrameLayout>

Saya ingin ini membantu Anda. semoga berhasil!

Hogun
sumber
Butuh waktu untuk menyembunyikan dan menampilkan keyboard dan juga butuh waktu untuk mendorong tata letak ke atas. Ada solusi? Bagaimana cara mengaturnya?
Vanjara Sweta
0
  • Setelah saya teliti di semua forum. cara-cara ini tidak dapat membantu menemukan titik. Beruntung ketika saya mencoba melakukan hal ini. Ini membantu saya menyelesaikan masalah

XML

<RelativeLayout 
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:fitsSystemWindows="true">
       <!-- Your xml -->
    </RelativeLayout>

Aktivitas

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView("Your Activity");
   setAdjustScreen();

}

Menciptakan fungsi

protected void setAdjustScreen(){
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
        /*android:windowSoftInputMode="adjustPan|adjustResize"*/
}

Akhirnya menambahkan beberapa baris ke tampilan utama Anda

 <activity
     android:name="Your Activity"
     android:windowSoftInputMode="adjustPan|adjustResize"
     android:screenOrientation="portrait"></activity>
Trần Thanh Phong
sumber
0

Saya memiliki masalah yang sama. Saya telah memecahkan masalah menggunakan coordinatorlayout

activity.main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    android:layout_height="match_parent" android:layout_width="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">


    <android.support.design.widget.AppBarLayout
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.v7.widget.Toolbar
        android:layout_height="?attr/actionBarSize"
        android:layout_width="match_parent"
        app:popupTheme="@style/AppTheme.PopupOverlay"
        android:background="?attr/colorPrimary"
        android:id="@+id/toolbar"/>

</android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main2"/>

</android.support.design.widget.CoordinatorLayout>

content_main2.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">


    <android.support.v7.widget.RecyclerView
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:layout_marginTop="30dp"
        android:layout_marginBottom="30dp"
        app:layout_scrollFlags="scroll|exitUntilCollapsed"
        android:id="@+id/post_msg_recyclerview">
    </android.support.v7.widget.RecyclerView>

    <EditText
        android:layout_width="match_parent"
        android:layout_height="50dp"
        app:layout_constraintBottom_toBottomOf="parent"
        android:background="@color/colorPrimary"


        />

</android.support.constraint.ConstraintLayout>

MainActivity.java

sekarang tambahkan baris ini linearLayoutManager.setStackFromEnd (true);

 LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        linearLayoutManager.setStackFromEnd(true);
        recyclerView.setLayoutManager(linearLayoutManager);
        Adapter adapter1=new Adapter(arrayList);
        recyclerView.setAdapter(adapter1);
gaurav gupta
sumber
0
<androidx.constraintlayout.widget.ConstraintLayout
  android:fitsSystemWindows="true">

  <androidx.coordinatorlayout.widget.CoordinatorLayout>
    <com.google.android.material.appbar.AppBarLayout>

      <com.google.android.material.appbar.CollapsingToolbarLayout/>

    </com.google.android.material.appbar.AppBarLayout>

    <androidx.core.widget.NestedScrollView>
    <Editext/>
    <androidx.core.widget.NestedScrollView/>

  </androidx.coordinatorlayout.widget.CoordinatorLayout>

</androidx.constraintlayout.widget.ConstraintLayout>
shehan gamage
sumber
0

Tambahkan ini dulu di tata letak root Anda.

android:fitsSystemWindows="true"

Saat Anda menggunakan pendekatan ini, menjadi tanggung jawab Anda untuk memastikan bahwa bagian-bagian penting dari UI aplikasi Anda (misalnya, kontrol bawaan dalam aplikasi Maps) tidak berakhir dengan diliputi oleh bilah sistem. Ini bisa membuat aplikasi Anda tidak dapat digunakan. Dalam kebanyakan kasus, Anda dapat menangani ini dengan menambahkan atribut android: fitsSystemWindows ke file tata letak XML Anda, atur true. Ini menyesuaikan bantalan ViewGroup induk untuk memberikan ruang bagi sistem windows. Ini cukup untuk sebagian besar aplikasi.

Namun, dalam beberapa kasus, Anda mungkin perlu memodifikasi lapisan default untuk mendapatkan tata letak yang diinginkan untuk aplikasi Anda. Untuk memanipulasi secara langsung bagaimana konten Anda ditampilkan relatif terhadap bilah sistem (yang menempati ruang yang dikenal sebagai "insets konten" jendela), ganti fitSystemWindows (insets persegi). Metode fitSystemWindows () dipanggil oleh hierarki tampilan ketika inset konten untuk jendela telah berubah, untuk memungkinkan jendela menyesuaikan isinya. Dengan mengganti metode ini Anda dapat menangani insets (dan karenanya tata letak aplikasi Anda) seperti yang Anda inginkan.

https://developer.android.com/training/system-ui/status#behind

Jika Anda ingin menjadi tukang jendela utama, silakan tonton video dari pengembang android. https://www.youtube.com/watch?v=_mGDMVRO3iE

Xiaoyuan hu
sumber
-1

Praktik terbaik memungkinkan konten gulir pengguna saat keyboard ditampilkan. Jadi untuk menambahkan fungsi ini Anda perlu meletakkan tata letak root Anda di dalam ScrollViewdan gunakanwindowSoftInputMode="adjustResize" metode aktivitas.

Tetapi jika Anda ingin menggunakan fungsi ini dengan <item name="android:windowTranslucentStatus">true</item> flag pada Android 5 konten tidak akan dapat digulir dan akan tumpang tindih dengan keyboard.

Untuk mengatasi masalah ini, periksa jawaban ini

Membuang
sumber