Search code examples
androidandroid-recyclerviewandroid-statusbar

How to get heights of a transparent softkeys bar and transparent status bar?


I have an activity containing a RecyclerView and both transparent status bar (the one containing wifi signal, etc...) and softkeys bar. Of course the number of items in the RecyclerView is undefined and i need the first one to have the standard top margin plus the status bar height, and the last one the standard bottom margin plus the height of the softkeys bar. This is needed because otherwise i'll get the first and the last items partially covered by the bars when the scroll is at the top or at the bottom respectively.

Here a sample code of how i'm handling the margins programmatically:

DisplayMetrics metrics = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);

        topSpace = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        bottomSpace = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        standardSpace = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);

        topSpace.setMargins(     (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8,    metrics),
                                 (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8 + 24, metrics),
                                 (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8,    metrics),
                                 (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8,    metrics));

        bottomSpace.setMargins(  (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8,    metrics),
                                 (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8,    metrics),
                                 (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8,    metrics),
                                 (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8 + 56, metrics) +
                                         getSoftkeysHeight(activity));

        standardSpace.setMargins((int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8,    metrics),
                                 (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8,    metrics),
                                 (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8,    metrics),
                                 (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8,    metrics));

I'm trying to use those answers but they seems not helping me because the drawable surface of the screen is indeed the whole screen...

Top bar is working fine Bottom not so fine...


Solution

  • You can use RecyclerView.ItemDecoration to modify the margins of the specific items.

    1. Create a class that extends RecyclerView.ItemDecoration :

      public static class SimpleItemDecorator extends RecyclerView.ItemDecoration {
      
      private int regularMargin;
      private int lastPosition;
      private int statusBarHeight;
      private int navigationBarHeight;
      
      public SimpleItemDecorator(Activity activity, int recyclerViewItemsCount) {
          // get the regular margin
          regularMargin = activity.getResources().getDimensionPixelSize(R.dimen.regularMargin);
      
          // determine the last position
          lastPosition = recyclerViewItemsCount - 1;
      
          // get the height of the status bar
          final Rect rectangle = new Rect();
          final Window window = activity.getWindow();
          window.getDecorView().getWindowVisibleDisplayFrame(rectangle);
          statusBarHeight = rectangle.top;
      
          // get the height of the navigation bar
          final int redId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
          navigationBarHeight = (redId > 0) ? resources.getDimensionPixelSize(resId) : 0;
      
      }
      
      @Override
      public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
          // modify the margins
          final int position = parent.getChildAdapterPosition(view);
          if (position == 0) {
              outRect.top = statusBarHeight + regularMargin;
          } else if (position == lastPosition) {
              outRect.bottom = navigationBar + regularMargin;
          }
      }
      

      }

    2. Add the created ItemDecorator to the RecyclerView :

      final int recyclerViewItemsCount = 6;
      final SimpleItemDecorator itemDecorator = new SimpleItemDecorator(this, recyclerViewItemsCount);
      recyclerView.addItemDecorator(itemDecorator);