底部弹出dialog_dialog底部弹出 - CSDN
精华内容
参与话题
  • Dialog实现底部弹窗

    千次阅读 2017-06-27 17:22:15
    有时要实现各种各样的弹窗,譬如选择支付方式的时候,很多APP就会选择由底部弹上来的。如图:下面是Dialog的实现:public class ChoosePayStatusDialog extends Dialog { private LinearLayout aliPayLly; private ...

    有时要实现各种各样的弹窗,譬如选择支付方式的时候,很多APP就会选择由底部弹上来的。如图:

    这里写图片描述

    下面是Dialog的实现:

    public class ChoosePayStatusDialog extends Dialog {
    
        private LinearLayout aliPayLly;
        private LinearLayout weixinPayLly;
    
        public ChoosePayStatusDialog(@NonNull Context context) {
            super(context, R.style.BottomDialog);//关键代码
            setContentView(R.layout.dialog_choose_pay);//关键代码
            setCancelable(true);//关键代码
            setCanceledOnTouchOutside(true);//关键代码
            getWindow().setGravity(Gravity.BOTTOM);//关键代码
            getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT);
    
            aliPayLly= (LinearLayout) findViewById(R.id.aliPayLly);
            weixinPayLly= (LinearLayout) findViewById(R.id.weixinPayLly);
            aliPayLly.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    EventBus.getDefault().post(new ChoosePayBean(2));
                    dismiss();
    
                }
            });
    
            weixinPayLly.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    EventBus.getDefault().post(new ChoosePayBean(1));
                    dismiss();
                }
            });
    
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            /* 触摸外部弹窗 */
            if (isOutOfBounds(getContext(), event)) {
                EventBus.getDefault().post(new ChoosePayBean());
                dismiss();
            }
            return super.onTouchEvent(event);
        }
    
    
        private boolean isOutOfBounds(Context context, MotionEvent event) {
            final int x = (int) event.getX();
            final int y = (int) event.getY();
            final int slop = ViewConfiguration.get(context).getScaledWindowTouchSlop();
            final View decorView = getWindow().getDecorView();
            return (x < -slop) || (y < -slop) || (x > (decorView.getWidth() + slop))
                    || (y > (decorView.getHeight() + slop));
        }
    }
    

    以上代码中:

    getWindow().setGravity(Gravity.BOTTOM);

    设置对话框的位置,这里设置成底部,也可以设置成Gravity.CENTER,根据需求而定。

    super(context, R.style.BottomDialog);

    BottomDialog样式文件代码如下:

    <style name="BottomDialog">
            <item name="android:windowIsTranslucent">true</item>
            <item name="android:windowBackground">@android:color/transparent</item>
            <item name="android:windowContentOverlay">@null</item>
            <item name="android:windowNoTitle">true</item>
            <item name="android:backgroundDimEnabled">true</item>
            <item name="android:windowIsFloating">false</item>
            <item name="android:windowAnimationStyle">@style/DialogAnimation</item>
            <item name="android:gravity">bottom</item>
        </style>

    @style/DialogAnimation中是定义对话框出现与消失的动画,文件内容如下:

    <style name="DialogAnimation">
            <item name="android:windowEnterAnimation">@anim/slide_up</item>
            <item name="android:windowExitAnimation">@anim/slide_down</item>
        </style>

    @anim/slide_up内容如下:

    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:fillAfter="true"
        android:fillBefore="true"
        android:fillEnabled="true"
        android:interpolator="@anim/anim_interpolator"
        android:shareInterpolator="true"
        android:zAdjustment="top">
        <translate
            android:duration="500"
            android:fromYDelta="100%p"
            android:toYDelta="0%p" />
    </set>

    @anim/slide_down内容如下:

    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:interpolator="@android:anim/decelerate_interpolator"
        android:shareInterpolator="true">
        <translate
            android:duration="500"
            android:fromYDelta="0.0%p"
            android:toYDelta="100.0%p" />
    </set>

    重写onTouchEvent方法和isOutOfBounds是为了监听点击对话框阴影部分,可以根据实际需求来定,关于这部分的博客地址为:《关于给Dialog设置setCanceledOnTouchOutside(true)后如何监听Dialog消失》

    展开全文
  • 1.dialog的弹入弹出有动画效果 2.能控制dialog弹出的最大高度 好,目标明确,开撸 自定义BottomDialog package com.example.zhoumohan.luckymorning.common.widget; import android.app.Dialog; impor...

    先上下效果图:

    简单实现了一个在项目中比较常用的效果,主要实现有两点:

    1.dialog的弹入弹出有动画效果

    2.能控制dialog弹出的最大高度

    好,目标明确,开撸

    自定义BottomDialog

    package com.example.zhoumohan.luckymorning.common.widget;
    
    import android.app.Dialog;
    import android.content.Context;
    import android.os.Bundle;
    import android.support.annotation.NonNull;
    import android.view.Gravity;
    import android.view.View;
    import android.view.Window;
    import android.view.WindowManager;
    import android.widget.FrameLayout;
    import android.widget.LinearLayout;
    import android.widget.ListView;
    import android.widget.TextView;
    
    import com.example.zhoumohan.luckymorning.R;
    import com.example.zhoumohan.luckymorning.demo.CouponAdapter;
    import com.example.zhoumohan.luckymorning.util.DisplayUtil;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class BottomDialog extends Dialog {
        private LinearLayout llContent;
        private TextView tvClose;
        private ListView lvCoupon;
        private CouponAdapter adapter;
    
        public BottomDialog(@NonNull Context context) {
            super(context);
        }
    
        public BottomDialog(@NonNull Context context, int themeResId) {
            super(context, themeResId);
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.bottom_dialog);
            Window window = this.getWindow();
            //设置位置在屏幕底部
            window.setGravity(Gravity.BOTTOM);
            //设置弹入弹出动画
            window.setWindowAnimations(R.style.BottomDialog_Animation);
            //设置为全屏dialog
            WindowManager.LayoutParams params = window.getAttributes();
            params.width = WindowManager.LayoutParams.MATCH_PARENT;
            params.height = WindowManager.LayoutParams.WRAP_CONTENT;
            window.setAttributes(params);
    
            initView();
        }
    
        private void initView() {
            llContent = findViewById(R.id.ll_content);
            tvClose = findViewById(R.id.tv_close);
            lvCoupon = findViewById(R.id.lv_coupon);
    
    
            List<String> list = new ArrayList<>();
            for (int i = 0; i < 15; i++) {
                list.add("标题" + i);
            }
    
            adapter = new CouponAdapter(getContext(),list);
            lvCoupon.setAdapter(adapter);
    
            tvClose.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    hide();
                }
            });
    
            //重要一步,通过此方法来得知dialog的布局内容的真实高度
    
            llContent.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
                @Override
                public void onLayoutChange(View view, int left, int top, int light, int bottom, int oldLeft, int oldTop, int oldLight, int oldBottom) {
                    //这个view就是llContent
                    int height = view.getHeight();
                    //这个是要设置的最大高度,我设置为屏幕高度的一半
                    int needHeight = DisplayUtil.getRealScreenRelatedInformation(getContext())[1]/2;
    
                    if (height > needHeight) {
                        //注意:这里的 LayoutParams 必须是 FrameLayout的!!
                        view.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, needHeight));
                    }
                }
            });
        }
    
    
    }
    

    接下来我们看下弹入弹出动画是怎么设置的

     <!--从底部进入退出动画-->
        <style name="BottomDialog.Animation" parent="Animation.AppCompat.Dialog">
            //弹入动画
            <item name="android:windowEnterAnimation">@anim/dialog_in_anim</item>
            //弹出动画
            <item name="android:windowExitAnimation">@anim/dialog_out_anim</item>
        </style>

    具体动画效果则是通过xml文件定义的,在res目录下创建anim文件夹,并创建以下两个文件

    dialog_in_anim.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate xmlns:android="http://schemas.android.com/apk/res/android"
            android:duration="300"
            android:fromYDelta="100%"
            android:toYDelta="0" />
    </set>

    dialog_out_anim.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate xmlns:android="http://schemas.android.com/apk/res/android"
            android:duration="300"
            android:fromYDelta="0"
            android:toYDelta="100%" />
    </set>

    其中DisplayUtil是获取屏幕宽高的工具类,这个是我在网上找的,大家可以换成自己的

    package com.example.zhoumohan.luckymorning.util;
    
    import android.content.Context;
    import android.util.DisplayMetrics;
    import android.util.Log;
    import android.view.WindowManager;
    
    public class DisplayUtil {
        /**
         * 在有虚拟按键的设备中,获取屏幕的宽高是由区别的。这个获得不包括虚拟按键的屏幕。
         * @param context
         * @return
         */
        public static int [] getScreenRelatedInformation(Context context) {
            WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            if (windowManager != null) {
                DisplayMetrics outMetrics = new DisplayMetrics();
                windowManager.getDefaultDisplay().getMetrics(outMetrics);
                int widthPixels = outMetrics.widthPixels;
                int heightPixels = outMetrics.heightPixels;
                int densityDpi = outMetrics.densityDpi;
                float density = outMetrics.density;
                float scaledDensity = outMetrics.scaledDensity;
                //可用显示大小的绝对宽度(以像素为单位)。
                //可用显示大小的绝对高度(以像素为单位)。
                //屏幕密度表示为每英寸点数。
                //显示器的逻辑密度。
                //显示屏上显示的字体缩放系数。
                Log.d("display", "widthPixels = " + widthPixels + ",heightPixels = " + heightPixels + "\n" +
                        ",densityDpi = " + densityDpi + "\n" +
                        ",density = " + density + ",scaledDensity = " + scaledDensity);
                return new int[]{widthPixels,heightPixels};
            }
            return null;
        }
    
        /**
         * 在有虚拟按键的设备中,获取屏幕的宽高是由区别的。这个获得包括虚拟按键的屏幕。
         * @param context
         * @return
         */
        public static int[] getRealScreenRelatedInformation(Context context) {
            WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            if (windowManager != null) {
                DisplayMetrics outMetrics = new DisplayMetrics();
                windowManager.getDefaultDisplay().getRealMetrics(outMetrics);
                int widthPixels = outMetrics.widthPixels;
                int heightPixels = outMetrics.heightPixels;
                int densityDpi = outMetrics.densityDpi;
                float density = outMetrics.density;
                float scaledDensity = outMetrics.scaledDensity;
                //可用显示大小的绝对宽度(以像素为单位)。
                //可用显示大小的绝对高度(以像素为单位)。
                //屏幕密度表示为每英寸点数。
                //显示器的逻辑密度。
                //显示屏上显示的字体缩放系数。
                Log.d("display", "widthPixels = " + widthPixels + ",heightPixels = " + heightPixels + "\n" +
                        ",densityDpi = " + densityDpi + "\n" +
                        ",density = " + density + ",scaledDensity = " + scaledDensity);
                return new int[]{widthPixels,heightPixels};
            }
            return null;
        }
    }
    

    最后贴一下dialog的布局文件

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/ll_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:maxHeight="600dp"
        android:background="@android:color/white">
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="60dp">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:text="可用消费卷" />
            <TextView
                android:id="@+id/tv_close"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true"
                android:layout_marginRight="16dp"
                android:text="关闭" />
        </RelativeLayout>
        <ListView
            android:id="@+id/lv_coupon"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </LinearLayout>

    在需要的地方调用即可

     BottomDialog dialog = new BottomDialog(getContext(),R.style.BottomDialog);
                    dialog.show();

    R.style.BottomDialog,大家可以设置自己所需的样式

     <style name="BottomDialog" parent="@android:style/Theme.Holo.Dialog">
            <!--是否有边框-->
            <item name="android:windowFrame">@null</item>
            <!--是否悬浮在Activity上-->
            <item name="android:windowIsFloating">true</item>
            <!--无标题-->
            <item name="android:windowNoTitle">true</item>
            <item name="android:windowFullscreen">true</item>
            <item name="android:windowBackground">@android:color/transparent</item>
        </style>
    

    其中的listview相关内容就不给大家展示了,到此大功告成

    展开全文
  • Android自定义底部弹出窗-dialog 上线项目功能抽取,在项目开发中,我们会在许多地方会用到底部自定义弹窗,比如设置:个人账户退出,切换,照片的拍照或者相册的调出,或者一些底部弹出列表,本文对自定义底部弹出窗-...

    Android自定义底部弹出窗-dialog(2种实现分析+源码)

    上线项目功能抽取,在项目开发中,我们会在许多地方会用到底部自定义弹窗,比如设置:个人账户退出,切换,照片的拍照或者相册的调出,或者一些底部弹出列表,本文对自定义底部弹出窗-dialog,做个开发记录,希望对读者有所帮助.

    本文实现的抽取的代码实例:安卓两种底部弹出窗dialog实现方式,一种是列表弹窗实现,2是灵活底部弹窗,传入布局以及控件id

    实现方式一:
    实现一

    实现方式二:

    实现方式二

    一 MainActivity代码

    两种dialog实现方式的调用

    package com.kx.kxbottomdialog;
    
    import android.content.Context;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.AdapterView;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    
        private Context mContext;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            init();
        }
    
        private void init() {
            mContext = this;
            findViewById(R.id.bt1).setOnClickListener(this);
            findViewById(R.id.bt2).setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.bt1:
                    bt1ListView();
                    break;
                case R.id.bt2://退出登录
                    Bt2Loginout();
                    break;
            }
        }
    
        /**
         * 底部列表弹窗
         */
        private void bt1ListView() {
            List<String> names = new ArrayList<>();
            names.add("随堂测验");
            names.add("单元考试");
            names.add("期中(末)考试");
            showDialog(new BottomCirTraDialog.SelectDialogListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    switch (position) {
                        case 0: //随堂测验
                            showToast("随堂测验");
                            break;
                        case 1://单元考试
                            showToast("单元考试");
                            break;
                        case 2://期中(末)考试
                            showToast("期中(末)考试");
                            break;
                        default:
                            break;
                    }
    
                }
            }, names);
        }
    
        private BottomCirTraDialog showDialog(BottomCirTraDialog.SelectDialogListener listener, List<String> names) {
            BottomCirTraDialog dialog = new BottomCirTraDialog(this, R.style.transparentFrameWindowStyle, listener, names);
            if (!this.isFinishing()) {
                dialog.show();
            }
            return dialog;
        }
    
        /**
         * 退出登录
         * 传入布局实现
         */
        private void Bt2Loginout() {
            BottomDialog dialog = new BottomDialog(mContext, R.layout.dialog_login_out,
                    new int[]{R.id.tv_choice_out, R.id.tv_cancel});
            dialog.show();
            dialog.setOnBottomItemClickListener(new BottomDialog.OnBottomItemClickListener() {
                @Override
                public void onBottomItemClick(BottomDialog dialog, View view) {
                    switch (view.getId()) {
                        case R.id.tv_choice_out:   //退出登录
                            //服务器登出  mCenterPI.logout();
                            dialog.cancel();
                            break;
                        case R.id.tv_cancel:  //取消
                            dialog.cancel();
                            break;
                    }
                }
            });
        }
    
    
        /**
         * Toast
         *
         * @param s
         */
        public void showToast(String s) {
            ToastUtil.toast(this, s);
        }
    }
    
    

    二 页面XML布局

    简单的两个按钮控件

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.kx.kxbottomdialog.MainActivity">
    
        <TextView
            android:padding="10dp"
            android:textColor="#000"
            android:gravity="center_horizontal"
            android:text="自定义底部弹窗"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    
        <Button
            android:text="列表弹窗"
            android:id="@+id/bt1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    
        <Button
            android:text="传入布局"
            android:id="@+id/bt2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    
    
    </LinearLayout>
    
    

    三 列表弹窗详细代码自定义控件

    package com.kx.kxbottomdialog;
    
    import android.app.Activity;
    import android.app.Dialog;
    import android.content.Context;
    import android.os.Bundle;
    import android.support.annotation.NonNull;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.Window;
    import android.view.WindowManager;
    import android.widget.AdapterView;
    import android.widget.BaseAdapter;
    import android.widget.Button;
    import android.widget.ListView;
    import android.widget.TextView;
    
    import java.util.List;
    
    /**
     * @ 创建:   kx
     * @ 时间:    2018/10/22
     * @ 描述:
     */
    
    public class BottomCirTraDialog extends Dialog implements AdapterView.OnItemClickListener {
    
        private List<String> mList;
        private SelectDialogListener mListener;
        private Activity mActivity;
        private boolean mUseCustomColor = false;
        private int mFirstItemColor;
        private int mOtherItemColor;
        private Button mBtnCancel;
    
        public BottomCirTraDialog(@NonNull Context context) {
            super(context);
        }
    
        public BottomCirTraDialog(Activity activity, int theme, SelectDialogListener listener, List<String> names) {
            super(activity, theme);
            mActivity = activity;
            mListener = listener;
            mList = names;
            //点击Dialog外部消失
            setCanceledOnTouchOutside(true);
        }
    
    
        public interface SelectDialogListener {
            void onItemClick(AdapterView<?> parent, View view, int position, long id);
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            View view = getLayoutInflater().inflate(R.layout.dialog_exam_type, null);
            setContentView(view, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            Window window = getWindow();
    
            //设置动画
            window.setWindowAnimations(R.style.main_menu_animstyle);
            WindowManager.LayoutParams attributes = window.getAttributes();
            attributes.x = 0;
            attributes.y = mActivity.getWindowManager().getDefaultDisplay().getHeight();
    
            //保证按钮水平满屏
            attributes.width = ViewGroup.LayoutParams.MATCH_PARENT;
            attributes.height = ViewGroup.LayoutParams.WRAP_CONTENT;
    
            //设置显示位置
            onWindowAttributesChanged(attributes);
    
            initView();
        }
    
        private void initView() {
            DialogAdapter dialogAdapter = new DialogAdapter(mList);
            ListView listView = findViewById(R.id.dialog_list);
            mBtnCancel = (Button) findViewById(R.id.btn_cancel);
            listView.setOnItemClickListener(this);
            listView.setAdapter(dialogAdapter);
            mBtnCancel.setOnClickListener(new View.OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    if(mCancelListener != null){
                        mCancelListener.onCancelClick(v);
                    }
                    dismiss();
                }
            });
        }
    
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            mListener.onItemClick(parent, view, position, id);
            dismiss();
        }
    
    
        private class DialogAdapter extends BaseAdapter {
            private List<String> mStrings;
            private Viewholder viewholder;
            private LayoutInflater layoutInflater;
    
            public DialogAdapter(List<String> strings) {
                this.mStrings = strings;
                this.layoutInflater = mActivity.getLayoutInflater();
            }
    
            @Override
            public int getCount() {
                return mStrings.size();
            }
    
            @Override
            public Object getItem(int position) {
                return mStrings.get(position);
            }
    
            @Override
            public long getItemId(int position) {
                return position;
            }
    
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                if (null == convertView) {
                    viewholder = new Viewholder();
                    convertView = layoutInflater.inflate(R.layout.view_dialog_item, null);
                    viewholder.dialogItemButton = (TextView) convertView.findViewById(R.id.dialog_item_bt);
                    convertView.setTag(viewholder);
                } else {
                    viewholder = (Viewholder) convertView.getTag();
                }
                viewholder.dialogItemButton.setText(mStrings.get(position));
                if (!mUseCustomColor) {
                    mFirstItemColor = mActivity.getResources().getColor(R.color.color_0073FF);
                    mOtherItemColor = mActivity.getResources().getColor(R.color.color_0073FF);
                }
    
                //根据数量 设置圆角  数量为1,其他上下,剩余中
                if (1 == mStrings.size()) {
                    viewholder.dialogItemButton.setTextColor(mFirstItemColor);
                    viewholder.dialogItemButton.setBackgroundResource(R.drawable.dialog_item_bg_only);
                } else if (position == 0) {
                    viewholder.dialogItemButton.setTextColor(mFirstItemColor);
                    viewholder.dialogItemButton.setBackgroundResource(R.drawable.select_dialog_item_bg_top);
                } else if (position == mStrings.size() - 1) {
                    viewholder.dialogItemButton.setTextColor(mOtherItemColor);
                    viewholder.dialogItemButton.setBackgroundResource(R.drawable.select_dialog_item_bg_buttom);
                } else {
                    viewholder.dialogItemButton.setTextColor(mOtherItemColor);
                    viewholder.dialogItemButton.setBackgroundResource(R.drawable.select_dialog_item_bg_center);
                }
                return convertView;
            }
    
        }
    
        public static class Viewholder {
            public TextView dialogItemButton;
        }
    
    
        /**
         * 取消事件监听接口
         *
         */
        private SelectDialogCancelListener mCancelListener;
    
        public interface SelectDialogCancelListener {
            void onCancelClick(View v);
        }
    }
    
    

    四 传入布局自定义弹窗

    package com.kx.kxbottomdialog;
    
    import android.app.Dialog;
    import android.content.Context;
    import android.os.Bundle;
    import android.view.Gravity;
    import android.view.View;
    import android.view.Window;
    import android.view.WindowManager;
    
    
    /**
     * @ 创建:   kx
     * @ 时间:    2018/10/22
     * @ 描述:
     */
    
    public class BottomDialog extends Dialog implements View.OnClickListener {
        private Context context;
        private int layoutRes;
        private View view;
        private int[] clickIds;   //需要设置点击事件的ID.需要其他ID,在dialog实例化后在dialog上fbc.
    
        public BottomDialog(Context context, int layoutRes, int[] clickIds) {
            super(context, R.style.dialog_full);    //设置主题
            this.context = context;
            this.layoutRes = layoutRes;
            this.clickIds = clickIds;
        }
    
        public BottomDialog(Context context, View view, int[] clickIds) {
            super(context, R.style.dialog_full);    //设置主题
            this.context = context;
            this.view = view;
            this.clickIds = clickIds;
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Window window = getWindow();
            //底部弹出的Dialog
            window.setGravity(Gravity.BOTTOM);
            //底部弹出的动画
            window.setWindowAnimations(R.style.DialogBottomAnimation);
            if(view != null) {
                setContentView(view);
            }else{
                setContentView(layoutRes);
            }
    
            getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT,WindowManager.LayoutParams.MATCH_PARENT);
            //点击Dialog外部消失
            setCanceledOnTouchOutside(true);
            //禁用返回键
            setCancelable(true);
            //设置点击事件
            if (clickIds != null) {
                for (int id : clickIds) {
                    findViewById(id).setOnClickListener(this);
                }
            }
        }
    
        public View getView() {
            if (view == null) {
                return getLayoutInflater().inflate(layoutRes, null);
            }
            return view;
        }
    
        private OnBottomItemClickListener listener;
    
        public interface OnBottomItemClickListener {
            void onBottomItemClick(BottomDialog dialog, View view);
        }
    
        public void setOnBottomItemClickListener(OnBottomItemClickListener listener) {
            this.listener = listener;
        }
    
        @Override
        public void onClick(View v) {
            listener.onBottomItemClick(this, v);
        }
    }
    
    

    五 styles

    <resources>
    
        <!-- Base application theme. -->
        <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
            <!-- Customize your theme here. -->
            <item name="colorPrimary">@color/colorPrimary</item>
            <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
            <item name="colorAccent">@color/colorAccent</item>
        </style>
    
        <style name="transparentFrameWindowStyle" parent="android:style/Theme.Dialog">
            <item name="android:windowBackground">@drawable/photo_choose_bg</item>
        </style>
    
        <style name="main_menu_animstyle">
            <item name="android:windowEnterAnimation">@anim/photo_dialog_in_anim</item>
            <item name="android:windowExitAnimation">@anim/photo_dialog_out_anim</item>
        </style>
    
        <!--自定义Dialog弹出的全屏样式,不要继承系统Dialog的样式会出现抖动的情况-->
        <style name="dialog_full">
            <item name="android:windowIsFloating">true</item>   <!--是否悬浮在界面上-->
            <item name="android:windowIsTranslucent">true</item>   <!--是否半透明-->
            <item name="android:windowNoTitle">true</item> <!--是否有标题-->
            <item name="android:windowBackground">@android:color/transparent</item>  <!--窗口背景色透明-->
            <item name="android:backgroundDimEnabled">true</item>  <!--背景是否模糊显示-->
        </style>
    
        <!--自定义Dialog的底部弹出的动画,直接从中间弹出的不加动画-->
        <style name="DialogBottomAnimation"  parent="android:Animation">
            <item name="android:windowEnterAnimation">@anim/dialog_bottom_enter</item>
            <item name="android:windowExitAnimation">@anim/dialog_bottom_exit</item>
        </style>
    </resources>
    
    

    六 相关的资源动画

    photo_dialog_in_anim

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android" >
    
        <translate
            android:duration="200"
            android:fromXDelta="0"
            android:fromYDelta="1000"
            android:toXDelta="0"
            android:toYDelta="0" />
    
    </set>
    

    photo_dialog_out_anim.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android" >
    
        <translate
            android:duration="300"
            android:fromXDelta="0"
            android:fromYDelta="0"
            android:toXDelta="0"
            android:toYDelta="1000" />
    
    </set>
    

    尾言

    为自己技术增值,量变引起质变.对象亦来源于生活,模式亦来源于验证的OO经验,那么请学会使用轮子,再到感受制造轮子的乐趣,你会发现原来编程那么美妙.如有错误或不当之处,请读者留言,博主好吸取经验,互相交流学习,对你有帮助请点赞,粉一波哦

    展开全文
  • 底部弹出框BottomDialog

    千次阅读 2018-03-27 14:29:51
    日常需求中通常都会有这样的需求,点击按钮会从底部弹出一个对话框,选择操作。例如分享或者更换头像弹出对话框。 因此抽空将此功能封装成库,方便以后引用。 ScreenShot Import Maven Step 1. Add ...

    BottomDialog

    日常需求中通常都会有这样的需求,点击按钮会从底部弹出一个对话框,选择操作。例如分享或者更换头像弹出对话框。

    因此抽空将此功能封装成库,方便以后引用。

    ScreenShot

    图一图二

    图三图四

    Import

    Maven

    Step 1. Add the JitPack repository to your build file

    <repositories>
        <repository>
            <id>jitpack.io</id>
            <url>https://jitpack.io</url>
        </repository>
    </repositories>

    Step 2. Add the dependency

    <dependency>
        <groupId>com.github.SmartCyl</groupId>
        <artifactId>BottomDialog</artifactId>
        <version>1.0.4</version>
    </dependency>

    Or Gradle

    Step 1. Add the JitPack repository to your build file

    Add it in your root build.gradle at the end of repositories:

    allprojects {
        repositories {
            ...
            maven { url 'https://jitpack.io' }
        }
    }

    Step 2. Add the dependency

    dependencies {
        compile 'com.github.SmartCyl:BottomDialog:1.0.4'
    }

    Usage

    当不需要图片时,Item的构造器第一个参数传0 :new Item(0,”name”)

    1、使用前3张图中类似的效果直接使用自带的layout文件即可。

    new SmartDialog().init(context).items(List<Item>).display();

    默认布局 APIs

    方法 说明 默认值
    backgroundRes 设置背景资源,如圆角(backgroundResEnable为true时生效) R.drawable.shape_round_corner
    backgroundResEnable 是否启用设置背景资源 true
    onItemClick ReciclerView的单击监听 -
    onItemLongClick ReciclerView的长按监听 -
    title 设置标题 标题
    titleVisible 是否显示标题 true
    titleGravity 标题显示位置 Gravity.CENTER
    titleColor 标题颜色 727272
    titleSize 标题字体大小 16
    cancelVisible 是否显示取消按钮 true
    cancel 隐藏Dialog -
    itemOrientation RecyclerView子项布局方式(垂直[图二]/水平[图一]) LinearLayout.VERTICAL
    recyclerViewOrientation RecyclerView排布方式(垂直/Grid[图二]) BaseSmartDialog.ORIENTATION_VERTICAL
    spanCount 列数(recyclerViewOrientation为GRID时生效) 3
    adapter 设置适配器 SmartAdapter

    2、使用自定义布局(如图四)

    new SmartDialog().init(context).layoutRes(layout).display();

    共用 APIs

    方法 说明 默认值
    items 设置数据源 -
    display 显示Dialog -
    layoutRes 设置自定义布局 -
    dialogHeight 设置Dialog高度 包裹内容
    dialogWidth 设置Dialog宽度 屏幕宽度(若宽度不铺满屏幕,调用padding(0)即可)
    padding(padding) 设置内边距 30
    padding(l,t,r,b) 设置内边距 30
    gravity Dialog的位置 Gravity.BOTTOM
    animEnable 是否启用Dialog从底部弹出的动画 true
    animDuration Dialog从底部弹出动画持续时间 500ms
    cancelableOutside 点击Dialog外部是否可隐藏Dialog true
    onOutsideClick 点击Dialog外部区域事件监听(用于点击外部后判断做什么操作,设置后点击外部Dialog不会自动消失,需要调用dialog.cancel()) -
    dimAmount 设置阴影部分的灰暗度 0.5F
    alpha 设置Dialog透明度 1F
    bindViewListener 绑定视图回调(可用于自定义layout的点击事件监听) -

    示例(默认布局)

    new SmartDialog().init(this)
        .items(items) // 设置数据源
        .title("标题")
        .onItemClick(new OnItemClickListener() {
            @Override
            public void onItemClick(int position, Item item) {
                // 单击回调
            }
        })
        .onItemLongClick(new OnItemLongCli() {
            @Override
            public void onItemLongClick(int position, Item item){
                // 长按回调
            }
        })
        .onOutsideClick(new OutsideClickListener() {
            @Override
            public void outsideClick(boolean isOutside, BaseSmartDialog dialog) {
                dialog.cancle(); // 使对话框消失
                // 点击外部区域监听                 
            }
        })
        .backgroundResEnable(true)
        .animEnable(false)
        .cancelVisible(true)
        .titleVisible(true)
        .cancelableOutside(true)
        .titleGravity(Gravity.CENTER)
        .gravity(Gravity.CENTER)
        .titleColor(R.color.colorAccent)
        .titleSize(20)
        .padding(20)
        .itemOrientation(LinearLayout.VERTICAL)
        .animDuration(400)
        .display();

    示例(自定义布局)

    new SmartDialog().init(this)
        .items(items) // 设置数据源
        .onOutsideClick(new OutsideClickListener() {
            @Override
            public void outsideClick(boolean isOutside, BaseSmartDialog dialog) {
                dialog.cancle(); // 使对话框消失
                // 点击外部区域监听                 
            }
        })
        // 为自定义布局的子控件设监听
        .bindViewListener(new BindViewListener() {
            @Override
            public void bind(View dialogView, final BaseSmartDialog dialog) {
                // xxx为自定义layout的id
                dialogView.findViewById(R.id.xxx).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        // do something
                        dialog.cancel();
                    }
                });
            }
        });
        .animEnable(false)
        .cancelableOutside(true)
        .gravity(Gravity.CENTER)
        .padding(20)
        .animDuration(400)
        .display();

    github地址

    展开全文
  • Dialog底部弹出效果

    2017-03-30 09:12:45
    经常需求在底部弹框,选择消失,可以用popupwindow,也可以用dialog,如下设置: dialog.show(); Window window = dialog.getWindow(); window.setWindowAnimations(R.style.take_phtoto);//动画 window....
  • 自定义Dialog之底部弹出Dialog

    千次阅读 2017-02-06 22:47:19
    自定义Dialog,设置Dialog居于底部并且和屏幕一样宽: public class BottomStyleDialog extends Dialog implements OnItemClickListener { private String[] mNames = new String[] { "我是条目1", "我是条目2",
  • 1.dialog_pick_avatar.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" an...
  • 底部弹出Dialog

    2018-08-18 11:18:36
    实际开发过程中总是有从底部弹出对话框的需求,显示和隐藏有一个划进划出的过场动画,核心代码如下: public void showDialog() { Dialog dialog = new Dialog(this, R.style.ActionSheetDialogStyle); View ...
  • 底部弹出Dialog窗口

    千次阅读 2019-04-16 15:42:11
    dialog_enter.xml //dialog的进入动画 &lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;set xmlns:android="http://schemas.android.com/apk/res/android"&gt...
  • Android 实现屏幕底部弹出Dialog

    万次阅读 2017-09-08 15:18:02
    Android 实现屏幕底部弹出Dialog 封装使用(本文作为开发中记录使用,请轻喷)日常开发中经常用到Dialog实现用户交互界面每次都要重写一个很麻烦(产品经理一言不合就要求弹窗)效果图 这个效果要的算是比较常见的了 ...
  • Android dialog软键盘弹出顶起View

    万次阅读 2015-03-19 15:42:56
     一开始我一直用RelativeLayout做布局,因为需要从底部弹出,所以该布局可以很简单的把View控制在底部。但紧接着问题出来了,弹出的软键盘会遮住大部分的View, 只留输入框,而且还显示不全。一直纠结中。
  • 通常我们使用dialog的时候会遇到一些问题,比如我想用自己定义的...我想要指定dialog底部弹出而不是在屏幕中央弹出要怎么做?我设置了dialog布局的宽度为填充父窗体然而实际效果却不是充满全屏的,这时我该怎么做?
  • 有时候进行分享操作的时候—–要求从从底部自下而上弹出.上图中的效果既可以通过自定义Dialog实现也可以通过自定义PopWindow来实现.关于popWindow的实现方式,大家可参照本人的另一篇博文Android自定义popWindow教程....
  • Android实现从底部弹出Dialog

    千次阅读 2018-02-26 22:04:54
    xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_p
  • AlertDialog弹窗在屏幕底部

    千次阅读 2015-04-03 09:01:25
    AlertDialog弹窗在屏幕底部
  • 原文链接: http://blog.csdn.net/shengyakun1/article/details/54174893   (吐槽一下原文排版好难看....   Android 部分机型没有物理按键,只有虚拟按键,Activity全屏方法如下: ...之前添加...
  • 1、示例简介:实现手指从屏幕底部向上滑动的方式来显示Dialog。 2、示例展示: 3、示例细节: ①当手指在屏幕下方1/4区域内按下时,在手指按下位置显示Dialog; ②在手指向上滑动的过程中,Dialog能自动根据手指到...
  • Android中实现底部弹出菜单栏

    万次阅读 2016-12-09 14:36:25
    今天闲的没事写了一个底部弹出菜单栏,虽然很简单,但是为了以后方便用,索性还是写下来了,那好,我们先看一下实现效果吧,我想这种效果现在用的实在是太多了(点击按钮显示底部菜单栏,然后单击空白地方隐藏菜单栏...
  • android 项目需求,底部需要弹出list框,整理了一个很好用的Dialog。代码如下: 1.代码片段private Context mContext; private Dialog bottomDialog; private ViewHolder holder;private void showDialog() { ...
  • 可以通过覆盖框架的样式来实现, 通过改变translate3d(x,y,z)来实现不同方向的弹出. 若将100%-0 改为x轴,则是左边弹出.其他方向同理 . @keyframes dialog-fade-in { 0% { transform: translate3d(0,100% , 0); ...
1 2 3 4 5 ... 20
收藏数 8,894
精华内容 3,557
热门标签
关键字:

底部弹出dialog