【问题标题】:Sliding layout below status bar in Umano SlidingPanelUmano SlidingPanel 中状态栏下方的滑动布局
【发布时间】:2016-01-11 15:59:06
【问题描述】:

我已经使用 https://github.com/umano/AndroidSlidingUpPanel 实现了 UmanoSlidingPanel。一切正常,除了我的滑动面板在展开时,滑动内容(sliding_view)在状态栏下方。我怎样才能避免这种情况?我尝试删除

 <item name="android:windowTranslucentStatus">true</item> 

来自styles.xml,但这使得状态栏对于主要内容也是不透明的。有什么办法解决这个问题?

<com.sothree.slidinguppanel.SlidingUpPanelLayout xmlns:sothree="http://schemas.android.com/apk/res-auto"
    android:id="@+id/sliding_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="bottom"
    sothree:umanoDragView="@+id/firstPanelDragArea"
    sothree:umanoPanelHeight="@dimen/bottom_panel_height"
    sothree:umanoShadowHeight="4dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <include
            android:id="@+id/toolbar"
            layout="@layout/toolbar" />

        <FrameLayout
            android:id="@+id/frame_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>

    <!-- SLIDING LAYOUT -->
    <LinearLayout
        android:id="@+id/firstPanelDragArea"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <include layout="@layout/sliding_view" />

    </LinearLayout>

styles.xml

 <style name="AppTheme" parent="@style/Theme.AppCompat">
    <item name="windowActionBar">false</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowTranslucentNavigation">true</item>
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:windowTranslucentStatus">true</item>
    <item name="windowNoTitle">true</item>
</style>

