国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android BottomSheet效果的兩種實現方式

2019-10-21 21:41:44
字體:
來源:轉載
供稿:網友

本文介紹了Android BottomSheet效果的兩種實現方式,分享給大家,具體如下:

Android,BottomSheet

BottomSheet效果

BottomSheet的效果是指從屏幕底部向上滑的效果,是MaterialDesign風格的一種,視覺效果如下:

Android,BottomSheet

BottomSheet效果

實現這種效果有幾種不同的方式,如果是在一個固定的頁面上添加這種效果,可以在該頁面布局中添加BoottomSheet相關的控件。如果是作為通用控件來提供給不同頁面使用,則可以使用BottomSheetDialog實現,本文將對兩種方法進行講解,其中會講到一些使用上的細節,處理不好這些細節,會出現非常怪異的效果。

單頁面添加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);  }}

這里需要注意的就是,設置背景透明和獲取Behavior都是對自定義布局的父布局,也就是bottomSheetView.getParent()進行。最終的效果就是下面的效果:

Android,BottomSheet

BottomSheet效果

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 海晏县| 房产| 武陟县| 嘉善县| 台南县| 肇东市| 龙江县| 闵行区| 石泉县| 耿马| 江山市| 延庆县| 惠水县| 汝南县| 青河县| 信阳市| 淳化县| 潜山县| 潼南县| 林芝县| 肥乡县| 贵港市| 安远县| 甘德县| 萨迦县| 土默特右旗| 惠水县| 新竹市| 房山区| 依兰县| 那坡县| 鄂托克前旗| 瑞昌市| 璧山县| 合肥市| 漠河县| 曲水县| 徐水县| 平陆县| 柳州市| 甘南县|