标签: Dialog

Dialog详解(包括进度条、PopupWindow、自定义view、自定义样式的对话框)

Dialog详解(包括进度条、PopupWindow、自定义view、自定义样式的对话框)

%title插图%num

Android中提供了多种对话框,在实际应用中我们可能会需要修改这些已有的对话框。本实例就是从实际出发,展现了andorid中大部分对话框,代码中用了一个对话框管理类来做封装,其中还定义了对话框的动画、自定义样式等等。

 

主布局文件(全是button)

复制代码
复制代码
<LinearLayout 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_parent"
    android:orientation="vertical"
    android:padding="16dp" >

    <ScrollView
        android:id="@+id/scrollView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical" >

            <Button
                android:id="@+id/simple_button_id"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:onClick="buttonListener"
                android:text="*简单的对话框" />

            <Button
                android:id="@+id/list_button_id"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:onClick="buttonListener"
                android:text="列表对话框" />

            <Button
                android:id="@+id/singleChoice_button_id"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:onClick="buttonListener"
                android:text="单选对话框" />

            <Button
                android:id="@+id/multiChoice_button_id"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:onClick="buttonListener"
                android:text="多选对话框" />

            <Button
                android:id="@+id/adapter_button_id"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:onClick="buttonListener"
                android:text="用适配器创建的对话框" />

            <Button
                android:id="@+id/view_button_id"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:onClick="buttonListener"
                android:text="自定义视图的对话框" />

            <Button
                android:id="@+id/progress_button_id"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:onClick="buttonListener"
                android:text="有进度条的对话框" />

            <Button
                android:id="@+id/activity_button_id"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:onClick="buttonListener"
                android:text="用Activity作的对话框" />

            <Button
                android:id="@+id/popup_button_id"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:onClick="buttonListener"
                android:text="用PopupWindow创建的对话框" />

            <Button
                android:id="@+id/date_button_id"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:onClick="buttonListener"
                android:text="选择日期的对话框" />

            <Button
                android:id="@+id/time_button_id"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:onClick="buttonListener"
                android:text="选择时间的对话框" />
        </LinearLayout>
    </ScrollView>

</LinearLayout>
复制代码
复制代码

 

自定义对话框视图

%title插图%num

复制代码
复制代码
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#f5f5f5"
        android:orientation="vertical" >

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="60dp" >

            <ImageView
                android:id="@+id/dialog_imageView_id"
                android:layout_width="match_parent"
                android:layout_height="3dp"
                android:layout_alignParentBottom="true"
                android:layout_alignParentLeft="true"
                android:background="#ffd060" />

            <TextView
                android:id="@+id/dialog_textView_id"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_centerVertical="true"
                android:text="自定义布局"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:textColor="#50c0e9" />
        </RelativeLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_marginTop="10dp"
            android:background="@drawable/my_input_box"
            android:paddingLeft="20dp"
            android:paddingRight="20dp" >

            <EditText
                android:id="@+id/dialog_username_EditText_id"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:background="@null"
                android:ems="10"
                android:hint="学号/账号"
                android:inputType="number" >

                <requestFocus />
            </EditText>
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:background="@drawable/my_input_box"
            android:paddingLeft="20dp"
            android:paddingRight="20dp" >

            <EditText
                android:id="@+id/dialog_password_EditText_id"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:background="@null"
                android:ems="10"
                android:hint="密码"
                android:password="true" />
        </LinearLayout>

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_marginTop="10dp"
            android:background="#bababa" />

        <Button
            android:id="@+id/dialog_logout_button_id"
            android:layout_width="match_parent"
            android:layout_height="45dp"
            android:background="@drawable/layout_selector"
            android:gravity="center_horizontal"
            android:text="确定"
            android:textColor="#535252"
            android:textSize="20sp" />
    </LinearLayout>

</RelativeLayout>
复制代码
复制代码

 

MainActivity.java

复制代码
复制代码
package com.kale.dialog;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;


public class MainActivity extends Activity {

    DialogManager dm;
    String msg = "内容";
    String[] str = new String[] { "android", "java", "ios" };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        dm = new DialogManager(this);

        
    }

    public void buttonListener(View v) {
        dm = new DialogManager(this);
        switch (v.getId()) {
        case R.id.simple_button_id:
            dm.simpleDialog("*简单的对话框", msg);
            break;
        case R.id.list_button_id:
            dm.listDialog("列表对话框", str);
            break;
        case R.id.singleChoice_button_id:
            dm.singleChoiceDialog("单选对话框", str);
            break;
        case R.id.multiChoice_button_id:
            dm.MultiChoiceDialog("多选对话框", str);
            break;
        case R.id.adapter_button_id:
            dm.adapterDialog("用适配器建立的对话框", str);
            break;
        case R.id.view_button_id:
            dm.viewDialog("采用自定义视图的对话框");
            break;
        case R.id.progress_button_id:
            dm.progressDialog("含进度条的对话框",msg);
            break;
        case R.id.activity_button_id:
            startActivity(new Intent(MainActivity.this,DialogActivity.class));
            break;
        case R.id.popup_button_id:
            dm.popupWindowDialog("PopupWindows对话框", v);
            break;
        case R.id.date_button_id:
            dm.dateDialog();
            break;
        case R.id.time_button_id:
            dm.timeDialog();
            break;            
        default:
            break;
        }
    }

}
复制代码
复制代码

 

 

 

现在我们分步讲解下各种对话框:

首先是一个公用的初始化设置和监听器设置

