我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Android之 弹框总结

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Android之 弹框总结

一 简介

1 弹框即浮与页面之上的窗口,如键盘弹框,吐司弹框,确认弹框,下拉选择框,应用悬浮框等

2 弹框控件也很多,比如常用的Spinner,Dialog,Toast,PopWindow等,以及新增的SnackBar,DialogFragment等。

二 Spinner下拉选择使用

1 Spinner根Listview,Gridview等是同一时代的产物,所以用法也根它们差不多,主要用到BaseAdapter来加载数据源

用系统提供的Adapter,使用简单,但样式固定,数据模型固定,只能是String类型。

效果图

布局文件,添加Spinner控件

java文件设置数据源和是配置

private void initSystemAdapter(){        //设置数据源        List list = new ArrayList();        list.add("苹果");        list.add("香蕉");        list.add("橘子");        list.add("香蕉");        //设置系统适配器        ArrayAdapter adapter=new ArrayAdapter(this, android.R.layout.simple_spinner_item,list);        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);        spinner.setAdapter(adapter);        //设置弹出偏移位置        spinner.setDropDownVerticalOffset(40);        //点击监听        spinner.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView parent, View view, int position, long id) {                Toast.makeText(SpinnerActivity.this, list.get(position), Toast.LENGTH_SHORT).show();            }        });    }

注意:系统Adapter样式固定,有以下几种

simple_spinner_dropdown_item(列表-间距较高比较好看)
simple_spinner_item(列表-间距紧凑不好看)
simple_list_item_checked(复选框-选中的有绿沟)
simple_list_item_single_choice (单选按钮)

3 自定义适配器,灵活度高,可以设置任何类型的数据源和样式

效果图

自定义条目布局 item_fruit_list.xml

    

自定义数据源 FruitBean.java

public class FruitBean {    public String name;    public FruitBean(String name) {        this.name = name;    }}

自定义适配器CustomerAdapter.java

public class CustomerAdapter extends BaseAdapter {    private Context mContext;    private List mList;    public CustomerAdapter(Context mContext, List mList) {        this.mContext = mContext;        this.mList = mList;    }    @Override    public int getCount() {        return mList.size();    }    @Override    public Object getItem(int position) {        return mList.get(position);    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        ViewHolder holder = null;        if (convertView == null) {            holder = new ViewHolder();            convertView = LayoutInflater.from(mContext).inflate(R.layout.item_fruit_list, null);            holder.tvName = (TextView) convertView.findViewById(R.id.tv_name);            convertView.setTag(holder);        } else {            holder = (ViewHolder) convertView.getTag();        }        holder.tvName.setText(mList.get(position).name);        return convertView;    }    class ViewHolder {        public TextView tvName;    }}

spinner配置自定义适配器

private void initCustomerAdapter(){//设置数据源List list = new ArrayList<>();list.add(new FruitBean("苹果"));list.add(new FruitBean("香蕉"));list.add(new FruitBean("橘子"));list.add(new FruitBean("香蕉"));//设置系统适配器CustomerAdapter customerAdapter=new CustomerAdapter(this,list);spinner.setAdapter(customerAdapter);//设置弹出偏移位置spinner.setDropDownVerticalOffset(40);}

三 Dialog的使用

1 Dialog是除了Toast之外,用的最频繁的弹框,各种加载框,提示框,选择框也大都用的Dialog

2 Dialog支持任意布局,以及弹出位置,所以非常灵活。

2 示例效果图

3 创建自定义Dialog

dialog_confirm.xm

设置dialog样式custom_dialog.style,半透明度,标题,背景,弹出动画等等

需要继承系统Dialog父类

public class ConfirmDialog extends Dialog {    private Context context;    private TextView tvTitle;    private TextView tvContent;    private TextView tvCancel;    private TextView tvSure;    private String title, content, cancelString, sureString;    public interface OnViewClickLiatener {        void sureClick();        void cancelClick();    }    public OnViewClickLiatener onViewClickLiatener;    public void setOnViewClickLiatener(OnViewClickLiatener onViewClickLiatener) {        this.onViewClickLiatener = onViewClickLiatener;    }    public ConfirmDialog(Context context) {        this(context, R.style.custom_dialog);    }    public ConfirmDialog(Context context, int themeResId) {        super(context, themeResId);        this.context = context;    }    public ConfirmDialog(Context context, int themeResId, String title, String content, String cancelString, String sureString) {        super(context, themeResId);        this.context = context;        this.title = title;        this.content = content;        this.cancelString = cancelString;        this.sureString = sureString;    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.dialog_confirm);        setCanceledOnTouchOutside(true);        WindowManager.LayoutParams params = getWindow().getAttributes();        params.width = (int) (ScreenUtils.getScreenWidth((Activity) context) * 0.8f);        params.height = ViewGroup.LayoutParams.WRAP_CONTENT;        getWindow().setGravity(Gravity.CENTER);        getWindow().setAttributes(params);        getWindow().setBackgroundDrawableResource(R.color.trans);        initView();        setData();    }    public void initView() {        tvTitle = (TextView) findViewById(R.id.tv_title);        tvContent = (TextView) findViewById(R.id.tv_content);        tvCancel = (TextView) findViewById(R.id.tv_cancel);        tvSure = (TextView) findViewById(R.id.tv_sure);    }    public void setData() {        if (!TextUtils.isEmpty(title)) {            tvTitle.setText(title);        }        if (!TextUtils.isEmpty(content)) {            tvContent.setText(content);        }        if (!TextUtils.isEmpty(cancelString)) {            tvCancel.setText(cancelString);        }        if (!TextUtils.isEmpty(sureString)) {            tvSure.setText(sureString);        }        tvCancel.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                dismiss();                if (onViewClickLiatener != null) {                    onViewClickLiatener.cancelClick();                }            }        });        tvSure.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                dismiss();                if (onViewClickLiatener != null) {                    onViewClickLiatener.sureClick();                }            }        });    }    @Override    public void dismiss() {        super.dismiss();    }}

