XPopup

项目地址:li-xiaojun/XPopup 

简介:?功能强大,UI 简洁,交互优雅的通用弹窗!可以替代 Dialog,PopupWindow,PopupMenu,BottomSheet,DrawerLayout,Spinner 等组件,自带十几种效果良好的动画, 支持完全的 UI 和动画自定义!(Powerful and Beautiful Popup,can absolutely replace Dialog,PopupWindow,PopupMenu,BottomSheet,DrawerLayout,Spinner. With built-in animators , very easy to custom Popup View.)

更多:作者   提 Bug

标签:

      

功能强大,UI 简洁,交互优雅的通用弹窗!可以替代 Dialog,PopupWindow,PopupMenu,BottomSheet,DrawerLayout,Spinner 等组件,自带十几种效果良好的动画, 支持完全的 UI 和动画自定义!它有这样几个特点:

  1. 功能强大,内部封装了常用的弹窗,内置十几种良好的动画,将弹窗和动画的自定义设计的极其简单
  2. UI 和动画简洁,遵循 Material Design,在设计动画的时候考虑了很多细节,过渡,层级的变化;或者说是模拟系统组件的动画,具体可以从 Demo 中感受
  3. 交互优雅,实现了优雅的手势交互以及智能的嵌套滚动,具体看 Demo
  4. 适配全面屏,目前适配了小米,华为,谷歌,OPPO,VIVO,三星,魅族,一加全系全面屏手机
  5. 通用性,项目需求复杂多变,产品经理天马行空,虽然很难做到 UI 的通用,但是你可以看到交互和动画完全可以通用;至于弹窗的 UI 和逻辑可能需要你自定义
  6. 易用性,所有的自定义弹窗只需继承对应的类,实现你的布局,然后在onCreate方法写逻辑即可

编写本库的初衷有以下几点

  1. 项目有这样常见需求:中间和底部弹出甚至可拖拽的对话框,指定位置的 PopupMenu 或者 PopupWindow,指定区域阴影的弹出层效果
  2. 市面上已有的类库要么功能不足够,要么交互效果不完美,有着普遍的缺点,就像 BottomSheet 存在的问题一样。比如:窗体消失的动画和背景渐变动画不一致,窗体消失后半透明背景仍然停留一会儿

设计思路: 综合常见的弹窗场景,我将其分为几类:

  1. Center 类型,就是在中间弹出的弹窗,比如确认和取消弹窗,Loading 弹窗
  2. Bottom 类型,就是从页面底部弹出,比如从底部弹出的分享窗体,知乎的从底部弹出的评论列表,我内部会处理好手势拖拽和嵌套滚动
  3. Attach 类型,就是弹窗的位置需要依附于某个 View 或者某个触摸点,就像系统的 PopupMenu 效果一样,但 PopupMenu 的自定义性很差,淘宝的商品列表筛选的下拉弹窗也属于这种,微信的朋友圈点赞弹窗也是这种。
  4. DrawerLayout 类型,就是从窗体的坐边或者右边弹出,并支持手势拖拽;好处是与界面解耦,可以在任何界面显示 DrawerLayout
  5. 大图浏览类型,就像掘金那样的图片浏览弹窗,带有良好的拖拽交互体验
  6. 全屏弹窗,弹窗是全屏的,就像 Activity 那样,可以设置任意的动画器;适合用来实现登录,选择性的界面效果。

ScreenShot

 

 

 

 

 

 

 

快速体验 Demo

扫描二维码下载 Demo: 

如果二维码图片不可见,点我下载 Demo 体验

使用

首先需要添加 Gradle 依赖:

//注意:1.6.0 之后的 API 大幅重构,不兼容之前的 API,但是扩展性更好,请酌情升级。
//注意:1.6.0 之后的 API 大幅重构,不兼容之前的 API,但是扩展性更好,请酌情升级。
//注意:1.6.0 之后的 API 大幅重构,不兼容之前的 API,但是扩展性更好,请酌情升级。
implementation 'com.lxj:xpopup:1.6.7'//重构之前的版本
//implementation 'com.lxj:xpopup:1.5.2'

