自定义dialog

重写样式、重写show方法解决宽度高度无法填充的问题

@Override
    public void show() {
        super.show();
        /**
         * 设置宽度全屏,放在show后面
         */
        LayoutParams layoutParams = getWindow().getAttributes();
        layoutParams.gravity=Gravity.BOTTOM;
        layoutParams.width= LayoutParams.MATCH_PARENT;
        layoutParams.height= LayoutParams.WRAP_CONTENT;
        getWindow().getDecorView().setPadding(0, 0, 0, 0);
        getWindow().setAttributes(layoutParams);

    }
dialog去标题
可以用主题去标题,只要有
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>

主题有这两个属性的,都可以,比如
android.R.style.Theme_DeviceDefault_Light_Dialog_NoActionBar主题

或者
这个方法多次调用会报错requestFeature() must be called before adding content
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
去背景
利用主题去背景
<item name="windowBackground">@color/transparent</item>
<item name="windowBackground">@null</item>

利用代码去背景
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));  // 有白色背景,加这句代码
或者
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);//去背景
圆角矩形
对话框布局使用shape
shape的corners设置圆角,可以分矩形的四个角分别设置圆角
如:<corners android:radius="10dp" />
注:如果布局使用了这个shape,最好再设置一下margin或者padding,不然有可能被其内容覆盖而导致圆角设置失败,因为布局里面的内容如果有设置过背景的话,就会被覆盖
解决方案:在代码中设置圆角背景
Window window = mDialog.getWindow();
        if (window!=null){  window.setBackgroundDrawableResource(R.drawable.white_bg_rectangle_circle_angle);
        }


        WindowManager.LayoutParams layoutParams = getWindow().getAttributes();

        Point point = new Point();
        getWindow().getWindowManager().getDefaultDisplay().getSize(point);获取屏幕宽度
        //layoutParams.gravity = Gravity.BOTTOM;设置dialog的位置 按需设置
        layoutParams.width = point.x * 9 / 10;
        layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
        //getWindow().getDecorView().setPadding(0, 0, 0, 0);按需设置
        getWindow().setAttributes(layoutParams);
取消点击消失
       if (mDialog == null) {  
            mDialog = new MyDialog(getActivity());  
            mDialog.setCanceledOnTouchOutside(false);//点击外部是否可取消
            mDialog.setCancelable(false);  //点击返回键是否可取消
        }  
java.lang.IllegalArgumentException
该异常表示view没有添加到窗口管理器,通常是我们dismiss对话框的时候,activity已经不存在了,建议不要在非UI线程操作对话框。
[解决方案]:常发生这类Exception的情形都是,有一个费时的线程操作,需要显示一个Dialog,在任务开始的时候显示一个对话框,然后当任务完成了在Dismiss对话框,如果在此期间如果Activity因为某种原因被杀掉且又重新启动了,那么当dialog调用dismiss的时候WindowManager检查发现Dialog所属的Activity已经不存在,所以会报错。
要避免此类Exception,就要正确的使用对话框,也要正确的使用线程:
1.不要在非UI线程中使用对话框创建,显示和取消对话框;
2.尽量少用单独线程,出发是真正的耗时操作采用线程,线程也不要直接用Java式的匿名线程,除非是那种单纯的操作,操作完成不需要做其他事情的。
3.如果是在fragment中发起异步网络的回调中进行dialog的操作,那么在操作之前,需要判断 isAdd( ),避免fragment被回收了但是还要求dialog去dismiss
4.对Dialog提前进行关闭
//在Activity 中
if (!isDestroyed()&&!isFinishing()){
    mDialog.show();
}
//在fragment中
if (isAdded()){
    myProgressDialog.dismiss();
}

android.view.WindowManager$BadTokenException: Unable to add window — token android.os.BinderProxy@41791b20 is not valid; is your activity running?

产生原因:

dialog要附属的activity或者view还没创建或者已经销毁

传入的context是getApplicationContext,applicationContext是整个APP的环境,不代表任何activity或者view,dialog不知道附属在哪里,所以报错

。。。。。。

解决:

在正确的时间弹出dialog。传入activity的或其他正确的context,他才知道要附属在谁的身上。

使用