使用

     ConfirmDialog showCancelDialog;    public void showCancelDialog(String reportOrderNo, String storeCode) {        if (showCancelDialog == null) {            showCancelDialog = new ConfirmDialog(activity, "取消提醒", "取消后将不再对已添加的内容进行保存", "暂不取消", "确认取消");            showCancelDialog.setOnViewClickLiatener(new ConfirmDialog.OnViewClickLiatener() {                @Override                public void sureClick() {                    if (TextUtils.isEmpty(reportOrderNo)) {                        activity.finish();                    } else {                        httpReportOrderCancel(reportOrderNo, storeCode);                    }                }                @Override                public void cancelClick() {                }            });        }        if (!showCancelDialog.isShowing()) {            showCancelDialog.show();        }    }

4 设置认为位置的dialog,如下效果图在屏幕右上角,并且有偏移距离

 根正常Dialog使用一样,不过在构造函数里面需要传一个view,即对于那个view弹出,通过获取view在屏幕的位置,来设置Dialog的偏移位置。如下示例

public class OtherUserMainMoreDialog extends Dialog {    private DialogViewListener listener;    private Activity mContext;    private View locationView;    private LinearLayout llRemarks;    private LinearLayout llPullBlack;    private LinearLayout llDeleteFriend;    public interface DialogViewListener {        void remarksClick();        void pullBlackClick();        void deleteFriend();    }    public OtherUserMainMoreDialog(Activity context) {        super(context);        mContext = context;    }    public void setDialogViewListener(DialogViewListener listener) {        this.listener = listener;    }    public OtherUserMainMoreDialog(Activity context, int themeResId, View locationView) {        super(context, themeResId);        mContext = context;        this.locationView = locationView;    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        View view = LayoutInflater.from(mContext).inflate(R.layout.dialog_other_more, null);        setContentView(view);        //设置Dialog点击外部消失        setCanceledOnTouchOutside(true);        setCancelable(true);        //获取控件 textview 的绝对坐标,( y 轴坐标是控件上部到屏幕最顶部(不包括控件本身))        //location [0] 为x绝对坐标;location [1] 为y绝对坐标        int[] location = new int[2];        locationView.getLocationInWindow(location); //获取在当前窗体内的绝对坐标        //获取当前Activity所在的窗体        Window window = getWindow();        WindowManager.LayoutParams wlp = window.getAttributes();        //获取通知栏高度  重要的在这,获取到通知栏高度        int notificationBar = Resources.getSystem().getDimensionPixelSize(                Resources.getSystem().getIdentifier("status_bar_height", "dimen", "android"));        wlp.x = location[0];//对 dialog 设置 x 轴坐标        wlp.y = location[1] + locationView.getHeight() - notificationBar - 15; //对dialog设置y轴坐标        wlp.gravity = Gravity.TOP;        wlp.width = WindowManager.LayoutParams.MATCH_PARENT;        window.setAttributes(wlp);        llRemarks = (LinearLayout) findViewById(R.id.ll_remarks);        llPullBlack = (LinearLayout) findViewById(R.id.ll_pull_black);        llDeleteFriend = (LinearLayout) findViewById(R.id.ll_delete_friend);        llPullBlack.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                if (listener != null) {                    listener.pullBlackClick();                }                cancel();            }        });        llRemarks.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                if (listener != null) {                    listener.remarksClick();                }                cancel();            }        });        llDeleteFriend.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                if (listener != null) {                    listener.deleteFriend();                }                cancel();            }        });    }}

5 DIalog使用注意:

由于DIalog必须依赖与一个Activty,如果Activity意外销毁,那Dialog再去弹出或者消息就会找不到该Activity,从而发生崩溃。解决方法如下:

