Dialog与PopWindow与DialogFragment

Dialog style解析(通俗理解)


  1. 如果dialog的style继承了系统样式,比如parent="@android:style/Theme.Dialog"或者parent="Theme.AppCompat.Light.Dialog",那么写item的时候name后面就不用带android,类似这样 <item name="windowActionBar">false</item>,但是如果不继承的话就需要强制带上android:类似这样<item name="android:windowActionBar">false</item>
  2. 想要dialog全屏需要用代码设置dialog的宽度,试过<item name="android:windowFullscreen">true</item>,但是没什么作用,所以还需要手动设置,Window window = customDialog.getWindow();
    WindowManager.LayoutParams attributes = window.getAttributes();
    attributes.width = getResources().getDisplayMetrics().widthPixels;
    window.setAttributes(attributes);
    其他固定宽度直接在布局文件里设置就行。
  3. 一般需要设置的属性有
    <item name="android:windowActionBar">false</item> 一般为false
    <item name="android:windowNoTitle">true</item> 一般为true
    <item name="android:windowFrame">@null</item> 一般为@null
    <item name="android:windowFullscreen">true</item> 好像没什么作用
    <item name="android:windowIsTranslucent">false</item> 是否半透明,好像没什么作用
    <item name="android:windowIsFloating">true</item> 一般为true,否则就会像activity一样
    <item name="android:background">#00000000</item>
    <item name="android:windowBackground">@color/transparent</item>
    <item name="android:windowCloseOnTouchOutside">true</item> 设置点击外部是否会dismiss
    <item name="android:backgroundDimEnabled">false</item> 设置是否需要透明黑背景,true表示有,false表示没有
  4. 因为上面背景都设置为了透明,所以写布局的时候需要显式的设置背景颜色
  5. dialog默认是居中的,如果想让其居于底部需要在代码里设置dialog.getWindow().setGravity(Gravity.BOTTOM);

PopWindow 嵌套ListView


我写该popWindow工具类主要是项目中如果用到多次的话,将其封装,每次都能直接使用,比较方便,而且格式能够统一

1.首先是布局文件,比较简单,就一个ListView

<?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:orientation="vertical"
              android:background="@drawable/pop_back"
    >

    <ListView
        android:id="@+id/pop_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:divider="@color/light_gray"
        android:dividerHeight="1px"
        android:listSelector="@color/transparent"
        android:scrollbars="none"
        />
</LinearLayout>

2.其次是ListView里面需要用的Java Bean

public class PopStringItem {
    private String id;
    private int icon;
    private String name;

    public PopStringItem(String id,int icon, String name) {
        this.id = id;
        this.icon = icon;
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getIcon() {
        return icon;
    }

    public void setIcon(int icon) {
        this.icon = icon;
    }
}

3.然后是popWindow的实现代码

public class ListPopWindow extends PopupWindow implements View.OnKeyListener {
    private List<PopStringItem> itemList;
    private LayoutInflater inflater;
    private PopListItemClickListener listItemClickListener;

    private Window window;
    private final WindowManager.LayoutParams params;

    public ListPopWindow(Context context, List<PopStringItem> items, PopListItemClickListener listItemClickListener) {
        super(context);
        init(context);
        window = ((Activity) context).getWindow();
        params = window.getAttributes();

        this.itemList = items;
        this.listItemClickListener = listItemClickListener;
        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = inflater.inflate(R.layout.list_pop_window, null);
        setContentView(view);
        ListView listView = (ListView) view.findViewById(R.id.pop_list);
        if (items.size() == 1) {
            listView.setDividerHeight(0);
        }
        MyAdapter adapter = new MyAdapter();
        listView.setAdapter(adapter);
        listView.setOnKeyListener(this);
        listView.setOnItemClickListener(adapter);
    }

    private void init(Context context) {
        int w = context.getResources().getDisplayMetrics().widthPixels;
        setWidth(w / 3);  //需要显示设置宽高度
        setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
        setFocusable(true);//设置popWindow是否具有获取焦点的能力,默认为false,一般来讲作用不大,但如果里面包含EditText等需要获取焦点的控件必须设置为true
        setOutsideTouchable(true);//设置点击外部区域popWindow是否会消失
       setBackgroundDrawable(new BitmapDrawable());  //设置popWindow的背景,只有加了该属性之后,setOutsideTouchable才会起作用,而且加了它之后,popWindow对手机的返回键才有响应,点击返回按钮,关闭popWindow,否则就会关闭popWindow所在的Activity
       update();
    }

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        dismiss();
        return true;
    }

    @Override
    public void showAsDropDown(View anchor) {
        params.alpha = 0.5f;  //如果popWindow显示的时候想让window背景变透明,就需要这样做
        window.setAttributes(params);
        super.showAsDropDown(anchor);
    }

