重写样式、重写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;
}