android - 调整片段大小

Posted

技术标签:

【中文标题】android - 调整片段大小【英文标题】:android - AdjustResize for Fragment 【发布时间】: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_
    android:layout_
    android:background="@color/pale_grey">

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

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

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

        <TextView
            android:id="@+id/tv_no_categories"
            android:layout_
            android:layout_
            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 - 但它破坏了我的状态栏...

【问题讨论】:

【参考方案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 一切正常。

以上是关于android - 调整片段大小的主要内容,如果未能解决你的问题,请参考以下文章

调整片段中 TextView 的文本大小

键盘打开时,带有片段的活动不会调整大小

显示键盘时防止 DialogFragment 调整大小/折叠

如何更改片段的大小?

android布局调整父级大小而不调整子级大小

Android 上的 Chrome 调整字体大小