Android开发,实现底部弹出菜单
文章目录
- 1. 实现分析
- 1. 继承 Dialog 并实现点击监听
- 2. 视图初始化
- 3. 窗口设置
- 4. 点击处理
- 5. 触摸外部关闭
- 2. 代码实现过程
- 3. 如何使用?
- 4. 效果图演示
1. 实现分析
1. 继承 Dialog 并实现点击监听
- 继承 Dialog 类并实现
View.OnClickListener
- 使用自定义样式
R.style.option_dialog
2. 视图初始化
- 在构造函数中加载布局
R.layout.dialog_from_custom
- 初始化按钮视图并设置点击监听
3. 窗口设置
- 在
onCreate
中设置对话框显示在底部 - 设置对话框宽度为屏幕宽度
4. 点击处理
- 处理三个按钮的点击事件
- 通过回调接口
OnDialogClickListener
通知外部点击事件
5. 触摸外部关闭
- 设置窗口装饰视图的触摸监听,点击外部时关闭对话框
2. 代码实现过程
- 写一个
DownDialog
extendsDialog
public class DownDialog extends Dialog implements View.OnClickListener {private TextView btn_take_photo, btn_select_photo, btn_cancel;//构造方法里面设置主题 R.style.option_dialogpublic DownDialog(Context context) {this(context, R.style.option_dialog);}public DownDialog(Context context, int themeResId) {super(context, themeResId);//加载布局文件View view = LayoutInflater.from(context).inflate(R.layout.dialog_from_custom, null);initView(view);initListener();setContentView(view);getWindow().getDecorView().setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {dismiss();return true;}});}private void initListener() {btn_cancel.setOnClickListener(this);btn_take_photo.setOnClickListener(this);btn_select_photo.setOnClickListener(this);}private void initView(View view) {btn_take_photo = view.findViewById(R.id.btn_take_photo);btn_select_photo = view.findViewById(R.id.btn_select_photo);btn_cancel = view.findViewById(R.id.btn_cancel);}@SuppressWarnings("deprecation")@Overrideprotected void onCreate(Bundle bundle) {super.onCreate(bundle);getWindow().setGravity(Gravity.BOTTOM);WindowManager m = getWindow().getWindowManager();Display d = m.getDefaultDisplay();WindowManager.LayoutParams p = getWindow().getAttributes();p.width = d.getWidth();getWindow().setAttributes(p);}@Overridepublic void onClick(View v) {if (v.getId() == R.id.btn_take_photo) {if (onDialogClickListener != null) {onDialogClickListener.onDialogClick("拍照", 1);}} else if (v.getId() == R.id.btn_select_photo) {if (onDialogClickListener != null) {onDialogClickListener.onDialogClick("相册", 2);}} else {if (onDialogClickListener != null) {onDialogClickListener.onDialogClick("取消", 3);}}dismiss();}//回调public interface OnDialogClickListener {void onDialogClick(String msg, int type);}private OnDialogClickListener onDialogClickListener;public void setOnDialogClickListener(OnDialogClickListener onDialogClickListener) {this.onDialogClickListener = onDialogClickListener;}}
- 在res/values/themes.xml 定义 样式主题
option_dialog
<style name="option_dialog" parent="@style/dialog_common"><item name="android:windowAnimationStyle">@style/AnimBottom</item><item name="android:windowBackground">@color/me_background_color</item></style><style name="dialog_common" parent="Base.AlertDialog.AppCompat.Light"><item name="android:windowBackground">@color/me_background_color</item></style><style name="AnimBottom" parent="@android:style/Animation"><item name="android:windowEnterAnimation">@anim/push_bottom_in</item><item name="android:windowExitAnimation">@anim/push_bottom_out</item></style>
- 在res/values/colors.xml中 定义
me_background_color
颜色
<color name="base_start_color_gray">#e8e9eb</color><color name="me_background_color">#b0000000</color><color name="base_start_color_pressed">#fffcfcfc</color><color name="base_end_color_pressed">#ffd7d7d7</color><color name="base_start_color_default">#FFFFFF</color><color name="base_end_color_default">#FFFFFF</color>
- 在res/anim 中定义
push_bottom_in
和push_bottom_out
动画 (如果没有anim ,先创建)
push_bottom_in.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- 上下滑入式 -->
<set xmlns:android="http://schemas.android.com/apk/res/android" ><translateandroid:duration="200"android:fromYDelta="50%p"android:toYDelta="0" /></set>
push_bottom_out.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- 上下滑入式 -->
<set xmlns:android="http://schemas.android.com/apk/res/android" ><translateandroid:duration="200"android:fromYDelta="0"android:toYDelta="50%p" /></set>
dialog_from_custom.xml
布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/pop_layout"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center_horizontal"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_marginLeft="15dp"android:layout_marginRight="15dp"android:gravity="center_horizontal"android:orientation="vertical"><TextViewandroid:id="@+id/btn_take_photo"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:gravity="center"android:background="@drawable/background_view_rounded_top"android:paddingBottom="8dp"android:paddingTop="8dp"android:text="拍照"android:textColor="#282828"android:textSize="16sp" /><Viewandroid:layout_width="match_parent"android:layout_height="1dp"android:background="#dddddd" /><TextViewandroid:id="@+id/btn_select_photo"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@drawable/background_view_rounded_bottom"android:paddingBottom="8dp"android:paddingTop="8dp"android:text="相册选取"android:gravity="center"android:textColor="#282828"android:textSize="16sp" /><TextViewandroid:id="@+id/btn_cancel"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_marginBottom="10dip"android:layout_marginTop="8dip"android:background="@drawable/rect_gray"android:paddingBottom="8dp"android:gravity="center"android:paddingTop="8dp"android:text="取消"android:textColor="#282828"android:textSize="16sp" /></LinearLayout>
</RelativeLayout>
- 在res/drawable下分别创建
background_view_rounded_top.xml
,background_view_rounded_bottom.xml
,rect_gray.xml
background_view_rounded_top.xml
<?xml version="1.0" encoding="UTF-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"android:insetLeft="1.0px"android:insetRight="1.0px"><selector><item android:state_pressed="true"><shape><gradientandroid:angle="270.0"android:endColor="@color/base_end_color_pressed"android:startColor="@color/base_start_color_pressed" /><cornersandroid:topLeftRadius="6dp"android:topRightRadius="6dp" /></shape></item><item><shape><gradientandroid:angle="270.0"android:endColor="@color/base_end_color_default"android:startColor="@color/base_start_color_default" /><cornersandroid:topLeftRadius="6dip"android:topRightRadius="6dip" /></shape></item></selector></inset>
background_view_rounded_bottom.xml
<?xml version="1.0" encoding="UTF-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"android:insetLeft="1.0px"android:insetRight="1.0px"><selector><item android:state_pressed="true"><shape><gradientandroid:angle="270.0"android:endColor="@color/base_end_color_pressed"android:startColor="@color/base_start_color_pressed" /><cornersandroid:bottomLeftRadius="6dip"android:bottomRightRadius="6dip"/></shape></item><item><shape><gradientandroid:angle="270.0"android:endColor="@color/base_end_color_default"android:startColor="@color/base_start_color_default" /><cornersandroid:bottomLeftRadius="6dip"android:bottomRightRadius="6dip"/></shape></item></selector>
</inset>
rect_gray.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle"><!-- 填充颜色 --><solid android:color="#FFFFFF"/><!-- 线的宽度,颜色灰色 --><!--<stroke--><!--android:width="1dp"--><!--android:color="#fffcfcfc"/>--><!-- 矩形的圆角半径 --><corners android:radius="6dp" />
</shape>
3. 如何使用?
DownDialog downDialog = new DownDialog(MainActivity.this);
downDialog.setOnDialogClickListener(new DownDialog.OnDialogClickListener() {@Overridepublic void onDialogClick(String msg, int type) {switch (type) {case 1: // 拍照Toast.makeText(MainActivity.this, "点击了拍照", Toast.LENGTH_SHORT).show();break;case 2: // 相册Toast.makeText(MainActivity.this, "点击了相册", Toast.LENGTH_SHORT).show();break;case 3: // 取消Toast.makeText(MainActivity.this, "点击了取消", Toast.LENGTH_SHORT).show();break;}}
});
downDialog.show();