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

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

}

}

大图浏览弹窗

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

// 多图片场景

new XPopup.Builder(getContext()).asImageViewer(imageView, position, list, new OnSrcViewUpdateListener() {

@Override

public void onSrcViewUpdate(ImageViewerPopupView popupView, int position) {

// 作用是当 Pager 切换了图片,需要更新源 View

popupView.updateSrcView((ImageView) recyclerView.getChildAt(position));

}

}, new ImageLoader())

.show();

// 单张图片场景

new XPopup.Builder(getContext())

.asImageViewer(imageView, url, new ImageLoader())

.show();

// 图片加载器,我不负责加载图片,需要你实现一个图片加载器传给我,这里以 Glide 为例。

class ImageLoader implements XPopupImageLoader {

@Override

public void loadImage(int position, @NonNull String url, @NonNull ImageView imageView) {

Glide.with(imageView).load(url).into(imageView);

}

//必须实现这个方法,返回 uri 对应的缓存文件,可参照下面的实现,内部保存图片会用到。

@Override

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

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

其他 设置主色调

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

XPopup.setPrimaryColor(getResources().getColor(R.color.colorPrimary));

设置全局的动画时长

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

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

常用设置

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() { //设置显示和隐藏的回调

@Override

public void onShow() {

// 完全显示的时候执行

}

@Override

public void onDismiss() {

// 完全隐藏的时候执行

}

})

// 设置弹窗的最大宽高,只对 Center 和 Bottom 类型弹窗生效。默认情况下,弹窗的布局是自适应的,如果你设置了最大宽高,则弹窗的宽高不会超过你设置的值!

// 如果你重写了getMaxWidth()和getMaxHeight()方法,此方法设置的值会被覆盖;

.maxWidth(300)

.maxHeight(400)

// 如果你想要一个全屏的弹窗,有 3 种方式:

// 1. 首先布局要都是match_parent,然后调用上面的方法设置这个值为 window 的宽高即可。

// 2. 可以重写getMaxWidth()和getMaxHeight()方法,效果是一样的。

// 3. 可以继承 FullScreenPopupView,直接编写布局即可。

.asXXX()

数据和状态保存

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

CustomDrawerPopupView drawerPopupView = new CustomDrawerPopupView(getContext());

//使用弹窗

new XPopup.Builder(getContext())

.popupPosition(PopupPosition.Right)//右边

.hasStatusBarShadow(true) //启用状态栏阴影

.asCustom(drawerPopupView)

.show();

在 RecyclerView 中长按弹出弹窗,这种场景需要 watch 一下 itemView:

CommonAdapter adapter = new CommonAdapter(android.R.layout.simple_list_item_1, data) {

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

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

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

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频 如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)

最后

在这里我和身边一些朋友特意整理了一份快速进阶为Android高级工程师的系统且全面的学习资料。涵盖了Android初级——Android高级架构师进阶必备的一些学习技能。

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。) 移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。** [外链图片转存中…(img-BUZAmVGM-1710508939159)] [外链图片转存中…(img-MGQl4w31-1710508939160)] [外链图片转存中…(img-TG8LBFb0-1710508939160)] [外链图片转存中…(img-PRvcOURs-1710508939161)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频 如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android) [外链图片转存中…(img-liBHJTfd-1710508939161)]

最后

在这里我和身边一些朋友特意整理了一份快速进阶为Android高级工程师的系统且全面的学习资料。涵盖了Android初级——Android高级架构师进阶必备的一些学习技能。

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。) [外链图片转存中…(img-6YiJhFsM-1710508939162)] 本文在开源项目:【GitHub 】中已收录,里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…

参考链接

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