【问题标题】:android - AdjustResize for Fragmentandroid - 调整片段大小
【发布时间】:2017-12-22 21:13:40
【问题描述】:

早安,先生们! 我有一个带有 TabLayout+ViewPager 和 2 个片段的 Activity。在第一个片段中,我有一个带有一些项目的 RecyclerView 和工具栏中的 SearchView。当您的搜索查询使 RecyclerView 消失时,我想显示占位符(我的意思是您没有找到任何结果和RecyclerView.setVisibility(GONE))。所以这是我的 Fragment.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/pale_grey">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_results"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical"
        android:scrollbarThumbVertical="@android:color/darker_gray"
        android:scrollbarSize="4dp"/>

    <LinearLayout
        android:id="@+id/ll_no_categories"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentBottom="true"
        android:layout_below="@+id/toolbar"
        android:gravity="center"
        android:orientation="vertical"
        android:visibility="gone"
        android:fitsSystemWindows="true">

        <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_marginBottom="24dp"
            android:visibility="visible"
            app:srcCompat="@drawable/vector_search_big" />

        <TextView
            android:id="@+id/tv_no_categories"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:text="@string/activity_home_services_category_list_empty"
            android:textColor="@color/black_40"
            android:textSize="16sp"/>
    </LinearLayout>
</RelativeLayout>

所以当我的ItemList.size = 0 我将 RecyclerView 设置为 GONELinearLayout 设置为 VISIBLE。我遇到的问题:我的活动清单中的adjustResize 不适用于此活动中的片段 - 占位符仍在键盘下方一半。我在没有 Fragment 的 Activity 中做了同样的事情,我唯一做的事情是在 Activity Manifest 中设置 adjustResize。 Fragment如何处理这个问题?

UPD:嗯,我找到了调整 Fragment 大小的解决方案 - 我在 Activity 的根元素中添加了 fitSystemWindows=true - 但它破坏了我的状态栏...

【问题讨论】:

    标签: android android-fragments resize fragment window-soft-input-mode


    【解决方案1】:

    UPD 03.03.2021:我的问题是半透明状态栏,没有它,adjustResize in Manifest 没有任何自定义类,一切正常。

    好的,现在我有一个可行的解决方案。如果您使用 SDK21 上调整大小,只需使用自定义类:

    package YOUR_PACKAGE_NAME;
    
    import android.app.Activity;
    import android.content.Context;
    import android.content.res.Configuration;
    import android.content.res.Resources;
    import android.graphics.Point;
    import android.graphics.Rect;
    import android.os.Build;
    import android.view.Display;
    import android.view.KeyCharacterMap;
    import android.view.KeyEvent;
    import android.view.View;
    import android.view.ViewConfiguration;
    import android.view.ViewTreeObserver;
    import android.view.WindowManager;
    import android.widget.FrameLayout;
    
    import java.lang.reflect.InvocationTargetException;
    
    
    public class AdjustResizeHelper {
        private boolean mHasBackKey = false;
        private boolean mHasMenuKey = false;
        // 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 AdjustResizeHelper(activity);
        }
    
        private View mChildOfContent;
        private int usableHeightPrevious;
        private FrameLayout.LayoutParams frameLayoutParams;
    
        private int mNavBarHeight = 0;
    
        private AdjustResizeHelper(Activity activity) {
            mHasMenuKey = ViewConfiguration.get(activity).hasPermanentMenuKey();
            mHasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
    
            mNavBarHeight = getNavigationBarSize(activity).y;
    
            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 - mNavBarHeight;
                }
                mChildOfContent.requestLayout();
                usableHeightPrevious = usableHeightNow;
            }
        }
    
        public static Point getNavigationBarSize(Context context) {
            Point appUsableSize = getAppUsableScreenSize(context);
            Point realScreenSize = getRealScreenSize(context);
    
            // navigation bar on the right
            if (appUsableSize.x < realScreenSize.x) {
                return new Point(realScreenSize.x - appUsableSize.x, appUsableSize.y);
            }
    
            // navigation bar at the bottom
            if (appUsableSize.y < realScreenSize.y) {
                return new Point(appUsableSize.x, realScreenSize.y - appUsableSize.y);
            }
    
            // navigation bar is not present
            return new Point();
        }
    
        public static Point getAppUsableScreenSize(Context context) {
            WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            Display display = windowManager.getDefaultDisplay();
            Point size = new Point();
            display.getSize(size);
            return size;
        }
    
        public static Point getRealScreenSize(Context context) {
            WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            Display display = windowManager.getDefaultDisplay();
            Point size = new Point();
    
            if (Build.VERSION.SDK_INT >= 17) {
                display.getRealSize(size);
            } else if (Build.VERSION.SDK_INT >= 14) {
                try {
                    size.x = (Integer) Display.class.getMethod("getRawWidth").invoke(display);
                    size.y = (Integer) Display.class.getMethod("getRawHeight").invoke(display);
                } catch (IllegalAccessException e) {} catch (InvocationTargetException e) {} catch (NoSuchMethodException e) {}
            }
    
            return size;
        }
    
        private int computeUsableHeight() {
            Rect r = new Rect();
            mChildOfContent.getWindowVisibleDisplayFrame(r);
            return r.bottom;
        }
    
    }
    

    然后在Activity的onCreate()方法中需要调整大小:

    if(Build.VERSION.SDK_INT >= 21) {
                AdjustResizeHelper.assistActivity(this);
                }
    

    它对我来说很棒。祝你好运!

    【讨论】:

    • 好东西,但是页面布局在底部边缘爬行,请修复此问题(Pixel 3a A11)
    • 老实说这个答案已经过时了,因为我的问题是半透明状态栏。没有这个自定义类,Manifest 中的 adjustResize 一切正常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-11
    • 1970-01-01
    相关资源
    最近更新 更多