android-AdjustResize for Fragment[英] android - AdjustResize for Fragment

本文是小编为大家收集整理的关于android-AdjustResize for Fragment的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

美好的一天,先生! 我有一个带有Tablayout+ViewPager的活动,其中有2个片段.在第一个片段中,我有一个带有某些项目的回收道和工具栏中的搜索视图.我想向占位符展示您的搜索查询使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设置为GONE和LinearLayout LinearLayout VISIBLE.我遇到的问题是:adjustResize在我的活动的表现中,这项活动中的片段不起作用 - 占位符仍在键盘下方.我在活动中做了同样的事情,没有碎片,也是我唯一做的事情 - 在活动表现中设置adjustResize.如何用片段处理这个问题?

它的外观

在此处输入图像说明

upd:好吧,我找到了调整片段大小的解决方案 - 我在活动的根元素中添加了fitssystemwindows = true - 但它打破了我的状态栏...

推荐答案

upd 03.03.2021 :我的问题是在半透明的状态栏上,没有任何自定义类别的adjustResize adjustResize,一切正常.

好吧,现在我有一个工作解决方案.如果您使用的是SDK <21,则调整尺寸正常毫无问题,但是如果要在SDK上调整大小> 21,只需使用自定义类:

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

}

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

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

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

本文地址:https://www.itbaoku.cn/post/2091068.html

问题描述

Good day, sirs! I have an Activity with a TabLayout+ViewPager and 2 Fragments in it. In the first Fragment I have a RecyclerView with some items and the SearchView in the Toolbar. I want to show the placeholder when your search query makes RecyclerView disappear (I mean you found no results and RecyclerView.setVisibility(GONE)). So there's my 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>

So when my ItemList.size = 0 I set RecyclerView to GONE and LinearLayout to VISIBLE. The problem I got: adjustResize in Manifest of my Activity doesn't work for Fragment in this Activity - placeholder still under the keyboard by half. I did the same thing in the Activity without Fragment and the only thing I did - set adjustResize in Activity Manifest. How to deal with this problem with Fragment?

That how it looks like

enter image description here

UPD: Well, I found the solution that resizes my Fragment - I added fitsSystemWindows=true in the root element of my Activity - but it breaks my statusbar...

推荐答案

UPD 03.03.2021: My problem was with a translucent statusbar, without it everything works fine with adjustResize in Manifest without any custom class.

Okay, now I have a working solution. If you are using SDK<21 the resize works fine without any problem, but if you want to resize on SDK>21 just use custom class:

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

}

Then in the onCreate() method of Activity that you need to resize:

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

It works awesome for me. Good luck!