    @Override
    public void showAsDropDown(View anchor, int xoff, int yoff) {
        params.alpha = 0.5f;
        window.setAttributes(params);
        super.showAsDropDown(anchor, xoff, yoff);
    }

    @Override
    public void showAsDropDown(View anchor, int xoff, int yoff, int gravity) {
        params.alpha = 0.5f;
        window.setAttributes(params);
        super.showAsDropDown(anchor, xoff, yoff, gravity);
    }

    @Override
    public void dismiss() {
        params.alpha = 1f;  //设置回来
        window.setAttributes(params);
        super.dismiss();
    }

    class MyAdapter extends BaseAdapter implements AdapterView.OnItemClickListener {

        @Override
        public int getCount() {
            int ret = 0;
            if (itemList != null) {
                ret = itemList.size();
            }
            return ret;
        }

        @Override
        public PopStringItem getItem(int position) {
            return itemList.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            PopStringItem item = getItem(position);
            ViewHolder holder = null;
            if (convertView == null) {
                convertView = inflater.inflate(R.layout.item_pop_list, parent, false);
                holder = new ViewHolder();
                holder.image = (ImageView) convertView.findViewById(R.id.image);
                holder.text = (TextView) convertView.findViewById(R.id.text);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            int icon = item.getIcon();
            if (icon == 0) {
                holder.image.setVisibility(View.GONE);
            } else {
                holder.image.setVisibility(View.VISIBLE);
                holder.image.setImageResource(icon);
            }
            holder.text.setText(item.getName());
            return convertView;
        }

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            PopStringItem item = getItem(position);
            if (listItemClickListener != null) {
                listItemClickListener.onClick(item);
            }
        }

        class ViewHolder {
            ImageView image;
            TextView text;
        }
    }

    //一个回调接口,交给使用PopWindow的Activity来处理
    public interface PopListItemClickListener {
        void onClick(PopStringItem item);
    }
}

4.popWindow的使用

//显示
 if (popupWindow == null) {
                popupWindow = new ListPopWindow(context, items, this);//items要提前赋值,this表示该类实现上面的回调点击事件
            }
   popupWindow.showAsDropDown();//需要设置参数
//点击事件的回调
 @Override
    public void onClick(PopStringItem item) {
        popupWindow.dismiss();
        if (item.getId().equals("")) {
            //根据id判断点击哪个item,进行事件处理
        }
    }

DialogFragment

比Dialog优势,具有生命周期,比如旋转屏幕的时候,activity重建,dialog就不会重新创建,由于不是正常销毁的,会造成内存泄漏,而DialogFragment就会重新创建。

使用方法:
1.如果已经有存在的dialog 就重写onCreateDialog方法,创建已经存在的dialog
2.重写onCreateView直接创建,跟fragment创建一样
但是需要setStyle
对于完全需要全屏的DialogFragment

@Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(Window.FEATURE_NO_TITLE, R.style.DialogFullscreenTransparent);
<style name="DialogFullscreenTransparent" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">match_parent</item>
        <item name="android:windowBackground">@android:color/transparent</item>
    </style>

@Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//            the window must be drawing the system bar backgrounds with FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS and FLAG_TRANSLUCENT_STATUS must not be set
            getDialog().getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            getDialog().getWindow().setStatusBarColor(getStatusBarColor());
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            //5.0及以上,不设置透明状态栏,设置会有半透明阴影
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.setStatusBarColor(color);
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            if (isAddView) {
                View statusBarView = new View(window.getContext());
                LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                        getStatusBarHeight(window.getContext()));
                statusBarView.setLayoutParams(params);
                statusBarView.setBackgroundColor(color);
                ViewGroup decorView = (ViewGroup) window.getDecorView();
                decorView.addView(statusBarView);
            }
            ViewGroup contentView = (ViewGroup) window.findViewById(android.R.id.content);
            View rootView = contentView.getChildAt(0);
            if (rootView instanceof ViewGroup) {
                rootView.setFitsSystemWindows(true);
            }
        }
        }
    }

对于不需要全屏的

 @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(Window.FEATURE_NO_TITLE, R.style.CustomCenterDialog);
    }

    @Override
    public void onStart() {
        super.onStart();
        Window window = getDialog().getWindow();
        if (window != null) {
            window.setLayout((int) getResources().getDimension(R.dimen.dimen_249_dip), WindowManager.LayoutParams.WRAP_CONTENT);  //必须手动指定宽高,布局写死100dp也是不起作用的
        }
        getDialog().setCanceledOnTouchOutside(true);
    }
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33666539/article/details/52313131
文章标签: Diaog PopWindow
个人分类: Android
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