复制代码
复制代码
private Context mContext;
    private AlertDialog.Builder builder;

    public DialogManager(Context context) {
        mContext = context;
        builder = new AlertDialog.Builder(mContext);
    }

    /**
     * 设置对话框的标题+图标+按钮
     * 
     * @param title
     */
    private void setButton(String title) {
        builder.setTitle(title).setIcon(R.drawable.ic_launcher)
                .setPositiveButton("好", new positiveListener())
                .setNeutralButton("中", new NeutralListener())
                .setNegativeButton("差", new NegativeListener());
        // .setCancelable(false);//设置点击空白处,不能消除该对话框
    }

    /**
     * @author:Jack Tony
     * @tips : 监听器
     * @date :2014-7-25
     */
    private class positiveListener implements DialogInterface.OnClickListener {
        @Override
        public void onClick(DialogInterface dialog, int which) {

            // dialog.dismiss();//设置对话框强制退出
            showToast("好");

        }
    }

    private class NeutralListener implements DialogInterface.OnClickListener {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            showToast("中");
        }
    }

    private class NegativeListener implements DialogInterface.OnClickListener {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            showToast("差");
        }
    }

    private void showToast(String msg) {
        Toast.makeText(mContext, msg, 0).show();
    }
复制代码
复制代码

 

简易对话框

%title插图%num

复制代码
复制代码
    /**
     * 简易对话框
     * 
     * @param title
     * @param msg
     */
    public void simpleDialog(String title, String msg) {
        setButton(title);
        builder.setMessage(msg).create().show();
    }
复制代码
复制代码

 

列表对话框

%title插图%num

复制代码
复制代码
/**
     * 列表对话框
     * 
     * @param title
     * @param str
     */
    public void listDialog(String title, final String[] str) {
        setButton(title);
        // 设置了列表就不能设置内容了,否则就会出问题
        builder.setItems(str, new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                showToast("选中了:" + str[which]);
            }
        }).create().show();
    }
复制代码
复制代码

 

单选对话框

%title插图%num

复制代码
复制代码
/**
     * 单选对话框
     * 
     * @param title
     * @param str
     */
    public void singleChoiceDialog(String title, final String[] str) {
        setButton(title);
        builder
        // 设置选中了第二项
        .setSingleChoiceItems(str, 1, new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                showToast("选中了:" + str[which]);
            }
        }).create().show();
    }
复制代码
复制代码

 

多选对话框

%title插图%num

复制代码
复制代码
    /**
     * 多选对话框
     * 
     * @param title
     * @param str
     */
    public void MultiChoiceDialog(String title, final String[] str) {
        setButton(title);
        builder
        // 默认选中几项
        .setMultiChoiceItems(str, new boolean[] { true, false, true },
                new OnMultiChoiceClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which,
                            boolean isChecked) {
                        showToast("你选择的id为" + which + " , " + "选中了:"
                                + str[which]);
                    }
                }).create().show();
    }
复制代码
复制代码

 

适配器对话框(可以用各种适配器,比如SimpleAdapter)

%title插图%num

复制代码
复制代码
    /**
     * 适配器对话框
     * 
     * @param title
     * @param str
     */
    public void adapterDialog(String title, final String[] str) {
        setButton(title);
        builder.setAdapter(
                new ArrayAdapter<String>(mContext,
                        android.R.layout.simple_list_item_multiple_choice, str),
                new OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        showToast("选中了:" + str[which]);
                    }
                }).create().show();
    }
复制代码
复制代码

 

自定义视图的对话框

%title插图%num

复制代码
复制代码
/**
     * 自定义视图对话框
     * 
     * @param title
     */
    public void viewDialog(String title) {
        // LayoutInflater是用来找layout文件夹下的xml布局文件,并且实例化
        LayoutInflater factory = LayoutInflater.from(mContext);
        // 把activity_login中的控件定义在View中
        View view = factory.inflate(R.layout.dialog_layout, null);
        // 将LoginActivity中的控件显示在对话框中

        // 获取用户输入的“用户名”,“密码”
        // 注意:view.findViewById很重要,因为上面factory.inflate(R.layout.activity_login,
        // null)将页面布局赋值给了view了
        TextView titleTv = (TextView) view
                .findViewById(R.id.dialog_textView_id);
        titleTv.setText(title);
        Button btn = (Button) view.findViewById(R.id.dialog_logout_button_id);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                showToast("按下自定义视图的按钮了~");
            }
        });

        builder
        // 设定显示的View
        .setView(view);
        // 设置dialog是否为模态,false表示模态,true表示非模态
        // ab.setCancelable(false);
        // 对话框的创建、显示,这里显示的位置是在屏幕的*下面,但是很不推荐这个种做法,因为距底部有一段空隙
        AlertDialog dialog = builder.create();
        Window window = dialog.getWindow();
        window.setGravity(Gravity.BOTTOM); // 此处可以设置dialog显示的位置
        window.setWindowAnimations(R.style.myAnimationstyle); // 添加动画
        dialog.show();
    }
复制代码
复制代码

 

进度条对话框(这里可以定义显示精准进度的、模糊进度的、圆形模糊进度的进度条)

%title插图%num