  • 把Activity设置为弱引用,以便Activity销毁时,持有Activity的对象能够及时回收。
  • 在Dialog弹出消息前判断是否Activity存活,从而保证安全弹出或者消息

如下处理:

@Overridepublic void dismiss() {if (context == null || ((Activity) context).isDestroyed() || ((Activity) context).isFinishing()) {return;}super.dismiss();}@Overridepublic void show() {if (context == null || ((Activity) context).isDestroyed() || ((Activity) context).isFinishing()) {return;}super.show();}

四,Toast的使用

1 最简单使用,调用系统api

Toast.makeText(context, "提示消息", Toast.LENGTH_SHORT).show();

2 设置Toast的位置,顶部,中间,底部等位置

Toast toast = Toast.makeText(context, "提示消息", Toast.LENGTH_SHORT);toast.setGravity(Gravity.TOP, 0, 0);toast.show();

3 控制短时间内弹出频率

 private static String oldMsg;    protected static Toast toast = null;    private static long oneTime = 0;    private static long twoTime = 0;    public static void showToast(Context context, String s, int gravity, int offX, int offY) {        if (toast == null) {            toast = Toast.makeText(context, s, Toast.LENGTH_SHORT);            toast.setGravity(gravity, offX, offY);            toast.show();            oneTime = System.currentTimeMillis();        } else {            twoTime = System.currentTimeMillis();            if (s.equals(oldMsg)) {                if (twoTime - oneTime > Toast.LENGTH_SHORT) {                    toast.show();                }            } else {                oldMsg = s;                toast.setText(s);                toast.show();            }        }        oneTime = twoTime;    }

4 自定义Toast布局样式

