1.android实现底部弹框的两种实现方式:


(1) 使用系统自带对话框AlertDialog 实现

(2)自定义对话框实现


 1.1使用系统自带对话框AlertDialog 实现


public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button mButton;
    private String[] items = {"色情/辱骂", "广告骚扰", "政治", "其他"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mButton = (Button) findViewById(R.id.activity_bt);
        initListener();
    }

    private void initListener() {
        mButton.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.activity_bt:
                showDialog();
                break;
        }
    }

    private void showDialog() {
        
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setItems(items, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(MainActivity.this, items + "", Toast.LENGTH_SHORT);
            }
        });
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(MainActivity.this, "取消", Toast.LENGTH_SHORT).show();
            }
        });
        AlertDialog mDialog = builder.create();
        mDialog.show();
        Window window = mDialog.getWindow();
        window.setGravity(Gravity.BOTTOM);
        window.setWindowAnimations(R.style.popupAnimation);
        mDialog.setCanceledOnTouchOutside(true);
        mDialog.setCancelable(true);
    }
}


动画主题

anim文件夹下进入代码 pop_in.xml:

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



anim文件夹下退出代码pop_out.xml:

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


styles.xml 主题

<!-- alertDialog animation 样式 -->
    <style name="popupAnimation" parent="android:Animation">
        <item name="android:windowEnterAnimation">@anim/pop_in</item>
        <item name="android:windowExitAnimation">@anim/pop_out</item>
    </style>




运行效果图如下:

Android PopupWindow实现弹窗 android弹框提示_android

这是第一种底部弹出提示框的实现方法。

(2)可能你已经发现了,其实Alertdialog 并不是紧挨着底部的,另外就是两边也会留下间隙,这是主题导致的。要想去除掉间隙,可以使用我们可以使用第二种方法:

在这里我贴出showDialog()的方法,其他的部分和上面的一样,


private void showDialog() {

        AlertDialog mDialog = new AlertDialog.Builder(this).create();
        mDialog.show();
        Window window = mDialog.getWindow();
        window.setGravity(Gravity.BOTTOM);
        window.setWindowAnimations(R.style.popupAnimation);
        View view = View.inflate(this, R.layout.alert_dialog_view, null);
        final TextView mAdTv = (TextView) view.findViewById(R.id.dialog_ad);
        final TextView mSexTv = (TextView) view.findViewById(R.id.dialog_eroticism);
        mAdTv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "mAdTv.getText():" + mAdTv.getText(), Toast.LENGTH_SHORT).show();
            }
        });
        mSexTv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "mSexTv.getText():" + mSexTv.getText(), Toast.LENGTH_SHORT).show();
            }
        });
        window.setContentView(view);
        window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT);//设置横向全屏

        mDialog.setCanceledOnTouchOutside(true);
        mDialog.setCancelable(true);
    }






layout.alert_dialog_view的布局如下:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/dialog_ad"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="#46a3e7"
        android:gravity="center"
        android:text="广告" />

    <View
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:background="#dddddd" />

    <TextView
        android:id="@+id/dialog_eroticism"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="#46a3e7"
        android:gravity="center"
        android:text="色情" />
</LinearLayout>



效果图如下:

Android PopupWindow实现弹窗 android弹框提示_ide_02


通过自定义布局的形式就能实现从底部弹出,并且没有和屏幕没有任何间距。但是但是这样就是变得麻烦起来:在一个项目中这种提示框有可能会用到好几次,每一次内容和条目数都是有可能不同的,难道还要每次都新建布局吗?这也太麻烦了。于是我就自己封装了一个底部弹出对话框,可以添加任意多个Item,方便调用。请看最后一种方法:


1.2 自定义对话框实现


写的这个对话框的支持放任意多个Item,而无须重复的创建布局。只需要调用简单的方法即可达到想要的效果,贴出核心方法:



public class DialogUtil {