复制代码
复制代码
    /**
     * 进度条对话框
     * 
     * @param title
     * @param msg
     */
    public void progressDialog(String title, String msg) {
        final ProgressDialog dialog = new ProgressDialog(mContext);
        dialog.setTitle(title);
        dialog.setMessage(msg);
        dialog.setCancelable(false);// 设置点击空白处也不能关闭该对话框

        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        // dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);//设置采用圆形进度条

        dialog.setMax(100);
        // dialog.setIndeterminate(true);//设置不显示明确的进度
        dialog.setIndeterminate(false);// 设置显示明确的进度

        dialog.setButton(ProgressDialog.BUTTON_POSITIVE, "确定",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        // 这里添加点击后的逻辑
                    }
                });
        dialog.setButton(ProgressDialog.BUTTON_NEUTRAL, "中立",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        // 这里添加点击后的逻辑
                    }
                });
        dialog.setButton(ProgressDialog.BUTTON_NEGATIVE, "取消",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        // 这里添加点击后的逻辑
                    }
                });
        dialog.show();

        //启动线程,模拟一个耗时的操作
        new Thread(new Runnable() {
            @Override
            public void run() {
                int Progress = 0;
                while (Progress < 100) {
                    try {
                        Thread.sleep(100);
                        Progress++;
                        // dialog.setProgress(Progress);
                        dialog.incrementProgressBy(1);// 进度条一次加10
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                dialog.dismiss();// 完成后消失
            }
        }).start();
    }
复制代码
复制代码

 

用PopupWindow做的对话框,PopupWindow特别适合显示从特定位置弹出的的菜单。我这里设置对话框是从底部弹出,用了一些动画效果。

%title插图%num

复制代码
复制代码
/**
     * PopupWindow做的对话框 感谢: http://www.apkbus.com/android-56965-1-1.html
     * http://blog.csdn.net/zhufuing/article/details/17783333
     * http://www.open-open.com/lib/view/open1379383271818.html
     * 
     * @param title
     * @param v
     */
    public void popupWindowDialog(String title, View v) {
        // 装载布局文件
        View view = LayoutInflater.from(mContext).inflate(
                R.layout.dialog_layout, null);
        // 创建PopupWindow对象,添加视图,设置宽高,*后一个参数为设置点击屏幕空白处(按返回键)对话框消失。
        // 也可以用.setFocusable(true);.
        final PopupWindow pWindow = new PopupWindow(view,
                LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, true);
        pWindow.setBackgroundDrawable(new BitmapDrawable());// 为了让对话框点击空白处消失,必须有这条语句
        pWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);// 出现输入法时,重新布局
        pWindow.setAnimationStyle(R.style.myAnimationstyle);// 设置动画

        TextView titleTv = (TextView) view
                .findViewById(R.id.dialog_textView_id);
        titleTv.setText(title);
        Button btn = (Button) view.findViewById(R.id.dialog_logout_button_id);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                showToast("按下PopupWindow中的按钮了~");
                pWindow.dismiss();
            }
        });
        // 用下拉方式显示
        // pWindow.showAsDropDown(v);
        pWindow.showAtLocation(v, Gravity.BOTTOM, 0, 0);
    }
复制代码
复制代码

动画效果和style文件

动画文件的目录 res/anim

dialog_enter.xml

复制代码
复制代码
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="200"
        android:fromYDelta="100%p"
        android:toYDelta="0" />

</set>
复制代码
复制代码

dialog_exit.xml

复制代码
复制代码
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="200"
        android:fromYDelta="0"
        android:toYDelta="50%p" />

</set>
复制代码
复制代码

样式文件的目录:values/styles.xml

复制代码
复制代码
<resources>
    
     <style name="myAnimationstyle" parent="android:Animation">  
        <item name="@android:windowEnterAnimation">@anim/dialog_enter</item>  
        <item name="@android:windowExitAnimation">@anim/dialog_exit</item>  
    </style>  
</resources>
复制代码
复制代码

 

日期对话框

%title插图%num

复制代码
复制代码
/**
     * 日期对话框
     */
    public void dateDialog() {
        Calendar c = Calendar.getInstance();
        DatePickerDialog dialog = new DatePickerDialog(mContext,
                new DatePickerDialog.OnDateSetListener() {

                    @Override
                    public void onDateSet(DatePicker dp, int year, int month,
                            int dayOfMonth) {
                        showToast(year + "-" + (month + 1) + "-" + dayOfMonth);
                    }
                }, c.get(Calendar.YEAR), c.get(Calendar.MONTH),
                c.get(Calendar.DAY_OF_MONTH));
        dialog.show();
    }
复制代码
复制代码

 

时间对话框

%title插图%num

复制代码
复制代码
    /**
     * 时间对话框
     */
    public void timeDialog() {
        Calendar c = Calendar.getInstance();
        new TimePickerDialog(mContext,
                new TimePickerDialog.OnTimeSetListener() {

                    @Override
                    public void onTimeSet(TimePicker arg0, int hourOfDay,
                            int minute) {
                        showToast(hourOfDay + ":" + minute);
                    }
                }, c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE), true)
                .show();
    }
复制代码
复制代码

 

用Activit做的对话框

%title插图%num

DialogActivity.java

复制代码
复制代码
package com.kale.dialog;

import android.app.Activity;
import android.os.Bundle;

public class DialogActivity extends Activity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dialog_layout);
    }
}
复制代码
复制代码

 

首先,定义风格

复制代码
复制代码
    <!-- android Dialog去掉标题栏 和边框 -->
     <style name="myDialogTheme" parent="android:Theme.Dialog">
        <item name="android:windowFrame">@null</item><!--边框-->
        <item name="android:windowIsFloating">true</item><!--是否浮现在activity之上-->
        <item name="android:windowIsTranslucent">true</item> <!-- 是否透明 -->
        <item name="android:windowNoTitle">true</item><!--除去title-->
        <item name="android:windowContentOverlay">@null</item> <!-- 对话框是否有遮盖 -->
        <item name="android:backgroundDimEnabled">false</item><!-- 不允许对话框的背景变暗 -->
        <item name="android:windowBackground">@null</item><!--除去背景色-->
    </style>
复制代码
复制代码

然后,在AndroidManifest.xml中给activity设置风格

复制代码
复制代码
        <activity 
            android:name="com.kale.dialog.DialogActivity"
            android:theme="@style/myDialogTheme">
        </activity>
