返回顶部
首页 > 资讯 > 移动开发 >Android之 弹框总结
  • 839
分享到

Android之 弹框总结

android 2023-09-04 22:09:05 839人浏览 安东尼
摘要

一 简介 1 弹框即浮与页面之上的窗口,如键盘弹框,吐司弹框,确认弹框,下拉选择框,应用悬浮框等 2 弹框控件也很多,比如常用的Spinner,Dialog,Toast,PopWindow等,以及新增的SnackBar,DialogFrag

一 简介

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

--结束END--

本文标题: Android之 弹框总结

本文链接: https://lsjlt.com/news/394437.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Android之 弹框总结
    一 简介 1 弹框即浮与页面之上的窗口,如键盘弹框,吐司弹框,确认弹框,下拉选择框,应用悬浮框等 2 弹框控件也很多,比如常用的Spinner,Dialog,Toast,PopWindow等,以及新增的SnackBar,DialogFrag...
    99+
    2023-09-04
    android
  • Android之 动画总结
    一 动画种类 1 动画在Android中运用也非常广泛,如点击按钮,加载框,Activity的转场等都有动画的身影 2 常用的动画有以下以下几种 逐帧动画【Frame Animation】,即顺序播放事先准备的图片 补间动画【Tween A...
    99+
    2023-09-27
    android 动画
  • Java SWT中常见弹出框实例总结
    目录1.提示框2.确认框3.文本输入框4.字体对话框5.路径选择框6.文件选择框7.颜色选择框总结以下弹出框是框的实现,放入到SWT项目下就可运行。 1.提示框 MessageBox...
    99+
    2023-01-16
    Java swt弹出框 Java swt 酷炫界面 java swt 弹出框
  • Java复习之集合框架总结
    俗话说:温故而知新。想想学过的知识,就算是以前学得很不错,久不用了,就会忘记,所以温习一下以前学习的知识我认为是非常有必要的。而本篇文件温习的是 Java基础中的集合框架。为什么会有集合框架?平时我们用数组存储一些基本的数据类型,或者是引用...
    99+
    2023-05-31
    java 集合框架 ava
  • 浅析Android之Adapter用法总结
    1.概念  Adapter是连接后端数据和前端显示的适配器接口,是数据和UI(View)之间一个重要的纽带。在常见的View(ListView,GridView)等...
    99+
    2022-06-06
    adapter Android
  • Android控件之SeekBar的用法总结
    1 SeekBar简介 SeekBar是进度条。我们使用进度条时,可以使用系统默认的进度条;也可以自定义进度条的图片和滑块图片等。 2 SeekBar示例 创建一个activi...
    99+
    2022-06-06
    seekbar Android
  • Android之 获取定位信息总结
    一,概述: 1  android原生是有定位api的,但稳定性和准确度远远不够,所以通常需要借助三方SDK获取位置信息 2 国内SDK选择性较多,百度,腾讯,高德等定位api,但都是需要在平台建立应用,配置key的,包括基础的定位。 3 国...
    99+
    2023-09-11
    android
  • Android开发之AlertDialog实现弹出对话框
    本文实例为大家分享了Android开发之AlertDialog实现弹出对话框的具体代码,供大家参考,具体内容如下 基本框架 我们在xml中添加一个按钮用来唤出对话框: <xml...
    99+
    2024-04-02
  • Android中常用的三个Dialog弹窗总结解析
    目录ProgressDialogDatePickerDialogTimePickerDialog布局完整代码ProgressDialog private void sh...
    99+
    2024-04-02
  • Android TabLayout总结
    文章目录 Android TabLayout总结基本使用添加图标、隐藏下划线自定义下划线、添加分割线设置角标圆角样式自定义View+Lottile代码下载 Android TabLay...
    99+
    2023-09-04
    android TabLayout
  • Android编程之OpenGL绘图技巧总结
    本文实例讲述了Android编程之OpenGL绘图技巧。分享给大家供大家参考,具体如下: 很久不用OpenGL ES绘图,怕自己忘记了,于是重新复习一遍,顺便原理性的东西总结如...
    99+
    2022-06-06
    技巧 opengl Android
  • Android程序开发之WebView使用总结
    前言: 今天修改项目中一个有关WebView使用的bug,激起了我总结WebView的动机,今天抽空做个总结。 使用场景: 1.)添加权限 <uses-perm...
    99+
    2022-06-06
    webview Android
  • Android蓝牙总结
    因为之前有做与蓝牙有关的项目,所以这里写个博客总结一下。 附带了一个项目以供参考:https://github.com/979451341/Bl...
    99+
    2022-06-06
    Android
  • Android笔试总结
      笔试,共10道题,不间。(答案整理自互联网,不保证完全正确,仅供参考。)   1.请谈一下Android系统的架构。   答:Android系统采用了分层架构,...
    99+
    2022-06-06
    Android
  • 2022年终总结,我的10年Android之旅
    本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 郭霖 即可关注,每个工作日都有文章更新。 不可思议,这已经是我第10个年头的年终总结了。 但准确来说,我的Android之旅应该不止10年。 2010年的夏天,那时我正...
    99+
    2023-08-16
    android 年终总结 随笔 个人感悟
  • 全网最全Android Framework框架总结,Android如何入门Framework层
    每一个Android开发,基本都了解或者学习过系统的知识,一是因为国内软件行业内卷,找工作时“面试造火箭,工作拧螺丝”的局面导致的,另一方面,从客观角度来讲,学习Android系统、Framework...
    99+
    2023-08-31
    android android studio ide
  • spring框架学习总结
    目录Spring 框架概述Spring优点Spring体系结构Spring拓展Spring Boot与Spring CloudSpring IoC 容器 (IoC 也称为依赖项注入(...
    99+
    2024-04-02
  • python web框架的总结
    1、Django Django可能是最具代表性的Python框架,是遵循MMVC结构模式的开源框架。其名字来自DjangoReinhardt,法国作曲家和吉他演奏家,很多人认为他是历...
    99+
    2024-04-02
  • Shiro框架漏洞总结
    一、shiro框架简介:      Apache Shiro是一个强大且易用的Java安全框架,能够用于身份验证、授权、加密和会话管理。只要rememberMe的AES加密密钥泄露,无论shiro是什么版本都会导致反序列化漏洞。Shiro拥...
    99+
    2023-09-04
    java 安全 开发语言 网络安全
  • Python开源框架总结
    Django: Python Web应用开发框架Django 应该是最出名的Python框架,GAE甚至Erlang都有框架受它影响。Django是走大而全的方向,它最出名的是其全自动化的管理后台:只需要使用起ORM,做简单的对象定义,它就...
    99+
    2023-01-31
    开源 框架 Python
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作