    /**
     * 此 dialog 效果从底部弹出,可以添加任意多个Item。
     *
     * @param context
     * @param mWidth   需要设置的dialog的宽度
     * @param listener 选择Item会调用此监听
     * @param contents 任意多个Item选项内容(从最顶端到最低端)
     * @return
     */
    public static Dialog showItemSelectDialog(Context context
            , int mWidth
            , final OnItemSelectedListener listener
            , final String... contents) {

        final Dialog mDialog = new Dialog(context, R.style.Dialog_Transparent_Theme);
        View rootView = LayoutInflater.from(context).inflate(R.layout.layout_choice, null);

        LinearLayout contentsView = (LinearLayout) rootView.findViewById(R.id.dialogContent);
        for (int i = 0; i < contents.length; i++) {
            if (i == 0) {
                View topView = LayoutInflater.from(context).inflate(R.layout.dialog_top_item, null);
                TextView topText = (TextView) topView.findViewById(R.id.dialog_top);
                topText.setText(contents[0]);
                topText.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {

                        mDialog.dismiss();
                        if (listener != null)
                            listener.getSelectedItem(contents[0]);
                    }
                });
                contentsView.addView(topView);
            } else if (i == contents.length - 1) {
                View bottomView = LayoutInflater.from(context).inflate(R.layout.dialog_bottom_item, null);
                TextView boottomTv = (TextView) bottomView.findViewById(R.id.dialog_bottom);
                boottomTv.setText(contents[contents.length - 1]);
                boottomTv.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {

                        mDialog.dismiss();
                        if (listener != null)
                            listener.getSelectedItem(contents[contents.length - 1]);
                    }
                });
                contentsView.addView(bottomView);
            } else {
                View centerView = LayoutInflater.from(context).inflate(R.layout.dialog_center_item, null);
                TextView centTv = (TextView) centerView.findViewById(R.id.dialog_center_item);
                final int finalI = i;
                centTv.setText(contents[finalI]);
                centTv.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {

                        mDialog.dismiss();
                        if (listener != null)
                            listener.getSelectedItem(contents[finalI]);
                    }
                });
                contentsView.addView(centerView);
            }
        }
        rootView.findViewById(R.id.btn_cancel).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mDialog.dismiss();
            }
        });
        mDialog.setContentView(rootView);
        mDialog.setCanceledOnTouchOutside(true);


        Window window = mDialog.getWindow();
        WindowManager.LayoutParams params = window.getAttributes();
        params.gravity = Gravity.BOTTOM;
        params.width = mWidth * 9 / 10;
        window.setWindowAnimations(R.style.popupAnimation);
        window.setAttributes(params);

        mDialog.show();

        return mDialog;
    }

监听事件代码:

public interface OnItemSelectedListener {
    public void getSelectedItem(String content);
}




布局layout_choice如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="fill_parent"
    android:gravity="bottom"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/dialogContent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" />

    <Button
        android:id="@+id/btn_cancel"
        android:layout_width="fill_parent"
        android:layout_height="45dp"
        android:layout_gravity="center"
        android:layout_marginBottom="5dp"
        android:layout_marginTop="10dp"
        android:background="@drawable/tv_shape"
        android:gravity="center"
        android:text="取消"
        android:textColor="@drawable/text_select_selector"
        android:textSize="16sp" />

</LinearLayout>



实现这个定义的dialog的原理很简单,加入传递了三条数据,会动态的将这三条数据加入到LineLayout,然后再显示dilog就可以了。接下来就是调用了。还是showDialog()这个方法:


private void showDialog() {
        DialogUtil.showItemSelectDialog(MainActivity.this, mWidth
                , onIllegalListener
                , "色情/辱骂"
                , "广告骚扰"
                , "政治"
                , "其他");//可填添加任意多个Item呦
    }

    private OnItemSelectedListener onIllegalListener = new OnItemSelectedListener() {
        @Override
        public void getSelectedItem(String content) {
            Toast.makeText(MainActivity.this, content, Toast.LENGTH_SHORT).show();
        }
    };


效果图:

Android PopupWindow实现弹窗 android弹框提示_xml_03



是不是很像ios的弹框效果,并且方法调用也很简单。从图中可以看到Item中只有最顶部和最底部是带有圆角的中间的部分是没有圆角的,所以我才使用了上 中 下 三个布局进行动态的加载,如何大家不需要这中效果根据想要的效果自己布置一下UI即可。