复制代码
复制代码

*后,启动这个activity即可

startActivity(new Intent(MainActivity.this,DialogActivity.class));

 

下面是DialogManager.java工具类的全部代码

复制代码
复制代码
package com.kale.dialog;

import java.util.Calendar;

import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.ProgressDialog;
import android.app.TimePickerDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.DialogInterface.OnMultiChoiceClickListener;
import android.graphics.drawable.BitmapDrawable;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;

public class DialogManager {

    private Context mContext;
    private AlertDialog.Builder builder;

    public DialogManager(Context context) {
        mContext = context;
        builder = new AlertDialog.Builder(mContext);
    }

    /**
     * 简易对话框
     * 
     * @param title
     * @param msg
     */
    public void simpleDialog(String title, String msg) {
        setButton(title);
        builder.setMessage(msg).create().show();
    }

    /**
     * 列表对话框
     * 
     * @param title
     * @param str
     */
    public void listDialog(String title, final String[] str) {
        setButton(title);
        // 设置了列表就不能设置内容了,否则就会出问题
        builder.setItems(str, new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                showToast("选中了:" + str[which]);
            }
        }).create().show();
    }

    /**
     * 单选对话框
     * 
     * @param title
     * @param str
     */
    public void singleChoiceDialog(String title, final String[] str) {
        setButton(title);
        builder
        // 设置选中了第二项
        .setSingleChoiceItems(str, 1, new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                showToast("选中了:" + str[which]);
            }
        }).create().show();
    }

    /**
     * 多选对话框
     * 
     * @param title
     * @param str
     */
    public void MultiChoiceDialog(String title, final String[] str) {
        setButton(title);
        builder
        // 默认选中几项
        .setMultiChoiceItems(str, new boolean[] { true, false, true },
                new OnMultiChoiceClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which,
                            boolean isChecked) {
                        showToast("你选择的id为" + which + " , " + "选中了:"
                                + str[which]);
                    }
                }).create().show();
    }

    /**
     * 适配器对话框
     * 
     * @param title
     * @param str
     */
    public void adapterDialog(String title, final String[] str) {
        setButton(title);
        builder.setAdapter(
                new ArrayAdapter<String>(mContext,
                        android.R.layout.simple_list_item_multiple_choice, str),
                new OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        showToast("选中了:" + str[which]);
                    }
                }).create().show();
    }

    /**
     * 自定义视图对话框
     * 
     * @param title
     */
    public void viewDialog(String title) {
        // LayoutInflater是用来找layout文件夹下的xml布局文件,并且实例化
        LayoutInflater factory = LayoutInflater.from(mContext);
        // 把activity_login中的控件定义在View中
        View view = factory.inflate(R.layout.dialog_layout, null);
        // 将LoginActivity中的控件显示在对话框中

        // 获取用户输入的“用户名”,“密码”
        // 注意:view.findViewById很重要,因为上面factory.inflate(R.layout.activity_login,
        // null)将页面布局赋值给了view了
        TextView titleTv = (TextView) view
                .findViewById(R.id.dialog_textView_id);
        titleTv.setText(title);
        Button btn = (Button) view.findViewById(R.id.dialog_logout_button_id);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                showToast("按下自定义视图的按钮了~");
            }
        });

        builder
        // 设定显示的View
        .setView(view);
        // 设置dialog是否为模态,false表示模态,true表示非模态
        // ab.setCancelable(false);
        // 对话框的创建、显示,这里显示的位置是在屏幕的*下面,但是很不推荐这个种做法,因为距底部有一段空隙
        AlertDialog dialog = builder.create();
        Window window = dialog.getWindow();
        window.setGravity(Gravity.BOTTOM); // 此处可以设置dialog显示的位置
        window.setWindowAnimations(R.style.myAnimationstyle); // 添加动画
        dialog.show();
    }

    /**
     * 进度条对话框
     * 
     * @param title
     * @param msg
     */
    public void progressDialog(String title, String msg) {
        final ProgressDialog dialog = new ProgressDialog(mContext);
        dialog.setTitle(title);
        dialog.setMessage(msg);
        dialog.setCancelable(false);// 设置点击空白处也不能关闭该对话框

        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        // dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);//设置采用圆形进度条

        dialog.setMax(100);
        // dialog.setIndeterminate(true);//设置不显示明确的进度
        dialog.setIndeterminate(false);// 设置显示明确的进度

        dialog.setButton(ProgressDialog.BUTTON_POSITIVE, "确定",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        // 这里添加点击后的逻辑
                    }
                });
        dialog.setButton(ProgressDialog.BUTTON_NEUTRAL, "中立",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        // 这里添加点击后的逻辑
                    }
                });
        dialog.setButton(ProgressDialog.BUTTON_NEGATIVE, "取消",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        // 这里添加点击后的逻辑
                    }
                });
        dialog.show();

        //启动线程,模拟一个耗时的操作
        new Thread(new Runnable() {
            @Override
            public void run() {
                int Progress = 0;
                while (Progress < 100) {
                    try {
                        Thread.sleep(100);
                        Progress++;
                        // dialog.setProgress(Progress);
                        dialog.incrementProgressBy(1);// 进度条一次加10
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                dialog.dismiss();// 完成后消失
            }
        }).start();
    }

    /**
     * PopupWindow做的对话框 感谢: http://www.apkbus.com/android-56965-1-1.html
     * http://blog.csdn.net/zhufuing/article/details/17783333
     * http://www.open-open.com/lib/view/open1379383271818.html
     * 
     * @param title
     * @param v
     */
    public void popupWindowDialog(String title, View v) {
        // 装载布局文件
        View view = LayoutInflater.from(mContext).inflate(
                R.layout.dialog_layout, null);
        // 创建PopupWindow对象,添加视图,设置宽高,*后一个参数为设置点击屏幕空白处(按返回键)对话框消失。
        // 也可以用.setFocusable(true);.
        final PopupWindow pWindow = new PopupWindow(view,
                LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, true);
        pWindow.setBackgroundDrawable(new BitmapDrawable());// 为了让对话框点击空白处消失,必须有这条语句
        pWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);// 出现输入法时,重新布局
        pWindow.setAnimationStyle(R.style.myAnimationstyle);// 设置动画

        TextView titleTv = (TextView) view
                .findViewById(R.id.dialog_textView_id);
        titleTv.setText(title);
        Button btn = (Button) view.findViewById(R.id.dialog_logout_button_id);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                showToast("按下PopupWindow中的按钮了~");
                pWindow.dismiss();
            }
        });
        // 用下拉方式显示
        // pWindow.showAsDropDown(v);
        pWindow.showAtLocation(v, Gravity.BOTTOM, 0, 0);
    }

    /**
     * 日期对话框
     */
    public void dateDialog() {
        Calendar c = Calendar.getInstance();
        DatePickerDialog dialog = new DatePickerDialog(mContext,
                new DatePickerDialog.OnDateSetListener() {

                    @Override
                    public void onDateSet(DatePicker dp, int year, int month,
                            int dayOfMonth) {
                        showToast(year + "-" + (month + 1) + "-" + dayOfMonth);
                    }
                }, c.get(Calendar.YEAR), c.get(Calendar.MONTH),
                c.get(Calendar.DAY_OF_MONTH));
        dialog.show();
    }

    /**
     * 时间对话框
     */
    public void timeDialog() {
        Calendar c = Calendar.getInstance();
        new TimePickerDialog(mContext,
                new TimePickerDialog.OnTimeSetListener() {

                    @Override
                    public void onTimeSet(TimePicker arg0, int hourOfDay,
                            int minute) {
                        showToast(hourOfDay + ":" + minute);
                    }
                }, c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE), true)
                .show();
    }

    /**
     * 设置对话框的标题+图标+按钮
     * 
     * @param title
     */
    private void setButton(String title) {
        builder.setTitle(title).setIcon(R.drawable.ic_launcher)
                .setPositiveButton("好", new positiveListener())
                .setNeutralButton("中", new NeutralListener())
                .setNegativeButton("差", new NegativeListener());
        // .setCancelable(false);//设置点击空白处,不能消除该对话框
    }

    /**
     * @author:Jack Tony
     * @tips : 监听器
     * @date :2014-7-25
     */
    private class positiveListener implements DialogInterface.OnClickListener {
        @Override
        public void onClick(DialogInterface dialog, int which) {

            // dialog.dismiss();//设置对话框强制退出
            showToast("好");

        }
    }

    private class NeutralListener implements DialogInterface.OnClickListener {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            showToast("中");
        }
    }

    private class NegativeListener implements DialogInterface.OnClickListener {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            showToast("差");
        }
    }

    private void showToast(String msg) {
        Toast.makeText(mContext, msg, 0).show();
    }
}
复制代码
复制代码

