问题描述
美好的一天,先生! 我有一个带有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); }
它对我来说很棒.祝你好运!
问题描述
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?
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!