必须添加的依赖库:

//版本号在 26 以及以上即可
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'

为了方便使用,已经内置了几种常见弹窗的实现:

  1. 显示确认和取消对话框

     new XPopup.Builder(getContext()).asConfirm("我是标题", "我是内容",new OnConfirmListener() {@Overridepublic void onConfirm() {toast("click confirm");}}).show();
    
  2. 显示带输入框的确认和取消对话框
     new XPopup.Builder(getContext()).asInputConfirm("我是标题", "请输入内容。",new OnInputConfirmListener() {@Overridepublic void onConfirm(String text) {toast("input text: " + text);}}).show();
    
  3. 显示中间弹出的列表弹窗
     new XPopup.Builder(getContext())//.maxWidth(600).asCenterList("请选择一项", new String[]{"条目 1", "条目 2", "条目 3", "条目 4"},new OnSelectListener() {@Overridepublic void onSelect(int position, String text) {toast("click " + text);}}).show();
    
  4. 显示中间弹出的加载框
     new XPopup.Builder(getContext()).asLoading("正在加载中").show();
    
  5. 显示从底部弹出的列表弹窗
     // 这种弹窗从 1.0.0 版本开始实现了优雅的手势交互和智能嵌套滚动new XPopup.Builder(getContext()).asBottomList("请选择一项", new String[]{"条目 1", "条目 2", "条目 3", "条目 4", "条目 5"},new OnSelectListener() {@Overridepublic void onSelect(int position, String text) {toast("click " + text);}}).show();
    
  6. 显示依附于某个 View 或者某个点的弹窗

     new XPopup.Builder(getContext()).atView(v)  // 依附于所点击的 View,内部会自动判断在上方或者下方显示.asAttachList(new String[]{"分享", "编辑", "不带 icon"},new int[]{R.mipmap.ic_launcher, R.mipmap.ic_launcher},new OnSelectListener() {@Overridepublic void onSelect(int position, String text) {toast("click " + text);}}).show();
    

    如果是想依附于某个 View 的触摸点,则需要先watch该 View,然后当单击或长按触发的时候去显示:

     // 必须在事件发生前,调用这个方法来监视 View 的触摸final XPopup.Builder builder = new XPopup.Builder(getContext()).watchView(view.findViewById(R.id.btnShowAttachPoint));view.setOnLongClickListener(new View.OnLongClickListener() {@Overridepublic boolean onLongClick(View v) {builder.asAttachList(new String[]{"置顶", "复制", "删除"}, null,new OnSelectListener() {@Overridepublic void onSelect(int position, String text) {toast("click " + text);}}).show();return false;}});
    

    asAttachList方法内部是对 AttachPopupView 的封装,如果你的布局不是列表,可以继承 AttachPopupView 实现自己想要的布局。 AttachPopupView 会出现在目标的上方或者下方,如果你想要出现在目标的左边或者右边(像微信朋友圈那样点赞的弹窗),可以继承 HorizontalAttachPopupView,然后编写你的布局即可。

    最简单示例如下:

     public class CustomAttachPopup extends HorizontalAttachPopupView {public CustomAttachPopup(@NonNull Context context) {super(context);}@Overrideprotected int getImplLayoutId() {return R.layout.custom_attach_popup;}@Overrideprotected void onCreate() {super.onCreate();findViewById(R.id.tv_zan).setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {ToastUtils.showShort("赞");}});findViewById(R.id.tv_comment).setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {ToastUtils.showShort("评论");}});}}
    
  1. 关闭弹窗

     dismiss();
    
  2. 自定义弹窗

    当你自定义弹窗的时候,需要选择继承CenterPopupViewBottomPopupViewAttachPopupView/HorizontalAttachPopupViewDrawerPopupViewPartShadowPopupView其中之一。假设需要自定义 Center 类型的弹窗:

     class CustomPopup extends CenterPopupView{//自定义弹窗本质是一个自定义 View,但是只需重写这个构造,其他的不用重写public CustomPopup(@NonNull Context context) {super(context);}// 返回自定义弹窗的布局@Overrideprotected int getImplLayoutId() {return R.layout.custom_popup;}// 执行初始化操作,比如:findView,设置点击,或者任何你弹窗内的业务逻辑@Overrideprotected void onCreate() {super.onCreate();findViewById(R.id.tv_close).setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {dismiss(); // 关闭弹窗}});}// 设置最大宽度,看需要而定@Overrideprotected int getMaxWidth() {return super.getMaxWidth();}// 设置最大高度,看需要而定@Overrideprotected int getMaxHeight() {return super.getMaxHeight();}// 设置自定义动画器,看需要而定@Overrideprotected PopupAnimator getPopupAnimator() {return super.getPopupAnimator();}}
    

    使用自定义弹窗:

     new XPopup.Builder(getContext()).asCustom(new CustomPopup(getContext())).show();
    
  3. 自定义动画

    自定义动画已经被设计得非常简单,动画和弹窗是无关的;这意味着你可以将动画设置给内置弹窗或者自定义弹窗。继承PopupAnimator,实现 3 个方法:

    • 如何初始化动画
    • 动画如何开始
    • 动画如何结束

      比如:自定义一个旋转的动画:

      class RotateAnimator extends PopupAnimator{@Overridepublic void initAnimator() {targetView.setScaleX(0);targetView.setScaleY(0);targetView.setAlpha(0);targetView.setRotation(360);}@Overridepublic void animateShow() {targetView.animate().rotation(0).scaleX(1).scaleY(1).alpha(1).setInterpolator(new FastOutSlowInInterpolator()).setDuration(animateDuration).start();}@Overridepublic void animateDismiss() {targetView.animate().rotation(360).scaleX(0).scaleY(0).alpha(0).setInterpolator(new FastOutSlowInInterpolator()).setDuration(animateDuration).start();}}
      

      使用自定义动画:

      new XPopup.Builder(getContext()).customAnimator(new RotateAnimator()).asConfirm("演示自定义动画", "当前的动画是一个自定义的旋转动画,无论是自定义弹窗还是自定义动画,已经被设计得非常简单;这个动画代码只有 6 行即可完成!", null).show();
      
  4. 显示 DrawerLayout 类型弹窗

    对于 DrawerLayout 类型的弹窗,我只能帮你做好弹窗效果和手势交互。里面的 UI 和逻辑是无法帮你完成的,所以需要自定义一个弹窗,继承DrawerPopupView。代码非常简单,如下:

    public class CustomDrawerPopupView extends DrawerPopupView {public CustomDrawerPopupView(@NonNull Context context) {super(context);}@Overrideprotected int getImplLayoutId() {return R.layout.custom_drawer_popup;}@Overrideprotected void onCreate() {super.onCreate();findViewById(R.id.btn).setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(getContext(), "nothing!!!", Toast.LENGTH_SHORT).show();}});}
    }
    

    使用自定义的 DrawerLayout 弹窗:

    new XPopup.Builder(getContext()).popupPosition(PopupPosition.Right)//右边.hasStatusBarShadow(true) //启用状态栏阴影.asCustom(new CustomDrawerPopupView(getContext())).show();
    
  1. 自定义局部阴影弹窗

    这种效果从分类上看仍然是 Attach 类型,因为要依附于某个 View,在其上方或者下方显示。常见于列表条件筛选弹窗,比如京东或者淘宝的商品列表筛选。同样我只能帮你把复杂的交互效果做了,弹窗里面的 UI 和逻辑需要你自己继承PartShadowPopupView来做,这当然非常简单。 最简单的示例如下:

    public class CustomPartShadowPopupView extends PartShadowPopupView {public CustomPartShadowPopupView(@NonNull Context context) {super(context);}@Overrideprotected int getImplLayoutId() {return R.layout.custom_part_shadow_popup; // 编写你自己的布局}@Overrideprotected void onCreate() {super.onCreate();// 实现一些 UI 的初始和逻辑处理}
    }
    

    显示的时候仍然需要指定 atView 显示,内部会智能判断应该如何展示以及使用最佳的动画器:

    new XPopup.Builder(getContext()).atView(ll_container).asCustom(new CustomPartShadowPopupView(getContext())).show();
    
  1. 自定义 Bottom 类型的弹窗

    自定义 Bottom 类型的弹窗会比较常见,默认 Bottom 弹窗带有手势交互和嵌套滚动;如果您不想要手势交互可以调用enableDrag(false)方法关闭。

    如果弹窗内有输入框,在弹出输入法的情况下,弹窗默认会贴附在输入法之上,并且保证不会盖住输入框;目前 Center 和 Bottom 类型弹窗有此效果。

    请注意:弹窗的宽高是自适应的,大部分情况下都应该将弹窗布局的高设置为wrap_content;除非你希望得到一个高度撑满的弹窗。

    Demo 中有一个模仿知乎评论的实现,代码在这里:

    public class ZhihuCommentPopup extends BottomPopupView {VerticalRecyclerView recyclerView;public ZhihuCommentPopup(@NonNull Context context) {super(context);}@Overrideprotected int getImplLayoutId() {return R.layout.custom_bottom_popup;}@Overrideprotected void onCreate() {super.onCreate();recyclerView = findViewById(R.id.recyclerView);ArrayList<String> strings = new ArrayList<>();for (int i = 0; i < 30; i++) {strings.add("");}CommonAdapter<String> commonAdapter = new CommonAdapter<String>(R.layout.adapter_zhihu_comment, strings) {@Overrideprotected void bind(@NonNull ViewHolder holder, @NonNull String s, int position) {}};commonAdapter.setOnItemClickListener(new MultiItemTypeAdapter.SimpleOnItemClickListener(){@Overridepublic void onItemClick(View view, RecyclerView.ViewHolder holder, int position) {dismiss();}});recyclerView.setAdapter(commonAdapter);}// 最大高度为 Window 的 0.85@Overrideprotected int getMaxHeight() {return (int) (XPopupUtils.getWindowHeight(getContext())*.85f);}
    }
    
  2. 大图浏览弹窗

    这种弹窗多用于 App 内列表中图片进行详细展示的场景,用法如下:

    // 多图片场景
    new XPopup.Builder(getContext()).asImageViewer(imageView, position, list, new OnSrcViewUpdateListener() {@Overridepublic void onSrcViewUpdate(ImageViewerPopupView popupView, int position) {// 作用是当 Pager 切换了图片,需要更新源 ViewpopupView.updateSrcView((ImageView) recyclerView.getChildAt(position));}}, new ImageLoader()).show();// 单张图片场景
    new XPopup.Builder(getContext()).asImageViewer(imageView, url, new ImageLoader()).show();// 图片加载器,我不负责加载图片,需要你实现一个图片加载器传给我,这里以 Glide 为例。
    class ImageLoader implements XPopupImageLoader {@Overridepublic void loadImage(int position, @NonNull String url, @NonNull ImageView imageView) {Glide.with(imageView).load(url).into(imageView);}//必须实现这个方法,返回 uri 对应的缓存文件,可参照下面的实现,内部保存图片会用到。@Overridepublic File getImageFile(@NonNull Context context, @NonNull Object uri) {try {return Glide.with(context).downloadOnly().load(uri).submit().get();} catch (Exception e) {e.printStackTrace();}return null;}}
    

    注意事项:假设你使用 Glide 加载图片,如果你的 ImageView 是 CenterCrop 的,那么加载的时候一定要指定大小为Target.SIZE_ORIGINAL; 这样会禁止 Glide 裁剪图片,保证可以拿到原始图片,让图片过渡动画变的天衣无缝。例如:

    Glide.with(imageView).load(s).apply(new RequestOptions().override(Target.SIZE_ORIGINAL)).into(imageView);
    

    如果你使用其他类库加载图片,请保证加载的图片没有被裁剪过。

  1. 其他
  2. 设置主色调

    默认情况下,XPopup 的主色为灰色,主色作用于 Button 文字,EditText 边框和光标,Check 文字的颜色上。主色调只需要设置一次即可,可以放在 Application 中设置。

    XPopup.setPrimaryColor(getResources().getColor(R.color.colorPrimary));
    
  3. 设置全局的动画时长

    默认情况下,弹窗的动画时长为 360 毫秒。你可以通过下面的方法进行修改:

      XPopup.setAnimationDuration(300); // 如果传入的值小于 200 会被忽略,动画的时长会影响除 Drawer 弹窗外的所有弹窗
    
  4. 常用设置

    new XPopup.Builder(getContext()).hasShadowBg(true) // 是否有半透明的背景,默认为 true.dismissOnBackPressed(true) // 按返回键是否关闭弹窗,默认为 true.dismissOnTouchOutside(true) // 点击外部是否关闭弹窗,默认为 true.autoDismiss(false) // 操作完毕后是否自动关闭弹窗,默认为 true;比如点击 ConfirmPopup 的确认按钮,默认自动关闭;如果为 false,则不会关闭.autoOpenSoftInput(true) //是否弹窗显示的同时打开输入法,只在包含输入框的弹窗内才有效,默认为 false.popupAnimation(PopupAnimation.ScaleAlphaFromCenter) // 设置内置的动画.customAnimator(null) // 设置自定义的动画器.moveUpToKeyboard(false) // 软键盘弹出时,弹窗是否移动到软键盘上面,默认为 true.popupPosition(PopupPosition.Right)//手动指定弹窗出现在目标的什么位置,对 Attach 和 Drawer 类型弹窗生效.hasStatusBarShadow(false) //是否有状态栏阴影,目前对 Drawer 弹窗和 FullScreen 弹窗生效.offsetX(-10) //弹窗在 x 方向的偏移量.offsetY(-10) //弹窗在 y 方向的偏移量.enableDrag(true) //是否启用拖拽,默认为 true,目前对 Bottom 弹窗有用.isCenterHorizontal(true)//默认为 false,默认情况下 Attach 弹窗依靠着目标的左边或者右边,如果 isCenterHorizontal 为 true,则与目标水平居中对齐.isRequestFocus(false)//默认为 true,默认情况下弹窗会抢占焦点,目的是为了响应返回按键按下事件;如果为 false,则不抢焦点.setPopupCallback(new XPopupCallback() { //设置显示和隐藏的回调@Overridepublic void onShow() {// 完全显示的时候执行}@Overridepublic void onDismiss() {// 完全隐藏的时候执行}})// 设置弹窗的最大宽高,只对 Center 和 Bottom 类型弹窗生效。默认情况下,弹窗的布局是自适应的,如果你设置了最大宽高,则弹窗的宽高不会超过你设置的值!// 如果你重写了`getMaxWidth()`和`getMaxHeight()`方法,此方法设置的值会被覆盖;.maxWidth(300).maxHeight(400)// 如果你想要一个全屏的弹窗,有 3 种方式:// 1. 首先布局要都是`match_parent`,然后调用上面的方法设置这个值为 window 的宽高即可。// 2. 可以重写`getMaxWidth()`和`getMaxHeight()`方法,效果是一样的。// 3. 可以继承 FullScreenPopupView,直接编写布局即可。.asXXX()
    
  5. 数据和状态保存

    如果每次显示都 new 一个,由于每次都是新的弹窗,状态无法保存。可以选择记录下:

      CustomDrawerPopupView drawerPopupView = new CustomDrawerPopupView(getContext());//使用弹窗new XPopup.Builder(getContext()).popupPosition(PopupPosition.Right)//右边.hasStatusBarShadow(true) //启用状态栏阴影.asCustom(drawerPopupView).show();
    
  6. 在 RecyclerView 中长按弹出弹窗,这种场景需要 watch 一下 itemView:

      CommonAdapter adapter = new CommonAdapter<String>(android.R.layout.simple_list_item_1, data) {@Overrideprotected void bind(@NonNull ViewHolder holder, @NonNull String s, int position) {holder.setText(android.R.id.text1, "长按我试试 - " + position);//必须要在事件发生之前就 watchfinal XPopup.Builder builder = new XPopup.Builder(getContext()).watchView(holder.itemView);holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {@Overridepublic boolean onLongClick(View v) {builder.asAttachList(new String[]{"置顶", "编辑", "删除"}, null,0,10, new OnSelectListener() {@Overridepublic void onSelect(int position, String text) {ToastUtils.showShort(text);}}).show();return true;}});}};
    
  • 最佳实践

    我们在项目中经常会点击某个按钮然后关闭弹窗,接着去做一些事。比如:点击一个按钮,关闭弹窗,然后开启一个界面:

      dismiss();getContext().startActivity(new Intent(getContext(), DemoActivity.class));
    

    要知道弹窗的关闭是有一个动画过程的,上面的写法会出现弹窗还没有完全关闭,就立即跳页面,界面有一种顿挫感;而且在设备资源不足的时候,还可能造成丢帧。

    为了得到最佳体验,您可以等 dismiss 动画完全结束去执行一些东西,而不是立即就执行。可以这样做:

      dismissWith(new Runnable() {@Overridepublic void run() {getContext().startActivity(new Intent(getContext(), DemoActivity.class));}});
    

    每个弹窗本身也有onShow()onDismiss()的生命周期回调,可以根据需要使用。

混淆

-dontwarn com.lxj.xpopup.widget.**
-keep class com.lxj.xpopup.widget.**{*;}

谁在用 XPopup

根据热心群众提供的信息,目前使用 XPopup 的产品和公司有:

  • 海鸥地图(https://cn.gullmap.com/)
  • 马自达汽车检测(主要是一个汽车厂商工作人员使用的汽车检测 APP)
  • 变福侠 App
  • 进境肉牛检疫追溯系统(App 端)

Android功能强大,UI 简洁,交互优雅的通用弹窗相关推荐

  1. 最新天狼星网络验证完整源码+功能强大/UI也不错

    正文: 最新天狼星网络验证完整源码+功能强大/UI也不错,程序是通过PHP开发的,功能方面真心没得说,程序的搭建很简单,就正常搭建就行了,用过这网络验证程序的都还觉得不错. 天狼星网络验证:一个可以添 ...

  2. 功能强大UI美观的视频答题猜歌闯关娱乐微信小程序源码

    正文: 功能强大UI美观的视频答题猜歌闯关娱乐微信小程序源码下载 后台管理资源本地化带数据和视频教程,这是一款拥有后端的闯关娱乐小程序. 支持个人小程序和企业小程序上线运营 功能强大齐全,带数据本地化 ...

  3. 功能强大UI美观的视频答题猜歌闯关娱乐微信小程序源码下载

    内容目录 一.详细介绍 二.效果展示 1.部分代码 2.效果图展示 三.学习资料下载 一.详细介绍 这是一款拥有后端的闯关娱乐小程序 支持个人小程序和企业小程序上线运营 功能强大齐全,带数据本地化 ( ...

  4. 超过 3K + 的一个开源弹框库,使用方便,功能强大,简直碉堡了

    [公众号回复 "1024",免费领取程序员赚钱实操经验] 今天章鱼猫带领大家来看一个基于 Android 的弹窗库,其实对于做 Android 的兄弟姐妹来讲,各种样式的弹窗,尤其 ...

  5. android原生组件,XUI: 一个简洁而优雅的Android原生UI框架,解放你的双手!

    XUI 一个简洁而又优雅的Android原生UI框架,解放你的双手!还不赶紧点击使用说明文档,体验一下吧! 涵盖绝大部分的UI组件:TextView.Button.EditText.ImageView ...

  6. Android常用ui,XUI: 一个简洁而优雅的Android原生UI框架,解放你的双手!

    XUI 一个简洁而又优雅的Android原生UI框架,解放你的双手!还不赶紧点击使用说明文档,体验一下吧! 涵盖绝大部分的UI组件:TextView.Button.EditText.ImageView ...

  7. android炫酷叼ui,XUI: 一个简洁而优雅的Android原生UI框架,解放你的双手!

    XUI 一个简洁而又优雅的Android原生UI框架,解放你的双手!还不赶紧点击使用说明文档,体验一下吧! 涵盖绝大部分的UI组件:TextView.Button.EditText.ImageView ...

  8. android ui风格 车载,XUI: 一个简洁而优雅的Android原生UI框架,解放你的双手!

    XUI 一个简洁而又优雅的Android原生UI框架,解放你的双手!还不赶紧点击使用说明文档,体验一下吧! 涵盖绝大部分的UI组件:TextView.Button.EditText.ImageView ...

  9. Android中后台线程如何与UI线程交互

    我想关于这个话题已经有很多前辈讨论过了.今天算是一次学习总结吧. 在android的设计思想中,为了确保用户顺滑的操作体验.一些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务.因此我们必须 ...

最新文章

  1. flash与字符串:数组转换为字符串
  2. vue 生命周期_Vue 生命周期
  3. mac osx linux,Linux 、Mac OSX 常见问题 及 笔记
  4. uboot启动 及命令分析(3)
  5. 大东电报与雷格斯在全球部署宝利通高清系统
  6. SSL4MIS:医学图像半监督分割的Baselines
  7. 不能bostype没有元数据异常_EAS BOS 开发问题集锦
  8. 杭电1963 完全背包
  9. vue ---- 插槽
  10. 什么情况下java会出现堆溢出_【Java面试题第三期】JVM中哪些地方会出现内存溢出?出现的原因是什么?...
  11. 在线制作ico矢量图标
  12. php 邮箱服务,laravel邮箱服务使用
  13. 数字的ASCII码值转为大写字母
  14. 备考通信复试过程中的一些知识点总结梳理——移动通信系统Ⅱ
  15. c++ socket 多线程 网络聊天室
  16. linux 常用命令——MySql 5.7添加用户、删除用户与授权
  17. random()随机数的产生方式与原理
  18. 基于Apache Hudi构建智能湖仓实践(附亚马逊工程师代码)
  19. excel2010如何在任务栏显示所有打开的excel文件
  20. CISP、CISP-PTE、CISP-DSG、CISP-IRE报名条件、考试内容、考题结构

热门文章

  1. BZOJ2226 基础数论
  2. SQL Server中的数字,浮点数和小数之间的差异
  3. 前端开发div常用属性标签大全
  4. 河南省3加2计算机学校,河南省最好的3+2学校
  5. 使用css实现一个抽奖转盘
  6. 企业做ISO9001认证需要提供哪些材料
  7. 带你走进MySQL数据库(MySQL入门详细总结一)
  8. swift设计模式学习 - 模板方法模式
  9. 孝感市高企培育,湖北省孝感市高企申报对象、流程、奖补
  10. watch和nvidia-smi命令实时查看GPU使用、显存占用情况