Android自定义Dialog对话框的几种方法(精简版)

自定义对话框是经常使用的功能,我们常用的弹窗操作,除了使用popwindow就是使用dialog来实现,这两种组件都支持之定义布局和功能来满足我们个性化的需求,也可以不采用自定义而直接使用系统封装好的api来实现功能。今天简单总结下在使用dialog做弹窗功能的方法和会遇到的问题与解决方案。
方法一:直接使用系统的,不自定义布局和功能方式

/* @setIcon 设置对话框图标
* @setTitle 设置对话框标题
* @setMessage 设置对话框消息提示
*/
final AlertDialog.Builder normalDialog =
new AlertDialog.Builder(MainActivity.this);
normalDialog.setIcon(R.drawable.icon_dialog);
normalDialog.setTitle(“我是一个普通Dialog”)
normalDialog.setMessage(“你喜欢系统对话框吗?”);
normalDialog.setPositiveButton(“确定”,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//…To-do
}
});
normalDialog.setNegativeButton(“关闭”,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//…To-do
}
});

//如果想自定义三个按钮的对话框,可以把下面的方法注释打开
// normalDialog.setNeutralButton(“第三个按钮”,
// new DialogInterface.OnClickListener() {
// @Override
// public void onClick(DialogInterface dialog, int which) {
// // …To-do
// }
// });
// 显示
normalDialog.show();

方法二:采用自定义布局和功能方式

自定义对话框布局: high_opinion_dialog_layout.xml

<?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=”wrap_content”
android:paddingTop=”@dimen/dp_20″
android:paddingBottom=”@dimen/dp_10″
android:paddingLeft=”@dimen/dp_15″
android:paddingRight=”@dimen/dp_15″
android:orientation=”vertical”>

<TextView
android:text=”Rate US”
android:gravity=”center”
android:textSize=”@dimen/sp_18″
android:textColor=”@color/black”
android:layout_gravity=”center_horizontal”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content” />
<TextView
android:text=”We’re glad you’re enjoying using our app! Would you mind giving us a review?”
android:gravity=”center”
android:textSize=”@dimen/sp_12″
android:layout_marginTop=”@dimen/dp_5″
android:textColor=”@color/black”
android:layout_gravity=”center_horizontal”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content” />

<LinearLayout
android:layout_width=”match_parent”
android:layout_marginTop=”@dimen/dp_15″
android:layout_height=”@dimen/dp_37″>