编辑

  public void onPanelSlide(View panel, float slideOffset) {
              if (slideOffset > 0.5 && !flagTransparent) {
                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
                flagTransparent = true;
                Log.i(TAG, "onPanelSlide, offset " + slideOffset);
            } else if (slideOffset < 0.5 && flagTransparent){
                getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
                flagTransparent = false;
                Log.i(TAG, "onPanelSlide, offset " + slideOffset);
  }

【问题讨论】:

    标签: android android-layout android-sliding


    【解决方案1】:

    1) 看看我创建的以下Gist

    文件sliding_up_activity.xml 可能是包含向上滑动面板视图的活动布局。 在那里你应该设置android:fitsSystemWindows="true",这样任何孩子都可以正确插入,不会落在操作栏或导航栏后面。

    文件sliding_view.xml 可能是您的向上滑动视图。

    您不需要在任何面板回调中执行任何其他操作。

    您可以安全地删除onPanelSlide() 中的半透明样式和代码。这应该会导致滑动面板正确插入,从而永远不会落后于状态或导航栏。

    或者,如果您没有相同的架构,您可以忘记sliding_up_activity.xml,而是在CoordinatorLayout 中设置android:fitsSystemWindows="true",而不是在sliding_view.xml 中。

    2) 我们讨论的第二件事是让状态栏变成半透明,让向上滑动的面板落在状态栏的后面,然后平滑地添加填充以正确插入内容。 为此,请设置android:fitsSystemWindows="false" 或将其从您的向上滑动面板具有的任何可能的父级中删除。 然后在onPanelSlide 你可以做这样的事情

        if (slideOffset >= ANCHOR_POINT) {
            // adjust the span of the offset
            float offset = (slideOffset - ANCHOR_POINT) / (1 - ANCHOR_POINT);
            // the padding top will be the base original padding plus a percentage of the status
            // bar height
            float paddingTop = mSlidePanelBasePadding + offset * mStatusBarInset;
            // apply the padding to the header container
            mContainer.setPadding(0, (int) paddingTop, 0, 0);
        }
    

    地点:

    • mSlidePanelBasePadding 将是您向上滑动面板的初始填充
    • mStatusBarInset 将是状态栏高度。

    当它越过锚点时,它应该逐渐向您的滑动面板添加填充。

    你可以这样获取状态栏高度:

    public int getStatusBarHeight() {
        int result = 0;
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }
    

    我希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      通过更改 SlidingUpPanelLayout.java 的 onMeasure 方法找到了另一个解决方案。贴出代码给以后的读者。需要添加4行代码。

      SlidingPanelLayout.java

       @Override
      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
          final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
          final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
          final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
          final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
      
          if (widthMode != MeasureSpec.EXACTLY) {
              throw new IllegalStateException("Width must have an exact value or MATCH_PARENT");
          } else if (heightMode != MeasureSpec.EXACTLY) {
              throw new IllegalStateException("Height must have an exact value or MATCH_PARENT");
          }
      
          final int childCount = getChildCount();
      
          if (childCount != 2) {
              throw new IllegalStateException("Sliding up panel layout must have exactly 2 children!");
          }
      
          mMainView = getChildAt(0);
          mSlideableView = getChildAt(1);
          if (mDragView == null) {
              setDragView(mSlideableView);
          }
      
          // If the sliding panel is not visible, then put the whole view in the hidden state
          if (mSlideableView.getVisibility() != VISIBLE) {
              mSlideState = PanelState.HIDDEN;
          }
      
          int layoutHeight = heightSize - getPaddingTop() - getPaddingBottom();
          int layoutWidth = widthSize - getPaddingLeft() - getPaddingRight();
      
          // First pass. Measure based on child LayoutParams width/height.
          for (int i = 0; i < childCount; i++) {
              final View child = getChildAt(i);
              final LayoutParams lp = (LayoutParams) child.getLayoutParams();
      
              // We always measure the sliding panel in order to know it's height (needed for show panel)
              if (child.getVisibility() == GONE && i == 0) {
                  continue;
              }
      
              int height = layoutHeight;
              int width = layoutWidth;
              if (child == mMainView) {
                  if (!mOverlayContent && mSlideState != PanelState.HIDDEN) {
                      height -= mPanelHeight;
                  }
      
                  width -= lp.leftMargin + lp.rightMargin;
              } else if (child == mSlideableView) {
                  // The slideable view should be aware of its top margin.
                  // See https://github.com/umano/AndroidSlidingUpPanel/issues/412.
       //                height -= lp.topMargin;.
       // START OF CODE CHANGES
                  if (height < SCREEN_HEIGHT) {  //SCREEN_HEIGHT = 900
                      height = height - MARGIN_BOTTOM; //MARGIN_BOTTOM = 8
                  } else {
                      height = height - getStatusBarHeight();
                  }
       // END OF CODE CHANGES
              }
      
      
        public int getStatusBarHeight() {
          int result = 0;
          int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
          if (resourceId > 0) {
          result = getResources().getDimensionPixelSize(resourceId);
          }
          return result;
      }
      

      【讨论】:

        【解决方案3】:

        在父布局中尝试android:fitsSystemWindows="true"。这应该可以解决您的问题。

        我过去实现的另一个解决方案是,在包含slidingUpPanel 的活动中,您可以使用半透明状态栏(API >= 19)对其进行样式设置:

        &lt;item name="android:windowTranslucentStatus"&gt;true&lt;/item&gt;

        然后在onPanelSlide 回调中,您可以修改您的slidingUpPanel 的填充逐渐添加,直到面板完全向上。在那一刻,添加的额外填充量应该是状态栏尺寸。

        【讨论】:

        • 我试过 android:fitsSystemWindows="true" 。它没有用。关于添加填充的第二个解决方案,我之前尝试过。它可以工作,但在展开面板时不能平滑过渡。
        • 你能发布你的布局吗?稍后我将发布如何在要点上进行平滑填充。主要是通过锚点并逐步使用滑动偏移百分比。这样一来,它就像一种魅力。
        • 我的意思是包含slidingUpPanelLayout的布局文件。
        • 编辑了我的问题以添加我在 onPanelSlide 中尝试过的内容。这使得状态栏在PanelExpanded 上不透明,但在向下滑动面板时,有时面板会再次展开。不知道为什么。
        • true 使状态栏只显示半透明颜色。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多