中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何在Android中實現BottomSheet效果

發布時間:2021-05-14 17:49:49 來源:億速云 閱讀:214 作者:Leah 欄目:移動開發

這篇文章將為大家詳細講解有關如何在Android中實現BottomSheet效果,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

首先引入依賴包:

compile 'com.android.support:design:27.1.1'

頁面布局如下:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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">

  <LinearLayout
    android:id="@+id/customActionWebView"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="文本一"/>

    <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="文本二"/>
  </LinearLayout>

  <android.support.v4.widget.NestedScrollView
    android:id="@+id/nested_scroll_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:behavior_hideable="true"
    app:behavior_peekHeight="150dp"
    android:layout_gravity="bottom"
    app:layout_behavior="@string/bottom_sheet_behavior">

    <WebView
      android:id="@+id/web_view"
      android:layout_width="match_parent"
      android:layout_height="match_parent">

    </WebView>
  </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>

根布局需要使用CoordinatorLayout,同時在其直接子布局——這里是NestedScrollView——里添加behavior app:layout_behavior = "@string/bottom_sheet_behavior" 。很多文章說指定behavior的控件必須是NestedScrollView,這是錯誤的,實際上任何view或viewgroup都可以。該behavior配合CoordinateLayout就可以實現behavior所在控件的上滑效果。如果需要上滑的布局展示的時候先漏出一部分,如上面視頻所示,可以通過設置 app:behavior_peekHeight 實現,它用來指定漏出的高度。

在代碼部分,首先獲取NestedScrollView的behavior,然后通過behavior控制底部卡片什么時候彈出,同時會有一些狀態回調函數可供調用。

public class BrowserActivity extends AppCompatActivity {
  private NestedScrollView nestedScrollView;
  private BottomSheetBehavior behavior;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.browser_layout);

    nestedScrollView = (NestedScrollView) findViewById(R.id.nested_scroll_view);
    behavior = BottomSheetBehavior.from(nestedScrollView);
    behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
      @Override
      public void onStateChanged(@NonNull View bottomSheet, int newState) {
        //這里是bottomSheet 狀態的改變
      }

      @Override
      public void onSlide(@NonNull View bottomSheet, float slideOffset) {
        //這里是拖拽中的回調,根據slideOffset可以做一些動畫
      }
    });
  }

  public void showBottomSheet() {
    behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
  }
}

通過這種方式可以在特定的頁面添加底部上滑的效果。

BottomSheetDialog實現通用效果

BottomSheetDialog是BottomSheet效果實現的一種更加通用的方法,比如我們需要在不同的頁面實現長按文本彈出卡片列表效果,下面給出實現。

我們集成BottomSheetDialog實現自定義的Dialog,其布局如下:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

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

    <view class="com.example.trio.tensordemo.CustomBottomSheetDialogForWebView$NestViewEmbeddedListView"
      android:id="@+id/card_list_view"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:divider="@color/transparent"
      android:scrollbars="none"
      android:dividerHeight="15dp"
      android:layout_margin="20dp">
    </view>
  </LinearLayout>

</android.support.v4.widget.NestedScrollView>

注意,這里最外層布局需要是 NestedScrollView ,而 不能是CoordinateLayout ,因為BottomSheetDialog本身已經有個CoordinateLayout根布局,它會把你的布局文件包裹起來,如果你在自己的布局里把最外層布局寫成CoordinateLayout,會導致底部上滑的卡片,在下滑消失后屏幕依舊變暗的問題,這是因為整個布局變成了兩個CoordinateLayout嵌套,下滑的時候里面的CoordinateLayout滑出屏幕,但外層的CoordinateLayout仍然在展示。通過查閱BottomSheetDialog源碼可以看出,它是這樣包裹你的布局文件的:

public class BottomSheetDialog extends AppCompatDialog {
  ...
  @Override
  public void setContentView(@LayoutRes int layoutResId) {
    super.setContentView(wrapInBottomSheet(layoutResId, null, null));
  }
  