<Button
android:id=”@+id/btn_cancel_high_opion”
android:layout_width=”0dp”
android:layout_height=”match_parent”
android:text=”Maybe later”
android:background=”@drawable/btn_cancer_high_opion_shape”
android:textColor=”@color/white”
android:layout_weight=”1″/>

<View
android:layout_width=”@dimen/dp_20″
android:layout_height=”match_parent”
/>
<Button
android:id=”@+id/btn_agree_high_opion”
android:layout_width=”0dp”
android:text=”Sure”
android:textColor=”@color/white”
android:background=”@drawable/btn_agree_high_opinion_shape”
android:layout_height=”match_parent”
android:layout_weight=”1″/>

</LinearLayout>

</LinearLayout>

然后在activity或者fragment中想要加点击弹出对话框的控件的监听事件中调用初始化下面方法

public class HomeActivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);

Button btn= findViewById(R.id.btn)
//点击按钮弹出对话框
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showDialog();
}
});

}

//初始化并弹出对话框方法
private void showDialog(){
View view = LayoutInflater.from(this).inflate(R.layout.high_opinion_dialog_layout,null,false);
final AlertDialog dialog = new AlertDialog.Builder(this).setView(view).create();

Button btn_cancel_high_opion = view.findViewById(R.id.btn_cancel_high_opion);
Button btn_agree_high_opion = view.findViewById(R.id.btn_agree_high_opion);

btn_cancel_high_opion.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferencesUnitls.setParam(getApplicationContext(),”HighOpinion”,”false”);
//… To-do
dialog.dismiss();
}
});

btn_agree_high_opion.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//… To-do
dialog.dismiss();
}
});

dialog.show();
//此处设置位置窗体大小,我这里设置为了手机屏幕宽度的3/4 注意一定要在show方法调用后再写设置窗口大小的代码,否则不起效果会
dialog.getWindow().setLayout((ScreenUtils.getScreenWidth(this)/4*3),LinearLayout.LayoutParams.WRAP_CONTENT);
}

}

此处附上ScreenUtils工具类代码

public class ScreenUtils {

/**
* 获取屏幕高度(px)
*/
public static int getScreenHeight(Context context) {
return context.getResources().getDisplayMetrics().heightPixels;
}
/**
* 获取屏幕宽度(px)
*/
public static int getScreenWidth(Context context) {
return context.getResources().getDisplayMetrics().widthPixels;
}

}

需要注意的问题总结:系统的dialog的宽度默认是固定的,即使你自定义布局的怎么修改宽高也不起作用,如果想修改弹出窗体大小,可以使用下面这段代码在调用dialog.show()方法之后来实现改变对话框的宽高的需求

//此处设置位置窗体大小,
dialog.getWindow().setLayout(width,height);

Android4.0的Alertdialog对话框,设置点击其他位置不消失

Android4.0以上AlertDialog,包括其他自定义的dialog,在触摸对话框边缘外部,对话框消失。

可以设置这么一条属性,当然必须先AlertDialog.Builder.create()之后才能调用这两个方法

方法一:

setCanceledOnTouchOutside(false);调用这个方法时,按对话框以外的地方不起作用。按返回键还起作用

方法二:

setCancelable(false);调用这个方法时,按对话框以外的地方不起作用。按返回键也不起作用

如果你需要自定义样式日期时间选择对话框控件,可以点击这里传送你过去

改变Android Dialog弹出后的Activity背景亮度:
在代码中修改.lp.alpha大小随自己要求设置

// 设置屏幕背景变暗
private void setScreenBgDarken() {
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.alpha = 0.5f;
lp.dimAmount = 0.5f;
getWindow().setAttributes(lp);
}
// 设置屏幕背景变亮
private void setScreenBgLight() {
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.alpha = 1.0f;
lp.dimAmount = 1.0f;
getWindow().setAttributes(lp);
}

如何控制弹窗弹出的位置:
一般都是在屏幕正中间弹出默认,但也可以控制从别的地方弹出,比如从底部弹出,可以这样写

View view = LayoutInflater.from(this).inflate(R.layout.send_dialog, null);
final Dialog dialog = new AlertDialog.Builder(this, R.style.home_dialog)
.setView(view)
.setCancelable(true)
.create();
dialog.show();

Window win = dialog.getWindow();
win.setGravity(Gravity.BOTTOM); // 这里控制弹出的位置
win.getDecorView().setPadding(0, 0, 0, 0);
WindowManager.LayoutParams lp = win.getAttributes();
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
dialog.getWindow().setBackgroundDrawable(null);
win.setAttributes(lp);

view.findViewById(R.id.cancle_dialog).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});

再补充一点爬坑的经验:
有时候会遇到定义dialog布局的时候出现加载出来的弹窗和自己布局里面定义的大小宽高不一致的效果,然后用dialog.getWindow().setLayout(width,height)方法怎么设置调节都不管用,我就遇到过一次,特别坑,后来发现了一点造成这种异常情况的原因:
出现问题时的dialog布局代码:

<?xml version=”1.0″ encoding=”utf-8″?>
<RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android”
android:layout_width=”@dimen/dp_310″
android:layout_height=”@dimen/dp_236″
android:background=”@drawable/wallpaper_downloadorsace_outside_shape”>

<RelativeLayout
android:id=”@+id/rl_close_dialog”
android:layout_width=”@dimen/dp_40″
android:layout_height=”@dimen/dp_40″>

<ImageView
android:id=”@+id/iv_close_dialog”
android:layout_width=”@dimen/dp_15″
android:layout_height=”@dimen/dp_15″
android:scaleType=”fitXY”
android:layout_marginLeft=”@dimen/dp_14″
android:layout_marginTop=”@dimen/dp_12″
android:src=”@drawable/icon_close” />