<!-- 自定义优惠券 dialog -->
<style name="youhuiquan_dialog" parent="android:style/Theme.Dialog">
    <!--<item name="android:windowFrame">@null</item>-->
    <item name="android:windowNoTitle">true</item>
    <!--<item name="android:windowBackground">@drawable/white_bg_rectangle_shape</item>-->
    <!--<item name="android:windowBackground">@color/white</item>-->
    <!--<item name="android:windowIsFloating">true</item>-->
    <item name="android:windowIsTranslucent">false</item>
    <!--<item name="android:backgroundDimEnabled">true</item>-->
</style>
MyNumStyleDialog myNumStyleDialog = new MyNumStyleDialog(this);
myNumStyleDialog.show();


public class MyNumStyleDialog extends Dialog implements OnItemClickListener {
    private static String[] TITLES = new String[] { "半透明", "活力橙", "卫士蓝", "金属灰",
    "苹果绿" };
    private static int[] RESIDS = new int[] {
        R.drawable.myshape_half_transparent, R.drawable.myshape_orange,
        R.drawable.myshape_blue, R.drawable.myshape_gray,
        R.drawable.myshape_green };

    private Context mContext;
    private ListView mListView;
    private List<MyStyleBean> mListDatas;
    private MyLocNumStyleAdapter adapter;

    public MyNumStyleDialog(Context context, int theme) {
        super(context, R.style.mydlg_style);
        // TODO Auto-generated constructor stub
        this.mContext = context;
        Window window = getWindow();
        LayoutParams params = window.getAttributes();
        params.gravity=Gravity.BOTTOM;
    }

    public MyNumStyleDialog(Context context) {
        this(context,0);
        // TODO Auto-generated constructor stub
    }
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mydialog_number_style);
        initData();
        mListView = (ListView) findViewById(R.id.lv_my_number_style);
        mListView.setOnItemClickListener(this);
        adapter = new MyLocNumStyleAdapter();
        mListView.setAdapter(adapter);
    }
    
    private void initData() {
        mListDatas = new ArrayList<MyStyleBean>();
        for (int i = 0; i < TITLES.length; i++) {
            MyStyleBean myStyleBean = new MyStyleBean();
            myStyleBean.title=TITLES[i];
            myStyleBean.resId=RESIDS[i];
            mListDatas.add(myStyleBean);
        }
    }

    private class MyLocNumStyleAdapter extends BaseAdapter{

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return mListDatas.size();
        }

        @Override
        public Object getItem(int position) {
            // TODO Auto-generated method stub
            return mListDatas.get(position);
        }

        @Override
        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            ViewHolder holder = null;
            if(convertView==null){
                convertView=View.inflate(mContext, R.layout.myitem_number_style, null);
                holder = new ViewHolder();
                holder.ivColor=(ImageView) convertView.findViewById(R.id.iv_my_number_style);
                holder.tvTitle=(TextView) convertView.findViewById(R.id.tv_my_number_style_title);
                holder.ivSelect=(ImageView) convertView.findViewById(R.id.iv_my_number_style_selected);
                convertView.setTag(holder);
            }else{
                holder=(ViewHolder) convertView.getTag();
            }
            MyStyleBean myStyleBean = (MyStyleBean) getItem(position);
            holder.ivColor.setImageResource(myStyleBean.resId);
            holder.tvTitle.setText(myStyleBean.title);
            int numberStyle = MySharedPreferencesUtils.getNumberStyle(mContext, 0);
            if(numberStyle==position){
                holder.ivSelect.setVisibility(View.VISIBLE);
            }else{
                holder.ivSelect.setVisibility(View.GONE);
            }
            
            
            return convertView;
        }
        
    }
    
    static class ViewHolder{
        ImageView ivColor;
        TextView tvTitle;
        ImageView ivSelect;
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
            long id) {
        // TODO Auto-generated method stub
        MySharedPreferencesUtils.setNumberStyle(mContext, position);
        adapter.notifyDataSetChanged();
        
    }

}

R.layout.mydialog_number_style

<?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="280dp"
    android:orientation="vertical" >
    
    <TextView 
        style="@style/MyTextNormal"
        android:background="#66000000"
        android:textColor="@color/white"
        android:padding="8dp"
        android:text="选择归属地样式"/>
    <ListView 
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/lv_my_number_style"></ListView>
    
</LinearLayout>
public class MyStyleBean {

    public int resId;
    public String title;
}
    原文作者:喂_balabala
    原文地址: https://www.jianshu.com/p/b3b46259f056
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