  private View wrapInBottomSheet(int layoutResId, View view, ViewGroup.LayoutParams params) {
    final FrameLayout container = (FrameLayout) View.inflate(getContext(),
        R.layout.design_bottom_sheet_dialog, null);
    final CoordinatorLayout coordinator =
        (CoordinatorLayout) container.findViewById(R.id.coordinator);
    if (layoutResId != 0 && view == null) {
      view = getLayoutInflater().inflate(layoutResId, coordinator, false);
    }
    FrameLayout bottomSheet = (FrameLayout) coordinator.findViewById(R.id.design_bottom_sheet);
    mBehavior = BottomSheetBehavior.from(bottomSheet);
    mBehavior.setBottomSheetCallback(mBottomSheetCallback);
    mBehavior.setHideable(mCancelable);
    if (params == null) {
      bottomSheet.addView(view);
    } else {
      bottomSheet.addView(view, params);
    }
    // We treat the CoordinatorLayout as outside the dialog though it is technically inside
    coordinator.findViewById(R.id.touch_outside).setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        if (mCancelable && isShowing() && shouldWindowCloseOnTouchOutside()) {
          cancel();
        }
      }
    });
    ...
    return container;
  }
  ...
}

所以,BottomSheetDialog本身的布局實際如下:

如何在Android中實現BottomSheet效果

BottomSheetDialog頁面布局

我們可以看到最外層是FrameLayout,里面有個CoordinateLayout,CoordinateLayout里面有個直接子布局FrameLayout,該CoordinateLayout指定了Behavior,最里面才是用戶自定義的布局,所以不應該在自定義布局里再添加CoordinateLayout,也不應該再次指定Behavior,直接擺放你的內容就行。

我們的自定義布局如下:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

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

    <view class="com.example.trio.tensordemo.CustomBottomSheetDialogForWebView$NestViewEmbeddedListView"
      android:id="@+id/card_list_view"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:divider="@color/transparent"
      android:scrollbars="none"
      android:dividerHeight="15dp"
      android:layout_margin="20dp">
    </view>
  </LinearLayout>

</android.support.v4.widget.NestedScrollView>

布局的核心是一個ListView,注意,由于ListView和behavior都需要處理滑動事件,所以直接使用ListView會導致滑動沖突,解決辦法是采用ScrollView嵌套ListView實現,同時使用自定義的ListView將所有列表項展開。

自定義的NestViewEmbeddedListView如下:

public static class NestViewEmbeddedListView extends ListView {
    public NestViewEmbeddedListView(android.content.Context context, android.util.AttributeSet attrs){
      super(context, attrs);
    }
    /**
     * 設置不滾動
     */
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
      int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
          MeasureSpec.AT_MOST);
      super.onMeasure(widthMeasureSpec, expandSpec);

    }
  }

自定義的BottomSheetDialog代碼如下:

public class CustomBottomSheetDialogForWebView extends BottomSheetDialog {
  private Context context;
  private NestViewEmbeddedListView listView;
  private NerResult nerResult;
  private CardListAdapter cardListAdapter = new CardListAdapter();

  public CustomBottomSheetDialogForWebView(@NonNull Context context, NerResult nerResult) {
    super(context);
    this.context = context;
    this.nerResult = nerResult;
    createView();
  }

  public void createView() {
    View bottomSheetView = getLayoutInflater().inflate(R.layout.webview_bottom_sheet_layout, null);
    setContentView(bottomSheetView);

    // 注意:這里要給layout的parent設置peekHeight,而不是在layout里給layout本身設置,下面設置背景色同理,坑爹!!!
    BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(((View) bottomSheetView.getParent()));
    bottomSheetBehavior.setPeekHeight(730);

    ((View) bottomSheetView.getParent()).setBackgroundColor(context.getResources().getColor(R.color.transparent));
    listView = bottomSheetView.findViewById(R.id.card_list_view);

    cardListAdapter.setNerItems(nerResult);
    listView.setAdapter(cardListAdapter);
  }
}

Android是什么

Android是一種基于Linux內核的自由及開放源代碼的操作系統,主要使用于移動設備,如智能手機和平板電腦,由美國Google公司和開放手機聯盟領導及開發。

關于如何在Android中實現BottomSheet效果就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

县级市| 九龙坡区| 罗平县| 铜鼓县| 马鞍山市| 乌苏市| 唐河县| 云浮市| 昔阳县| 中宁县| 金山区| 兴义市| 财经| 永定县| 新郑市| 从江县| 金平| 西和县| 磴口县| 乌拉特前旗| 克拉玛依市| 唐山市| 哈巴河县| 锡林郭勒盟| 商丘市| 舟山市| 额济纳旗| 榆树市| 温泉县| 永仁县| 六安市| 女性| 扶绥县| 德惠市| 琼结县| 丹棱县| 闽清县| 晋宁县| 丰镇市| 筠连县| 申扎县|