</RelativeLayout>

<RelativeLayout
android:layout_marginTop=”@dimen/dp_46″
android:layout_marginBottom=”@dimen/dp_35″
android:layout_centerInParent=”true”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”>

<LinearLayout
android:id=”@+id/ll_localsave_out”
android:layout_width=”@dimen/dp_215″
android:layout_height=”@dimen/dp_53″
android:layout_centerHorizontal=”true”
android:background=”@drawable/wallpaper_downloadorsace_shape”
android:gravity=”center”>

<LinearLayout
android:id=”@+id/ll_localsave”
android:background=”@drawable/local_save_water_selector”
android:clickable=”true”
android:gravity=”center”
android:layout_width=”match_parent”
android:layout_height=”match_parent”>
<!–android:background=”?android:attr/selectableItemBackground” 系统自带水波纹效果 –>

<ImageView
android:layout_width=”@dimen/dp_22″
android:layout_height=”@dimen/dp_28″
android:scaleType=”fitXY”
android:src=”@drawable/icon_phone” />

<com.blossom.ripple.widget.AvenirNextRegularTextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_marginLeft=”@dimen/dp_7″
android:text=”Local save”
android:textColor=”@color/white”
android:textSize=”@dimen/sp_17″ />

</LinearLayout>

</LinearLayout>

<LinearLayout
android:layout_alignParentBottom=”true”
android:layout_marginBottom=”@dimen/dp_45″
android:layout_width=”@dimen/dp_215″
android:layout_height=”@dimen/dp_53″
android:layout_centerHorizontal=”true”
android:background=”@drawable/wallpaper_downloadorsace_shape”
android:gravity=”center”>

<LinearLayout
android:id=”@+id/ll_setaswallpaper”
android:background=”@drawable/local_save_water_selector”
android:clickable=”true”
android:gravity=”center”
android:layout_width=”match_parent”
android:layout_height=”match_parent”>

<!–android:background=”?android:attr/selectableItemBackground” 系统自带水波纹效果 –>

<ImageView
android:layout_width=”@dimen/dp_28″
android:layout_height=”@dimen/dp_24″
android:scaleType=”fitXY”
android:src=”@drawable/icon_album” />

<com.blossom.ripple.widget.AvenirNextRegularTextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_marginLeft=”@dimen/dp_5″
android:text=”Set as wallpaper”
android:textColor=”@color/white”
android:textSize=”@dimen/sp_17″ />
</LinearLayout>

</LinearLayout>

</RelativeLayout>

</RelativeLayout>

运行效果如下图

%title插图%num

运行出来的效果很头痛,虽然我在布局代码里面写死了弹窗布局的宽高大小,然后想通过window的setlayout方法控制改变弹窗的大小,但无论如何都不行,后来仔细检查布局代码发现了猫腻,在一个子布局LinearLayout的标签下引用了一个android:layout_alignParentBottom=”true”的属性,然后稍微调整了下代码再次运行便解决了上面的问题。下面贴下修改后的正确代码,我在里面加了问题原因的注释还:

<?xml version=”1.0″ encoding=”utf-8″?>
<RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android”
android:layout_width=”@dimen/dp_310″
android:layout_height=”@dimen/dp_236″
android:background=”@drawable/wallpaper_downloadorsace_outside_shape”>

<RelativeLayout
android:id=”@+id/rl_close_dialog”
android:layout_width=”@dimen/dp_40″
android:layout_height=”@dimen/dp_40″>

<ImageView
android:id=”@+id/iv_close_dialog”
android:layout_width=”@dimen/dp_15″
android:layout_height=”@dimen/dp_15″
android:scaleType=”fitXY”
android:layout_marginLeft=”@dimen/dp_14″
android:layout_marginTop=”@dimen/dp_12″
android:src=”@drawable/icon_close” />

</RelativeLayout>

<RelativeLayout
android:layout_marginTop=”@dimen/dp_46″
android:layout_marginBottom=”@dimen/dp_35″
android:layout_centerInParent=”true”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”>

<LinearLayout
android:id=”@+id/ll_localsave_out”
android:layout_width=”@dimen/dp_215″
android:layout_height=”@dimen/dp_53″
android:layout_centerHorizontal=”true”
android:background=”@drawable/wallpaper_downloadorsace_shape”
android:gravity=”center”>

<LinearLayout
android:id=”@+id/ll_localsave”
android:background=”@drawable/local_save_water_selector”
android:clickable=”true”
android:gravity=”center”
android:layout_width=”match_parent”
android:layout_height=”match_parent”>
<!–android:background=”?android:attr/selectableItemBackground” 系统自带水波纹效果 –>

<ImageView
android:layout_width=”@dimen/dp_22″
android:layout_height=”@dimen/dp_28″
android:scaleType=”fitXY”
android:src=”@drawable/icon_phone” />

<com.blossom.ripple.widget.AvenirNextRegularTextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_marginLeft=”@dimen/dp_7″
android:text=”Local save”
android:textColor=”@color/white”
android:textSize=”@dimen/sp_17″ />

</LinearLayout>

</LinearLayout>

<LinearLayout
android:layout_width=”@dimen/dp_215″
android:layout_height=”@dimen/dp_53″
android:layout_centerHorizontal=”true”
android:layout_below=”@+id/ll_localsave_out”
android:layout_marginTop=”@dimen/dp_30″
android:background=”@drawable/wallpaper_downloadorsace_shape”
android:gravity=”center”>
<!–android:layout_alignParentBottom=”true” 这个属性曾经导致过弹窗特别大,会挨着屏幕顶部和底部–>