 private static TextView textView;        public static void showPicToast(Context context, String text) {        if (toast == null) { // 1. 创建前 2.消失后toast为null            // 获取打气筒            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);            //创建视图            View view = inflater.inflate(R.layout.toast_bg, null);            textView = (TextView) view.findViewById(R.id.tv_toast_text);            //创建土司            toast = new Toast(context);            //设置居中方式  默认在底部            //toast.setGravity(Gravity.CENTER, 0, 0);//如果不设置剧中方式,使用系统默认的吐司位置            //设置土司的持续时长            toast.setDuration(Toast.LENGTH_SHORT);            toast.setGravity(Gravity.CENTER, 0, 0);            //设置土司的背景View            toast.setView(view);        }        //设置土司的显示额内容        textView.setText(text);        toast.show();    }

5 使用注意:

Android 30之后Toast位置参数将失效,设置位置也会跟随系统的位置,所以Google建议用SnackBar来替换Toast。

如果坚持用Toast那么推荐一个Toast库,可以设置Toast位置,如下添加依赖库

implementation 'com.hjq:toast:8.8'

在application里面初始化

ToastUtils.init(this);

在其它位置弹出该Toast

ToastUtils.show("提示消息");

五 SnackBar

2 简单使用

 public void snackbar1(View view) {   Snackbar.make(this,llRootLayout,"snack bar",Snackbar.LENGTH_SHORT).show();}

第一个参数是Context 
第二个参数是要显示的view
第三个参数是显示的字符串
第四个参数是显示时长,时长有下面三种:
Snackbar.LENGTH_SHORT与Toast.LENGHT_SHORT(大约1秒多)一样显示较短时长后自动消失
Snackbar.LENGTH_LONG与Toast.LENGHT_LONG(大约3秒)一样显示相对较长时间后自动消失
Snackbar.LENGTH_INDEFINITE:永不消失除非手动调用dismiss()方法去除Snackbar

3 交互使用

public void snackbar2(View view) {Snackbar snack_bar = Snackbar.make(this,view, "确定退出吗?", Snackbar.LENGTH_INDEFINITE);snack_bar.setAction("确认", new View.OnClickListener() {@Overridepublic void onClick(View v) {//退出}});snack_bar.show();}

4 自定义布局SnackBar

布局snackbar_view.xml

            

工具类SnackBarUtil.java 

public class SnackBarUtil {    //自定义 SnackBar 布局    public static void show(Activity activity, View view, String msg, String action, SnackBarOnClick listener) {        //获取示例 findViewById(android.R.id.content) //LENGTH_LONG/LENGTH_SHORT: 会自动消失 LENGTH_INDEFINITE: 需要手动点击消失        Snackbar snackbar = Snackbar.make(view, "", Snackbar.LENGTH_SHORT);        //设置 Snackbar 的深度,避免被其他控件遮挡        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {            snackbar.getView().setElevation(0);        }        //设置背景透明,避免自带黑色背景影响        snackbar.getView().setBackgroundColor(Color.TRANSPARENT);        //设置padding 取消自定义时黑色边框        snackbar.getView().setPadding(0, 0, 0, 0);        Snackbar.SnackbarLayout snackbarLayout = (Snackbar.SnackbarLayout) snackbar.getView();        //设置SnackBar的显示位置        //ViewGroup.LayoutParams layoutParams = snackbarLayout.getLayoutParams();        FrameLayout.LayoutParams flp = new FrameLayout.LayoutParams(dip2px(activity,260),dip2px(activity,32)); // 将原来Snackbar的宽高传入新的LayoutParams        flp.gravity = Gravity.CENTER | Gravity.BOTTOM; // 设置显示位置        flp.bottomMargin = dip2px(activity,8);        ((View) snackbarLayout).setLayoutParams(flp);        //获取自定义布局        View inflate = LayoutInflater.from(activity).inflate(R.layout.snackbar_view, null);        //获取布局内控件        TextView textView = inflate.findViewById(R.id.textView);        //TextView 前边添加图片        //Drawable drawable = getResources().getDrawable(R.mipmap.ic_launcher_round);//图片自己选择        //drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());        //textView.setCompoundDrawables(drawable, null, null, null);        //增加文字和图标的距离        //textView.setCompoundDrawablePadding(20);        //设置文本        textView.setText(msg);        if (action != null && listener != null) {            TextView textViewSub = inflate.findViewById(R.id.textViewSub);            textViewSub.setVisibility(View.VISIBLE);            textViewSub.setText(action);            textViewSub.setOnClickListener(v -> {                if (listener != null) {                    listener.clickEvent(snackbar);                }            });        }        //添加图片 获取布局内控件        //ImageView imageView = inflate.findViewById(R.id.imageView2);        //获取图片资源        //Drawable drawable = activity.getResources().getDrawable(closeIcon);        //设置图片        //imageView.setImageDrawable(drawable);        //将自定义布局添加到 Snackbar 中        snackbarLayout.addView(inflate);        //显示        snackbar.show();    }    public interface SnackBarOnClick {        void clickEvent(Snackbar snackbar);    }        public static int dip2px(Activity activity, float dpValue) {        final float scale = activity.getResources().getDisplayMetrics().density;        return (int) (dpValue * scale + 0.5f);    }}

 调用工具类SnackBarUtil

public void snackbar3(View view) {        SnackBarUtil.show(this, view, "确定退出吗?", "确认", new SnackBarUtil.SnackBarOnClick() {            @Override            public void clickEvent(Snackbar snackbar) {                //退出            }        });    }

六 PopWindow下拉弹框使用

1 PopWindow也是一种弹框,相比较Dialog它更多的使用场景是基于某个控件位置的弹出,也支持任意布局和样式

2 示例,添加布局文件,popup_size_listview.xml

    

3 自定义PopupWindow

public class PopupviewSizeModel extends PopupWindow {    private IPopuWindowListener mOnClickListener;    private Activity mContext;    private RecyclerView recyclerView;    private PopupModelListAdapter popupModelListAdapter;    private List listString=new ArrayList<>();        public void setPopuWindowListener(IPopuWindowListener mOnClickListener) {        this.mOnClickListener = mOnClickListener;    }    public PopupviewSizeModel(Activity context) {        super(context);        this.mContext = context;        //获取布局文件        View mContentView = LayoutInflater.from(mContext).inflate(R.layout.popup_size_listview, null);        initView(mContentView);        //设置布局        setContentView(mContentView);        int width = context.getWindowManager().getDefaultDisplay().getWidth();        setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);        setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);        //设置可以点击外部消息        //开始        setOutsideTouchable(true);        setFocusable(true);//        setBackgroundDrawable(new BitmapDrawable());        setBackgroundDrawable(context.getResources().getDrawable(android.R.color.transparent));        setAnimationStyle(R.style.pop_animation);    }    private void initView(View contentView) {        recyclerView = (RecyclerView) contentView.findViewById(R.id.rcl_view);        LinearLayoutManager manager = new LinearLayoutManager(mContext);        recyclerView.setLayoutManager(manager);        recyclerView.setNestedScrollingEnabled(false);        popupModelListAdapter = new PopupModelListAdapter(mContext, R.layout.item_popup_size_list, listString);        recyclerView.setAdapter(popupModelListAdapter);        popupModelListAdapter.setOnItemClickListener(new MultiItemTypeAdapter.OnItemClickListener() {            @Override            public void onItemClick(View view, RecyclerView.ViewHolder holder, int position) {                dismiss();                if(mOnClickListener!=null){                    mOnClickListener.onItemClick(position);                }            }            @Override            public boolean onItemLongClick(View view, RecyclerView.ViewHolder holder, int position) {                return false;            }        });    }    public void setListData(List list) {        listString.clear();        listString.addAll(list);        popupModelListAdapter.setData(listString);        popupModelListAdapter.notifyDataSetChanged();    }//     /     * 在android7.0上,如果不主动约束PopuWindow的大小,比如,设置布局大小为 MATCH_PARENT,那么PopuWindow会变得尽可能大,以至于 view下方无空间完全显示PopuWindow,而且view又无法向上滚动,此时PopuWindow会主动上移位置,直到可以显示完全。//     * 解决办法:主动约束PopuWindow的内容大小,重写showAsDropDown方法://     * @param anchor//     *///    @Override//    public void showAsDropDown(View anchor,int xoff,int yoff,int gravity) {//        if (Build.VERSION.SDK_INT >= 24) {//            Rect visibleFrame = new Rect();//            anchor.getGlobalVisibleRect(visibleFrame);//            int height = anchor.getResources().getDisplayMetrics().heightPixels - visibleFrame.bottom;//            setHeight(height);//            showAsDropDown(anchor, xoff, yoff,gravity);//        } else {//           showAsDropDown(anchor, xoff, yoff,gravity);//        }//        super.showAsDropDown(anchor);//    }    public interface IPopuWindowListener {        void onItemClick(int position);    }}

4 设置数据模型 

publicclass BindSizeListDTO{        public String id;        public String name;        public BindSizeListDTO(String name) {            this.name = name;        }    }

5 在指定view位置弹出该PopupWindow

private PopupviewSizeModel popupviewModelSize;List listStringSize = new ArrayList<>();private void showSizePopup() {listStringSize.add(new InfoBean.BindSizeListDTO("230x150"));listStringSize.add(new InfoBean.BindSizeListDTO("270x200"));listStringSize.add(new InfoBean.BindSizeListDTO("300x200"));listStringSize.add(new InfoBean.BindSizeListDTO("330x225"));listStringSize.add(new InfoBean.BindSizeListDTO("340x239"));if (popupviewModelSize == null) {popupviewModelSize = new PopupviewSizeModel(mContext);popupviewModelSize.setPopuWindowListener(new PopupviewSizeModel.IPopuWindowListener() {@Overridepublic void onItemClick(int position) {Toast.makeText(SnackBarActivity.this, "点击了条目", Toast.LENGTH_SHORT).show();}});}popupviewModelSize.setListData(listStringSize);popupviewModelSize.showAsDropDown(tvSize);}

七 DialogFragment

1 Dialog是依赖与Activity的生命周期,DialogFragment与Dialog不同的是它本质上是一个Fragment,也就具有Fragment所拥有的生命周期,

1 创建DialogFragment的方式,用onCreateDialog来创建系统提供的Dialog

public class SystemDialogFragment extends DialogFragment {    @NonNull    @Override    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {        AlertDialog dialog = new AlertDialog.Builder(getContext())                .setTitle("系统弹窗")                .setMessage("信息")                //.setIcon(R.drawable.assign_set_question_ic_v2)                .setNegativeButton("取消", new DialogInterface.OnClickListener() {                    @Override                    public void onClick(DialogInterface dialog, int which) {                    }                }).setPositiveButton("确定", new DialogInterface.OnClickListener() {                    @Override                    public void onClick(DialogInterface dialog, int which) {                        Toast.makeText(getContext(), "确认", Toast.LENGTH_SHORT).show();                    }                }).create();        return dialog;    }}

Activity中调用该DialogFragment

public class DialogFragmentActivity extends ComponentActivity {    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activty_dialog_fragment);    }    public void alertdialog(View view) {        SystemDialogFragment systemDialogFragment=new SystemDialogFragment();        systemDialogFragment.show(getFragmentManager(),"ss");    }}

效果:

2 自定义布局DialogFragment

创建布局文件dialog_confirm.xml

                                

创建DialogFragment,CustomerDialogFragment.java

public class CustomerDialogFragment extends DialogFragment {    public View mRootView;    private TextView tvTitle;    private TextView tvContent;    private TextView tvCancel;    private TextView tvSure;    @Nullable    @Override    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {        if (mRootView == null){            //获取布局            mRootView = inflater.inflate(R.layout.dialog_confirm,container,false);        }        tvTitle = (TextView) mRootView.findViewById(R.id.tv_title);        tvContent = (TextView) mRootView.findViewById(R.id.tv_content);        tvCancel = (TextView) mRootView.findViewById(R.id.tv_cancel);        tvSure = (TextView) mRootView.findViewById(R.id.tv_sure);        tvCancel.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                dismiss();            }        });        tvSure.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Toast.makeText(getActivity(), "点击确定", Toast.LENGTH_SHORT).show();                dismiss();            }        });        return mRootView;    }}

Activity调用该DialogFragment

 public void customerdialog(View view) {     CustomerDialogFragment systemDialogFragment=new CustomerDialogFragment();     systemDialogFragment.show(getFragmentManager(),"Customer"); }

效果演示

八 系统悬浮框

1 系统悬浮框跟随应用生命周期,可以不在Acitivity上面,不依赖Acitivity,适合全局生命周期的弹框

2 使用,新建布局文件,float_layout_window.xml

                        

2 添加悬浮框权限

3 新建FloatWindowsActivity.java,添加悬浮框布局

public class FloatWindowsActivity extends ComponentActivity {    public WindowManager mWindowManager;    public View mWindowView;    public LinearLayout mText;    public WindowManager.LayoutParams wmParams;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activty_float_windows);    }    public void folatwindows(View view) {        checkFloatPermission();    }    @Override    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {        super.onActivityResult(requestCode, resultCode, data);        if(requestCode==0){            checkFloatPermission();        }    }        public void checkFloatPermission(){        if(!Settings.canDrawOverlays(FloatWindowsActivity.this)) {            Toast.makeText( FloatWindowsActivity.this, "当前无权限,请授权", Toast.LENGTH_SHORT);            startActivityForResult( new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse( "package:"+ getPackageName())), 0);        }else {            initWindowParams();        }    }        private void initWindowParams() {        //1,获取系统级别的WindowManager        mWindowManager = (WindowManager) getApplication().getSystemService(getApplication().WINDOW_SERVICE);        wmParams = new WindowManager.LayoutParams();        //2,添加系统参数,确保悬浮框能显示到手机上        //电话窗口。它用于电话交互(特别是呼入)。它置于所有应用程序之上,状态栏之下。        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {            wmParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;        } else {            wmParams.type = WindowManager.LayoutParams.TYPE_PHONE;        }        // flag 设置 Window 属性        wmParams.flags                |= WindowManager.LayoutParams.FLAG_FULLSCREEN                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;        //期望的位图格式。默认为不透明        wmParams.format = PixelFormat.TRANSLUCENT;        //不许获得焦点        wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;        //窗口停靠位置        wmParams.gravity = Gravity.LEFT | Gravity.TOP;        wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;        wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;        addWindowViewZWindow();        initClick();    }        private void addWindowViewZWindow() {        if(mWindowView==null){            mWindowView = LayoutInflater.from(getApplication()).inflate(R.layout.float_layout_window, null);            mText = (LinearLayout) mWindowView.findViewById(R.id.linear);        }        mWindowManager.addView(mWindowView, wmParams);    }        int mStartX, mStartY;    int mEndX, mEndY;    private void initClick() {        mText.setOnTouchListener(new View.OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                switch (event.getAction()) {                    //按下鼠标的时候记录下屏幕的位置                    case MotionEvent.ACTION_DOWN:                        mStartX = (int) event.getRawX();                        mStartY = (int) event.getRawY();                        break;                    case MotionEvent.ACTION_MOVE:                        mEndX = (int) event.getRawX();                        mEndY = (int) event.getRawY();                        if (needIntercept()) {//getRawX是触摸位置相对于整个屏幕的位置,getX是控触摸点相对于控件最左边的位置wmParams.x = (int) event.getRawX() - mWindowView.getMeasuredWidth() / 2;wmParams.y = (int) event.getRawY() - mWindowView.getMeasuredHeight() / 2;mWindowManager.updateViewLayout(mWindowView, wmParams);return true;                        }                        break;                    case MotionEvent.ACTION_UP:                        if (needIntercept()) {return true;                        }                        break;                }                return false;            }        });        mText.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Toast.makeText(FloatWindowsActivity.this, "点击悬浮框", Toast.LENGTH_SHORT).show();            }        });    }        private boolean needIntercept() {        if (Math.abs(mStartX - mEndX) > 30 || Math.abs(mStartY - mEndY) > 30) {            return true;        }        return false;    }}

4 效果图

可以在任意Activity显示

 也可以退到桌面仍显示

来源地址:https://blog.csdn.net/qq_29848853/article/details/131057663

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Android之 弹框总结

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java SWT中常见弹出框实例总结

刚开始写Java工具的小伙伴可能不知道怎么写消息对话框,在这里总结一些常用的几种消息弹出框,下面这篇文章主要给大家介绍了关于Java SWT中常见弹出框的相关资料,需要的朋友可以参考下
2023-01-16

Java复习之集合框架总结

俗话说:温故而知新。想想学过的知识,就算是以前学得很不错,久不用了,就会忘记,所以温习一下以前学习的知识我认为是非常有必要的。而本篇文件温习的是 Java基础中的集合框架。为什么会有集合框架?平时我们用数组存储一些基本的数据类型,或者是引用
2023-05-31

浅析Android之Adapter用法总结

1.概念 Adapter是连接后端数据和前端显示的适配器接口,是数据和UI(View)之间一个重要的纽带。在常见的View(ListView,GridView)等地方都需要用到Adapter。如下图直观的表达了Data、Adapter、Vi
2022-06-06

Android控件之SeekBar的用法总结

1 SeekBar简介 SeekBar是进度条。我们使用进度条时,可以使用系统默认的进度条;也可以自定义进度条的图片和滑块图片等。 2 SeekBar示例 创建一个activity,包含2个SeekBar。第1个SeekBar是系统默认的S
2022-06-06

Android程序开发之WebView使用总结

前言:今天修改项目中一个有关WebView使用的bug,激起了我总结WebView的动机,今天抽空做个总结。使用场景:1.)添加权限2022-06-06

Android编程之OpenGL绘图技巧总结

本文实例讲述了Android编程之OpenGL绘图技巧。分享给大家供大家参考,具体如下: 很久不用OpenGL ES绘图,怕自己忘记了,于是重新复习一遍,顺便原理性的东西总结如下: 1. Android 3D坐标系统 如图:Android的
2022-06-06

2022年终总结,我的10年Android之旅

本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 郭霖 即可关注,每个工作日都有文章更新。 不可思议,这已经是我第10个年头的年终总结了。 但准确来说,我的Android之旅应该不止10年。 2010年的夏天,那时我正
2023-08-16

Android笔试总结

笔试,共10道题,不间。(答案整理自互联网,不保证完全正确,仅供参考。)1.请谈一下Android系统的架构。答:Android系统采用了分层架构,从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和linux核心层。2.谈谈and
2022-06-06

Android蓝牙总结

因为之前有做与蓝牙有关的项目,所以这里写个博客总结一下。 附带了一个项目以供参考:https://github.com/979451341/BleStudy 一.蓝牙操作流程 1.获取蓝牙服务mBluetoothManager = (Blu
2022-06-06

Python开源框架总结

Django: Python Web应用开发框架Django 应该是最出名的Python框架,GAE甚至Erlang都有框架受它影响。Django是走大而全的方向,它最出名的是其全自动化的管理后台:只需要使用起ORM,做简单的对象定义,它就
2023-01-31

Android开发之TextView控件用法实例总结

本文实例总结了Android开发之TextView控件用法。分享给大家供大家参考,具体如下: TextView控件可以向用户展现文本信息,我们可以设置该文本信息是否能编辑 1、TextView基本使用 在程序中创建TextView对象 在x
2022-06-06

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录