BottomPopUpDialog底部彈出框的實現(xiàn)
這是一個之前實現(xiàn)的簡單效果,類似于ios底部彈出框,所以想寫一篇博客記錄一下寺谤。
效果如圖:
使用 DialogFragment
當我要實現(xiàn)這個效果的時候隙畜,首先想到的是 DialogFragment ,因為可以使用其生命周期來管理各種事件的處理,以及通過 onCreateView 或者 onCreateDIalog 來自定義視圖东揣,方便需求的變化和功能的擴展践惑。
如果不了解 DialogFragment 的話,可以去看看相關(guān)資料嘶卧,這里不做詳述哈尔觉。
我們來看看底部彈出框的布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/transparent"
android:gravity="bottom">
<com.shadow.bottompopupdialog.MaxHeightScrollView
android:id="@+id/sl_root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="@drawable/round_rect_white"
android:padding="2dp">
<LinearLayout
android:id="@+id/pop_dialog_content_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/round_rect_white"
android:orientation="vertical">
</LinearLayout>
</com.shadow.bottompopupdialog.MaxHeightScrollView>
<TextView
android:id="@+id/cancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/sl_root"
android:layout_marginBottom="5dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="5dp"
android:background="@drawable/round_rect_white"
android:gravity="center"
android:minHeight="55dp"
android:padding="10dp"
android:text="@string/cancel"
android:textColor="@color/text_color"
android:textSize="18sp" />
</RelativeLayout>
如代碼所示,主要布局是 ScrollView 里面嵌套一個 LinearLayout 布局芥吟,用來在代碼里添加item侦铜。
別忘了這個自定義 MaxHeightScrollView
上面的布局中我使用的是 MaxHeightScrollView ,自定義 ScrollView 是想要顯示最高的高度為屏幕的三分之二钟鸵。
public class MaxHeightScrollView extends ScrollView {
public MaxHeightScrollView(Context context) {
super(context);
}
public MaxHeightScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Context context = getContext();
if (null != context) {
int screenHeight = getScreenHeight(context);
heightMeasureSpec = MeasureSpec.makeMeasureSpec(screenHeight * 2 / 3, MeasureSpec.AT_MOST);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
/**
* 獲取屏幕高度
*/
private int getScreenHeight(Context context) {
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
return metrics.heightPixels;
}
}
BottomPopUpDialog 詳情
先來看看一些view的細節(jié)
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//該方法需要放在onViewCreated比較合適, 若在 onStart 在部分機型會出現(xiàn)閃爍的情況
getDialog().getWindow().setBackgroundDrawableResource(mBackgroundShadowColor);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//去掉title
setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Holo_Light_NoActionBar);
}
如代碼所示钉稍,在 onViewCreated 里設(shè)置彈窗的背景陰影顏色,默認是黑色透明的顏色棺耍。
mBackgroundShadowColor = R.color.transparent_70
而且可以在代碼中設(shè)置它的顏色贡未。
/**
* 設(shè)置dialog背景陰影顏色
*/
public BottomPopUpDialog setBackgroundShadowColor(int color) {
mBackgroundShadowColor = color;
return this;
}
setStyle是為了去掉title,當然也可以使用
getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE)
可調(diào)用的公共方法
/**
* 設(shè)置item數(shù)據(jù)
*/
public BottomPopUpDialog setDialogData(String[] dataArray) {
mDataArray = dataArray;
return this;
}
/**
* 設(shè)置監(jiān)聽item監(jiān)聽器
*/
public BottomPopUpDialog setItemOnListener(BottomPopDialogOnClickListener listener) {
mListener = listener;
return this;
}
/**
* 設(shè)置字體顏色
*
* @param index item的索引
* @param color res color
*/
public BottomPopUpDialog setItemTextColor(int index, int color) {
mColorArray.put(index, color);
return this;
}
/**
* 設(shè)置item分隔線顏色
*/
public BottomPopUpDialog setItemLineColor(int color) {
mLineColor = color;
return this;
}
/**
* 設(shè)置是否點擊回調(diào)取消dialog
*/
public BottomPopUpDialog setCallBackDismiss(boolean dismiss) {
mIsCallBackDismiss = dismiss;
return this;
}
設(shè)置相應(yīng)的數(shù)據(jù)后會在 onCreateView 里初始化數(shù)據(jù)蒙袍,這些公共方法是必須要在dialogfragment.show() 之前調(diào)用俊卤,因為只有在show方法調(diào)用之后,dialogfragment 才會初始化害幅,開始相應(yīng)的生命周期消恍。
初始化數(shù)據(jù)
private void initItemView() {
//循環(huán)添加item
for (int i = 0; i < mDataArray.length; i++) {
final PopupDialogItem dialogItem = new PopupDialogItem(getContext());
dialogItem.refreshData(mDataArray[i]);
//最后一項隱藏分割線
if (i == mDataArray.length - 1) {
dialogItem.hideLine();
}
//設(shè)置字體顏色
if (mColorArray.size() != 0 && mColorArray.get(i) != 0) {
dialogItem.setTextColor(mColorArray.get(i));
}
if (mLineColor != 0) {
dialogItem.setLineColor(mLineColor);
}
mContentLayout.addView(dialogItem);
dialogItem.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mListener.onDialogClick(dialogItem.getItemContent());
if (mIsCallBackDismiss) dismiss();
}
});
}
}
可以從代碼中看到 LinearLayout 里循環(huán)添加的 item 是 PopupDialogItem ,它其實主體就是一個 TextView 矫限,負責(zé)顯示
String數(shù)組里的內(nèi)容哺哼。
BottomPopUpDialog 使用
BottomPopUpDialog dialog = new BottomPopUpDialog()
.setDialogData(getResources().getStringArray(R.array.popup_array))
.setItemTextColor(2, R.color.colorAccent)
.setItemTextColor(4, R.color.colorAccent)
.setCallBackDismiss(true)
.setItemOnListener(new BottomPopUpDialog.BottomPopDialogOnClickListener() {
@Override
public void onDialogClick(String tag) {
Snackbar.make(view, tag, Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
dialog.show(getSupportFragmentManager(), "tag");
這些方法之前介紹過,setItemTextColor 可以重復(fù)設(shè)置顏色叼风。
最后
這是一個簡單的小組件取董,記錄一下編程的思路。
點擊這里有源碼 GitHub地址