<LinearLayout
android:id=”@+id/ll_setaswallpaper”
android:background=”@drawable/local_save_water_selector”
android:clickable=”true”
android:gravity=”center”
android:layout_width=”match_parent”
android:layout_height=”match_parent”>

<!–android:background=”?android:attr/selectableItemBackground” 系统自带水波纹效果 –>

<ImageView
android:layout_width=”@dimen/dp_28″
android:layout_height=”@dimen/dp_24″
android:scaleType=”fitXY”
android:src=”@drawable/icon_album” />

<com.blossom.ripple.widget.AvenirNextRegularTextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_marginLeft=”@dimen/dp_5″
android:text=”Set as wallpaper”
android:textColor=”@color/white”
android:textSize=”@dimen/sp_17″ />
</LinearLayout>

</LinearLayout>
</RelativeLayout>

</RelativeLayout>

问题解决后感觉又积累了一点弹窗方面的经验,收获满满的,赶紧记录下来吧,省的以后忘记了再犯同样的错误!

还有一个关于弹窗容易遇到的异常:Unable to add window – token android.os.BinderProxy@d80e90e is not valid; is your activity running?android.view.ViewRootImpl.setView(ViewRootImpl.java:688)

该异常表示不能添加窗口,通常是所要依附的view已经不存在导致的。
[解决方案]:Dialog&AlertDialog,WindowManager不能正确使用时,经常会报出该异常,原因比较多,几个常见的场景如下:
1.上一个页面没有destroy的时候,之前的Activity已经接收到了广播。如果此时之前的Activity进行UI层面的操作处理,就会造成crash。UI层面的刷新,一定要注意时机,建议使用set_result来代替广播的形式进行刷新操作,避免使用广播的方式,代码不直观且容易出错。
2.Dialog在Actitivty退出后弹出。在Dialog调用show方法进行显示时,必须要有一个Activity作为窗口的载体,如果Activity被销毁,那么导致Dialog的窗口载体找不到。建议在Dialog调用show方法之前先判断Activity是否已经被销毁。
3.Service&Application弹出对话框或WindowManager添加view时,没有设置window type为TYPE_SYSTEM_ALERT。需要在调用dialog.show()方法前添加dialog.getWindow().SetType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT)。
4.6.0的系统上, (非定制 rom 行为)若没有给予悬浮窗权限, 会弹出该问题, 可以通过Settings.canDrawOverlays来判断是否有该权限.
5.某些不稳定的MIUI系统bug引起的权限问题,系统把Toast也当成了系统级弹窗,android6.0的系统Dialog弹窗需要用户手动授权,若果app没有加入SYSTEM_ALERT_WINDOW权限就会报这个错。需要加入给app加系统Dialog弹窗权限,并动态申请权限,不满足*条会出现没权限闪退,不满足第二条会出现没有Toast的情况。

今天的分享先到这里,后续会不断添加和更新更多更好的学习资料,如果你喜欢可以关注加好友,互相探讨学习,我们互相学习一起成长!

自定义Dialog或者AlertDialog在部分手机上margin失效的问题

*近项目中用到的自定义布局的Dialog比较多,我把宽度写死以后,在一些手机上是没有问题的,但是部分手机上(比如oppo手机)横向的margin不起作用,困扰了很长时间,今天有时间解决了一下。

原来不管是AlertDialog还是Dialog,因为AlertDialog集成于Dialog,他们本身的宽度都是与屏幕的宽度留有距离的,即我们在写自定义布局的时候不用给他设置成Dialog的样式,宽度match_parent,高度wrap_content即可,如果使用的是AlertDialog,ok,就不用管了,但是如果直接用的Dialog还是加上以下代码吧!

Window window=dialog.getWindow();
WindowManager.LayoutParams lp=window.getAttributes();
lp.width=WindowManager.LayoutParams.MATCH_PARENT;
lp.height=WindowManager.LayoutParams.WRAP_CONTENT;
window.setGravity(Gravity.CENTER);
window.setAttributes(lp);
总结:在部分手机上出现边距不起作用的应该是本来Dialog自身与屏幕宽度有边距,而我设置的宽度超出了它本身的宽度,导致margin不起作用。困惑了很久的问题终于豁然开朗了☺。

Android:Dialog显示图片

下看一下效果图
%title插图%num %title插图%num

点击TextView弹出Dialog
点击图片Dialog消失

先看一下MainActivity

package com.cxy.demo;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;

import startdialogimageview.qq986945193.dialogdemo.R;

/**
*程序功能:Dialog显示图片
*/
public class MainActivity extends Activity {

Dialog dia;
private TextView tv;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

tv = (TextView) findViewById(R.id.tv);
tv.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
dia.show();
}
});

Context context = MainActivity.this;
dia = new Dialog(context, R.style.edit_AlertDialog_style);
dia.setContentView(R.layout.activity_start_dialog);
ImageView imageView = (ImageView) dia.findViewById(R.id.start_img);
imageView.setBackgroundResource(R.mipmap.iv_android);
//选择true的话点击其他地方可以使dialog消失,为false的话不会消失
dia.setCanceledOnTouchOutside(true); // Sets whether this dialog is
Window w = dia.getWindow();
WindowManager.LayoutParams lp = w.getAttributes();
lp.x = 0;
lp.y = 40;
dia.onWindowAttributesChanged(lp);
imageView.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View view) {
dia.dismiss();
}
});
}

}

用到的style

<style name=”edit_AlertDialog_style” parent=”@android:style/Theme.Dialog”>
<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:background”>@android:color/transparent</item>
<item name=”android:backgroundDimEnabled”>true</item>
<!– 是否使用背景半透明 –>
</style>

布局文件的话就不上传了,比较简单。

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速