在有些桌面軟體或應用程式中,會看到可由螢幕下方拖拉出畫面的效果 (如Google Map),像這樣↓↓
這邊介紹簡單的製作方式:
首先以 GitHub 上的 PixelSlide 專案作為範例
原理就是在 CoordinatorLayout 中加入 include 區域,然後將另一個 view 引導進來
主要程式碼說明如下:
public class MainActivity extends AppCompatActivity { private View mBottomSheet; private BottomSheetBehavior mBottomSheetBehavior; private ExpandIconView mExpandIconView; private float mSlideOffset = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViews(); setUpViews(); } private void findViews() { mBottomSheet = findViewById(R.id.bottom_sheet); //這邊是初始化拖拉畫面中的元件 mExpandIconView = (ExpandIconView) mBottomSheet.findViewById(R.id.expandIconView); } private void setUpViews() { //設定箭頭icon的狀態(套件) mExpandIconView.setState(ExpandIconView.LESS, true); //將mBottomSheet綁定給BottomSheetBehavior mBottomSheetBehavior = BottomSheetBehavior.from(mBottomSheet); //監聽BottomSheetBehavior拖動過程 mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { @Override public void onStateChanged(@NonNull View bottomSheet, int newState) { //拖動的畫面狀態切換 if (newState == BottomSheetBehavior.STATE_COLLAPSED) { mExpandIconView.setState(ExpandIconView.LESS, true); } else if (newState == BottomSheetBehavior.STATE_EXPANDED) { mExpandIconView.setState(ExpandIconView.MORE, true); } } @Override public void onSlide(@NonNull View bottomSheet, final float slideOffset) { //這裡是整個拖動過程 mSlideOffset = slideOffset; //控制箭頭套件的狀態而已 new Handler().postDelayed(new Runnable() { @Override public void run() { float dis = (mSlideOffset - slideOffset) * 10; if (dis > 1) { dis = 1; } else if (dis < -1) { dis = -1; } if (mBottomSheetBehavior.getState() == BottomSheetBehavior.STATE_DRAGGING) { mExpandIconView.setFraction(.5f + dis * .5f, false); } } }, 150); } }); //設定拖拉畫面收起時的突出大小 //這邊將dp轉換為px mBottomSheetBehavior.setPeekHeight((int) convertDpToPixel(70, this)); //設定拖拉視窗的狀態 (STATE_COLLAPSED = 縮小, STATE_EXPANDED = 展開) mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); } //dp轉px public float convertDpToPixel(float dp, Context context) { return dp * (getDisplayMetrics(context).densityDpi / 160f); } public DisplayMetrics getDisplayMetrics(Context context) { Resources resources = context.getResources(); return resources.getDisplayMetrics(); } }
這邊可以來做一些修改,讓他更貼近實際使用。
-
設計圓角,讓畫面更好看
在res資料夾筆下新增drawable資料夾,裡面新增一個xml,例:drawable_round_edge.xml
在檔案中新增一個<shape>
,設定背景顏色與圓角大小,如下
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <!--填充設定--> <solid android:color="#ff333333"/> <!--圓角設定--> <corners android:topLeftRadius="20dp" android:topRightRadius="20dp"/> </shape>
在專案的bottom_sheet
layout中,也就是你的拖拉畫面佈局中,在最頂層View設定背景為drawable_round_edge.xml
-
限制展開大小
在預設的設計中,展開拖拉畫面布局時,會蓋住整個畫面,就像下圖一樣。
大部分會希望能看到部分背景,所以我們要限制拖拉畫面的高度,讓他可以看見部分背景佈局,如下圖。
增加程式碼功能:
首先增加一個計算畫面高度的功能:
public float convertPercentageToPixel(float percentage, Context context) { return getDisplayMetrics(context).heightPixels * percentage; }
這邊會抓取app畫面的高度,然後再乘以input進來的percentage比例,結果就是我們想要顯示的比例高度(上圖範例為占用70%)
然後在findViews()
中增加拖拉布局的頂層畫面物件:
private void findViews() { mBottomSheet = findViewById(R.id.bottom_sheet); mExpandIconView = (ExpandIconView) mBottomSheet.findViewById(R.id.expandIconView); //---加入此行--- mbottom_sheet = (FrameLayout) mBottomSheet.findViewById(R.id.bottom_sheet); }
接下來在setUpViews()
中設定mbottom_sheet
布局的高度:
private void setUpViews() { //---加入這區--- //取得View的參數 ViewGroup.LayoutParams params = mbottom_sheet.getLayoutParams(); //設定View的高度,按比例計算 params.height = (int)convertPercentageToPixel(0.7f, this); //設定View的參數 mbottom_sheet.setLayoutParams(params); //---加入這區--- mExpandIconView.setState(ExpandIconView.LESS, true); mBottomSheetBehavior = BottomSheetBehavior.from(mBottomSheet); mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { @Override public void onStateChanged(@NonNull View bottomSheet, int newState) { if (newState == BottomSheetBehavior.STATE_COLLAPSED) { mExpandIconView.setState(ExpandIconView.LESS, true); } else if (newState == BottomSheetBehavior.STATE_EXPANDED) { mExpandIconView.setState(ExpandIconView.MORE, true); } ... ...
這樣在拖拉佈局產生之後,就會按畫面高度比例去設定拖拉布局的最大高度了!
-END-
發佈留言