如果二维码图片不可见,点我下载 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’

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

new XPopup.Builder(getContext()).asConfirm(“我是标题”, “我是内容”,

new OnConfirmListener() {

@Override

public void onConfirm() {

toast(“click confirm”);

}

})

.show();

new XPopup.Builder(getContext()).asInputConfirm(“我是标题”, “请输入内容。”,

new OnInputConfirmListener() {

@Override

public void onConfirm(String text) {

toast("input text: " + text);

}

})

.show();

new XPopup.Builder(getContext())

//.maxWidth(600)

.asCenterList(“请选择一项”, new String[]{“条目 1”, “条目 2”, “条目 3”, “条目 4”},

new OnSelectListener() {

@Override

public void onSelect(int position, String text) {

toast("click " + text);

}

})

.show();

new XPopup.Builder(getContext())

.asLoading(“正在加载中”)

.show();

// 这种弹窗从 1.0.0 版本开始实现了优雅的手势交互和智能嵌套滚动

new XPopup.Builder(getContext())

.asBottomList(“请选择一项”, new String[]{“条目 1”, “条目 2”, “条目 3”, “条目 4”, “条目 5”},

new OnSelectListener() {

@Override

public void onSelect(int position, String text) {

toast("click " + text);

}

})

.show();

显示依附于某个 View 或者某个点的弹窗

new XPopup.Builder(getContext())

.atView(v) // 依附于所点击的 View,内部会自动判断在上方或者下方显示

.asAttachList(new String[]{“分享”, “编辑”, “不带 icon”},

new int[]{R.mipmap.ic_launcher, R.mipmap.ic_launcher},

new OnSelectListener() {

@Override

public 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() {

@Override

public boolean onLongClick(View v) {

builder.asAttachList(new String[]{“置顶”, “复制”, “删除”}, null,

new OnSelectListener() {

@Override

public 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);

}

@Override

protected int getImplLayoutId() {

return R.layout.custom_attach_popup;

}

@Override

protected void onCreate() {

super.onCreate();

findViewById(R.id.tv_zan).setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

ToastUtils.showShort(“赞”);

}

});

findViewById(R.id.tv_comment).setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

ToastUtils.showShort(“评论”);

}

});

}

}

关闭弹窗

dismiss();

自定义弹窗

当你自定义弹窗的时候,需要选择继承CenterPopupView,BottomPopupView,AttachPopupView/HorizontalAttachPopupView,DrawerPopupView,PartShadowPopupView其中之一。假设需要自定义 Center 类型的弹窗:

class CustomPopup extends CenterPopupView{

//自定义弹窗本质是一个自定义 View,但是只需重写这个构造,其他的不用重写

public CustomPopup(@NonNull Context context) {

super(context);

}

// 返回自定义弹窗的布局

@Override

protected int getImplLayoutId() {

return R.layout.custom_popup;

}

// 执行初始化操作,比如:findView,设置点击,或者任何你弹窗内的业务逻辑

@Override

protected void onCreate() {

super.onCreate();

findViewById(R.id.tv_close).setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

dismiss(); // 关闭弹窗

}

});

}

// 设置最大宽度,看需要而定

@Override

protected int getMaxWidth() {

return super.getMaxWidth();

}

// 设置最大高度,看需要而定

@Override

protected int getMaxHeight() {

return super.getMaxHeight();

}

// 设置自定义动画器,看需要而定

@Override

protected PopupAnimator getPopupAnimator() {

return super.getPopupAnimator();

}

}

使用自定义弹窗:

new XPopup.Builder(getContext())

.asCustom(new CustomPopup(getContext()))

.show();

自定义动画

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

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

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

class RotateAnimator extends PopupAnimator{

@Override

public void initAnimator() {

targetView.setScaleX(0);

targetView.setScaleY(0);

targetView.setAlpha(0);

targetView.setRotation(360);

}

@Override

public void animateShow() {

targetView.animate().rotation(0).scaleX(1).scaleY(1).alpha(1).setInterpolator(new FastOutSlowInInterpolator()).setDuration(animateDuration).start();

}

@Override

public 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();

显示 DrawerLayout 类型弹窗

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

public class CustomDrawerPopupView extends DrawerPopupView {

public CustomDrawerPopupView(@NonNull Context context) {

super(context);

}

@Override

protected int getImplLayoutId() {

return R.layout.custom_drawer_popup;

}

@Override

protected void onCreate() {

super.onCreate();

findViewById(R.id.btn).setOnClickListener(new OnClickListener() {

@Override

public 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();

自定义局部阴影弹窗

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

public class CustomPartShadowPopupView extends PartShadowPopupView {

public CustomPartShadowPopupView(@NonNull Context context) {

super(context);

}

@Override

protected int getImplLayoutId() {

return R.layout.custom_part_shadow_popup; // 编写你自己的布局

}

@Override

protected void onCreate() {

super.onCreate();

// 实现一些 UI 的初始和逻辑处理

}

}

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

new XPopup.Builder(getContext())

.atView(ll_container)

.asCustom(new CustomPartShadowPopupView(getContext()))

.show();

自定义 Bottom 类型的弹窗

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

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

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

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

public class ZhihuCommentPopup extends BottomPopupView {

VerticalRecyclerView recyclerView;

public ZhihuCommentPopup(@NonNull Context context) {

super(context);

}

@Override

protected int getImplLayoutId() {

return R.layout.custom_bottom_popup;

}

@Override

protected void onCreate() {

super.onCreate();

recyclerView = findViewById(R.id.recyclerView);

ArrayList strings = new ArrayList<>();

for (int i = 0; i < 30; i++) {

strings.add(“”);

}

CommonAdapter commonAdapter = new CommonAdapter(R.layout.adapter_zhihu_comment, strings) {

@Override

protected void bind(@NonNull ViewHolder holder, @NonNull String s, int position) {}

};

commonAdapter.setOnItemClickListener(new MultiItemTypeAdapter.SimpleOnItemClickListener(){

@Override

public void onItemClick(View view, RecyclerView.ViewHolder holder, int position) {

dismiss();

}

});

recyclerView.setAdapter(commonAdapter);

}

// 最大高度为 Window 的 0.85

@Override

protected int getMaxHeight() {

return (int) (XPopupUtils.getWindowHeight(getContext())*.85f);

}

}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

Android学习是一条漫长的道路,我们要学习的东西不仅仅只有表面的 技术,还要深入底层,弄明白下面的 原理,只有这样,我们才能够提高自己的竞争力,在当今这个竞争激烈的世界里立足。

人生不可能一帆风顺,有高峰自然有低谷,要相信,那些打不倒我们的,终将使我们更强大,要做自己的摆渡人。

资源持续更新中,欢迎大家一起学习和探讨。

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**

[外链图片转存中…(img-ia4U7Vv8-1711781544396)]

[外链图片转存中…(img-Pssfv6hY-1711781544397)]

[外链图片转存中…(img-WAfc6sSy-1711781544397)]

[外链图片转存中…(img-lN0I4Dex-1711781544397)]

[外链图片转存中…(img-783mAZ2o-1711781544397)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

Android学习是一条漫长的道路,我们要学习的东西不仅仅只有表面的 技术,还要深入底层,弄明白下面的 原理,只有这样,我们才能够提高自己的竞争力,在当今这个竞争激烈的世界里立足。

人生不可能一帆风顺,有高峰自然有低谷,要相信,那些打不倒我们的,终将使我们更强大,要做自己的摆渡人。

资源持续更新中,欢迎大家一起学习和探讨。

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

相关阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: