diff --git a/README.OPENSOURCE b/README.OPENSOURCE
index 1a224340d1ccd524f747ab8aa48052e779be2446..c390449bf510ea00d59b6bd6b808b4b16a533474 100644
--- a/README.OPENSOURCE
+++ b/README.OPENSOURCE
@@ -4,7 +4,7 @@
"License": "Apache License",
"License File": " LICENSE ",
"Version Number": "2.3.2",
- "Upstream URL": "https://github.com/li-xiaojun/XPopup/archive/1906806f1e33ab4ae6758dff84643ad1b4cab280.zip",
+ "Upstream URL": "https://github.com/li-xiaojun/XPopup",
"Description": "Powerful, interactive, and silky general pop-up window"
}
]
diff --git a/README.md b/README.md
index 3b26e28e0cb01eb2e3f0ddcd4fa6f0e8ba894c20..1f6b4b2f543ccae52098dd7baddbbad902f1af5c 100644
--- a/README.md
+++ b/README.md
@@ -31,13 +31,13 @@
|:---:|:---:|
|
|
|
-|Drawer弹窗| 全屏弹窗(可作为Ability替代品,搭配十几个动画使用更佳)|
+|自定义底部弹窗| 全屏弹窗(可作为Ability替代品)|
|:---:|:---:|
-|
|
|
+|
|
|
-|Position自由定位弹窗(放在屏幕任意地方) | 自定义底部弹窗|
+|Position自由定位弹窗(放在屏幕任意地方) | Drawer弹窗|
|:---:|:---:|
-|
|
|
+|
|
|
|自定义弹窗和自定义动画 | 内置优雅美观的动画器,可搭配弹窗结合使用|
|:---:|:---:|
@@ -66,7 +66,7 @@ allprojects{
mavenCentral()
}
}
-implementation 'io.openharmony.tpc.thirdlib:XPopup:1.0.9'
+implementation 'io.openharmony.tpc.thirdlib:XPopup:1.1.0'
```
## entry运行要求
diff --git a/changelog.md b/changelog.md
index 811e1eb92005ce11439d12eef115336e3280c660..ec892f81d856edb22f850be8fc21bba5cdbacf24 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,4 +1,11 @@
-## 1.0.9
+##1.1.0
+1.解决弹窗被软键盘遮盖的问题
+
+2.解决弹窗destroy后不释放资源的问题
+
+3.解决部分弹窗会出现双重阴影背景的问题
+
+## 1.0.9
1.修复dialog模式设置返回键不关闭弹窗功能失效的问题
2.修复Attach弹窗在不同设备下显示位置不同的问题
@@ -54,11 +61,13 @@
11.设置按下返回键、点击弹窗外面是否关闭弹窗
-12.设置是否自动打开输入法(暂时仅Dialog模式支持)
+12.Popup移动到软键盘上面
-13.设置是否半透明背景(暂时仅Component模式支持)
+13.设置是否自动打开输入法(暂时仅Dialog模式支持)
-14.设置是否点击事件透传(暂时仅Component模式支持,滑动事件暂时无法拦截)
+14.设置是否半透明背景(暂时仅Component模式支持)
+
+15.设置是否点击事件透传(暂时仅Component模式支持,滑动事件暂时无法拦截)
未支持部分:
@@ -72,12 +81,10 @@
5.应用后台弹出Xpopup
-6.Popup移动到软键盘上面
-
-7.设置是否高斯模糊背景
+6.设置是否高斯模糊背景
-8.设置是否显示状态栏阴影
+7.设置是否显示状态栏阴影
-9.设置是否显示状态栏
+8.设置是否显示状态栏
-10.设置是否显示导航栏
\ No newline at end of file
+9.设置是否显示导航栏
\ No newline at end of file
diff --git a/entry/src/main/java/com/lxj/xpopupdemo/MainAbility.java b/entry/src/main/java/com/lxj/xpopupdemo/MainAbility.java
index 4355b858a12ee5e09161ce0e62b38a274672d2a1..59d1aff632214f1d5a3b5e4b5ce19fc8adb8c7af 100644
--- a/entry/src/main/java/com/lxj/xpopupdemo/MainAbility.java
+++ b/entry/src/main/java/com/lxj/xpopupdemo/MainAbility.java
@@ -4,7 +4,9 @@ import com.lxj.xpopup.XPopup;
import com.lxj.xpopup.core.BasePopupView;
import com.lxj.xpopup.impl.LoadingPopupView;
import com.lxj.xpopup.util.ElementUtil;
+import com.lxj.xpopup.util.LogUtil;
import com.lxj.xpopup.util.XPermission;
+import com.lxj.xpopup.util.XPopupUtils;
import com.lxj.xpopupdemo.stackLayout.AllAnimatorDemo;
import com.lxj.xpopupdemo.stackLayout.CustomAnimatorDemo;
import com.lxj.xpopupdemo.stackLayout.CustomPopupDemo;
@@ -19,7 +21,10 @@ import ohos.agp.components.PageSlider;
import ohos.agp.components.PageSliderProvider;
import ohos.agp.components.RadioButton;
import ohos.agp.components.RadioContainer;
+import ohos.eventhandler.EventHandler;
+import ohos.eventhandler.EventRunner;
import ohos.multimodalinput.event.KeyEvent;
+import ohos.system.version.SystemVersion;
import java.util.ArrayList;
@@ -33,7 +38,6 @@ public class MainAbility extends Ability {
ArrayList pageview;
RadioContainer radioContainer;
private PageSlider pageSlider;
- private Component content;
@Override
public void onStart(Intent intent) {
@@ -43,8 +47,7 @@ public class MainAbility extends Ability {
StatusBarUtils.setStatusBarColor(this, ElementUtil.getColor(this, ResourceTable.Color_colorBar));
// 暂未实现的效果先移除出去
((RadioContainer) findComponentById(ResourceTable.Id_radio_container)).removeComponentById(ResourceTable.Id_rb_jubu);
- content = findComponentById(ResourceTable.Id_content);
- QuickStartDemo view0 = new QuickStartDemo(this, content);
+ QuickStartDemo view0 = new QuickStartDemo(this);
ComponentContainer view1 = new PartShadowDemo(this);
ComponentContainer view2 = new ImageViewerDemo(this);
ComponentContainer view3 = new AllAnimatorDemo(this);
@@ -69,6 +72,18 @@ public class MainAbility extends Ability {
loadingPopupView.show();
loadingPopupView.delayDismiss(1200);
+ new EventHandler(EventRunner.getMainEventRunner()).postTask(new Runnable() {
+ @Override
+ public void run() {
+ String str = "deviceHeight:" + XPopupUtils.getScreenHeight(MainAbility.this)
+ + " hapHeight:" + XPopupUtils.getAppHeight(MainAbility.this)
+ + " statusHeight:" + XPopupUtils.getStatusBarHeight(radioContainer)
+ + " navHeight:" + XPopupUtils.getNavBarHeight(radioContainer)
+ + " 设备SDK版本:" + SystemVersion.getApiVersion();
+ LogUtil.debug("XPopup", str);
+ }
+ }, 100);
+
// 数据适配器
PageSliderProvider mPagerAdapter = new PageSliderProvider() {
@Override
diff --git a/entry/src/main/java/com/lxj/xpopupdemo/custom/PagerBottomPopup.java b/entry/src/main/java/com/lxj/xpopupdemo/custom/PagerBottomPopup.java
index 18abb468fd005dd2f861a1d0c983bb93e0f1d9a3..9b6326a21bd4376178ef8102f020cbc5f3ba92b9 100644
--- a/entry/src/main/java/com/lxj/xpopupdemo/custom/PagerBottomPopup.java
+++ b/entry/src/main/java/com/lxj/xpopupdemo/custom/PagerBottomPopup.java
@@ -51,7 +51,7 @@ public class PagerBottomPopup extends BottomPopupView {
@Override
protected int getMaxHeight() {
- return (int) (XPopupUtils.getScreenHeight(getContext()) * .85f);
+ return (int) (XPopupUtils.getAppHeight(getContext()) * .85f);
}
class PAdapter extends PageSliderProvider {
diff --git a/entry/src/main/java/com/lxj/xpopupdemo/custom/ZhihuCommentPopup.java b/entry/src/main/java/com/lxj/xpopupdemo/custom/ZhihuCommentPopup.java
index 28fd1eed6d4d59b73807411f9b3b98017697eb22..c0e74cbc5e1d9d963284198858809a309c447b84 100644
--- a/entry/src/main/java/com/lxj/xpopupdemo/custom/ZhihuCommentPopup.java
+++ b/entry/src/main/java/com/lxj/xpopupdemo/custom/ZhihuCommentPopup.java
@@ -45,6 +45,7 @@ public class ZhihuCommentPopup extends BottomPopupView {
final CustomEditTextBottomPopup textBottomPopup = new CustomEditTextBottomPopup(getContext());
new XPopup.Builder(getContext())
.autoOpenSoftInput(true)
+ .setComponent(ZhihuCommentPopup.this) // 用于获取页面根容器,监听页面高度变化,解决输入法盖住弹窗的问题
.setPopupCallback(new SimpleCallback() {
@Override
public void onShow(BasePopupView popupView) {
@@ -106,6 +107,6 @@ public class ZhihuCommentPopup extends BottomPopupView {
@Override
protected int getMaxHeight() {
- return (int) (XPopupUtils.getScreenHeight(getContext()) * .7f);
+ return (int) (XPopupUtils.getAppHeight(getContext()) * .7f);
}
}
\ No newline at end of file
diff --git a/entry/src/main/java/com/lxj/xpopupdemo/stackLayout/CustomPopupDemo.java b/entry/src/main/java/com/lxj/xpopupdemo/stackLayout/CustomPopupDemo.java
index 7a8b5c2123a3b304f4995d1c67c9065ff74b3d2e..5fddd233ba5eff4f7b33ca7df80857dd76ac5d7e 100644
--- a/entry/src/main/java/com/lxj/xpopupdemo/stackLayout/CustomPopupDemo.java
+++ b/entry/src/main/java/com/lxj/xpopupdemo/stackLayout/CustomPopupDemo.java
@@ -56,6 +56,7 @@ public class CustomPopupDemo extends BaseStackLayout {
new XPopup.Builder(getContext())
.popupAnimation(data[position])
.autoOpenSoftInput(true)
+ .setComponent(listContainer) // 用于获取页面根容器,监听页面高度变化,解决输入法盖住弹窗的问题
.asCustom(customPopup)
.show();
}
diff --git a/entry/src/main/java/com/lxj/xpopupdemo/stackLayout/QuickStartDemo.java b/entry/src/main/java/com/lxj/xpopupdemo/stackLayout/QuickStartDemo.java
index 947c49f3d79fa12b5a151d088972e5f857da5684..70ec5971aa45499be9f8994f073359105c6910bb 100644
--- a/entry/src/main/java/com/lxj/xpopupdemo/stackLayout/QuickStartDemo.java
+++ b/entry/src/main/java/com/lxj/xpopupdemo/stackLayout/QuickStartDemo.java
@@ -33,11 +33,9 @@ import ohos.hiviewdfx.HiLogLabel;
public class QuickStartDemo extends BaseStackLayout implements Component.ClickedListener {
private static final String TAG = QuickStartDemo.class.getName();
- private Component content;
- public QuickStartDemo(Context context, Component content) {
+ public QuickStartDemo(Context context) {
super(context);
- this.content = content;
}
@Override
@@ -100,7 +98,8 @@ public class QuickStartDemo extends BaseStackLayout implements Component.Clicked
popupView = new XPopup.Builder(getContext())
.dismissOnBackPressed(false) // 点击返回键是否消失
.dismissOnTouchOutside(true) // 点击外部是否消失
- .isComponentMode(true, content) // Component实现模式
+ .setPopupCallback(new DemoXPopupListener())
+ .isComponentMode(true, component) // Component实现模式
.asConfirm("哈哈", "床前明月光,疑是地上霜;举头望明月,低头思故乡。",
"取消", "确定",
new OnConfirmListener() {
@@ -131,6 +130,7 @@ public class QuickStartDemo extends BaseStackLayout implements Component.Clicked
.hasStatusBarShadow(false) // 暂无实现
.autoOpenSoftInput(true)
.isDarkTheme(true)
+ .setComponent(component) // 用于获取页面根容器,监听页面高度变化,解决输入法盖住弹窗的问题
.setPopupCallback(new DemoXPopupListener())
.asInputConfirm("我是标题", null, null, "我是默认Hint文字",
new OnInputConfirmListener() {
@@ -235,7 +235,7 @@ public class QuickStartDemo extends BaseStackLayout implements Component.Clicked
.hasShadowBg(false)
.isDestroyOnDismiss(true) // 对于只使用一次的弹窗,推荐设置这个
.atView(component) // 依附于所点击的View,内部会自动判断在上方或者下方显示
- .isComponentMode(true, content) // Component实现模式
+ .isComponentMode(true, component) // Component实现模式
.asAttachList(new String[]{"分享", "编辑", "不带icon不带icon", "分享分享分享"},
new int[]{ResourceTable.Media_icon, ResourceTable.Media_icon},
new OnSelectListener() {
@@ -249,7 +249,7 @@ public class QuickStartDemo extends BaseStackLayout implements Component.Clicked
new XPopup.Builder(getContext())
.hasShadowBg(false) // 去掉半透明背景
.atView(component)
- .isComponentMode(true, content) // Component实现模式
+ .isComponentMode(true, component) // Component实现模式
.asCustom(new CustomAttachPopup(getContext()))
.show();
break;
@@ -258,7 +258,7 @@ public class QuickStartDemo extends BaseStackLayout implements Component.Clicked
.isDestroyOnDismiss(true) // 对于只使用一次的弹窗,推荐设置这个
.atView(component)
.hasShadowBg(false) // 去掉半透明背景
- .isComponentMode(true, content) // Component实现模式
+ .isComponentMode(true, component) // Component实现模式
.asCustom(new CustomAttachPopup2(getContext())).show();
break;
case ResourceTable.Id_btnShowDrawerLeft: // 像DrawerLayout一样的Drawer弹窗
@@ -279,6 +279,7 @@ public class QuickStartDemo extends BaseStackLayout implements Component.Clicked
new XPopup.Builder(getContext())
.hasStatusBarShadow(true)
.autoOpenSoftInput(true)
+ .setComponent(component) // 用于获取页面根容器,监听页面高度变化,解决输入法盖住弹窗的问题
.asCustom(new CustomFullScreenPopup(getContext()))
.show();
break;
@@ -286,6 +287,7 @@ public class QuickStartDemo extends BaseStackLayout implements Component.Clicked
new XPopup.Builder(getContext())
.autoOpenSoftInput(true)
.isDestroyOnDismiss(true) // 对于只使用一次的弹窗,推荐设置这个
+ .setComponent(component) // 用于获取页面根容器,监听页面高度变化,解决输入法盖住弹窗的问题
.asCustom(new CustomEditTextBottomPopup(getContext()))
.show();
break;
diff --git a/entry/src/main/resources/base/layout/ability_main.xml b/entry/src/main/resources/base/layout/ability_main.xml
index fef22494d4d0aae2e945b161bf6afa317755f3c5..4f97a094736a164e65a145177c7fb2a418168913 100644
--- a/entry/src/main/resources/base/layout/ability_main.xml
+++ b/entry/src/main/resources/base/layout/ability_main.xml
@@ -1,7 +1,6 @@
@@ -11,7 +10,7 @@
ohos:width="match_parent"
ohos:background_element="$color:colorBar"
ohos:padding="16vp"
- ohos:text="XPopup-1.0.8"
+ ohos:text="XPopup-1.1.0"
ohos:text_color="#fff"
ohos:text_size="20fp"
ohos:text_weight="600"/>
diff --git a/library/src/main/java/com/lxj/xpopup/XPopup.java b/library/src/main/java/com/lxj/xpopup/XPopup.java
index 882faf22c317dd9ddc977ccdb6c0cf23bb8970d5..5d086ed0f98d40c656fcac34cfefe42587374c83 100644
--- a/library/src/main/java/com/lxj/xpopup/XPopup.java
+++ b/library/src/main/java/com/lxj/xpopup/XPopup.java
@@ -30,6 +30,7 @@ import com.lxj.xpopup.util.EventUtil;
import com.lxj.xpopup.util.LogUtil;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.Component;
+import ohos.agp.components.ComponentContainer;
import ohos.agp.components.Image;
import ohos.agp.render.render3d.math.Quaternion;
import ohos.agp.utils.LayoutAlignment;
@@ -95,7 +96,7 @@ public class XPopup {
}
if ("xpopup".equals(component.getTag()) && event.getAction() == TouchEvent.POINT_MOVE) {
// 长按发送,阻断父View拦截
- LogUtil.debug("XPopup", "后修完善");
+ LogUtil.debug("XPopup", "后续完善");
}
if (event.getAction() == TouchEvent.PRIMARY_POINT_UP) {
// 长按结束,恢复阻断
@@ -259,7 +260,7 @@ public class XPopup {
/**
* 是否自动打开输入法,当弹窗包含输入框时很有用,默认为false
*
- * @param autoOpenSoftInput 是否自动打开输入法,暂未实现
+ * @param autoOpenSoftInput 是否自动打开输入法
* @return Builder构造器对象
*/
public Builder autoOpenSoftInput(Boolean autoOpenSoftInput) {
@@ -270,7 +271,7 @@ public class XPopup {
/**
* 当弹出输入法时,弹窗是否要移动到输入法之上,默认为true。如果不移动,弹窗很有可能被输入法盖住
*
- * @param isMoveUpToKeyboard 当弹出输入法时,弹窗是否要移动到输入法之上,暂未实现
+ * @param isMoveUpToKeyboard 当弹出输入法时,弹窗是否要移动到输入法之上
* @return Builder构造器对象
*/
public Builder moveUpToKeyboard(Boolean isMoveUpToKeyboard) {
@@ -475,12 +476,30 @@ public class XPopup {
* XPopup的弹窗默认是Dialog实现,该方法设置为true则切换为Component实现
*
* @param componentMode 是否是Component实现,默认是false
- * @param contentRoot Component实现时需要传入Ability根布局(控件)
- * @return
+ * @param comonent Component实现时需要传入Ability根布局中的任意一个控件
+ * @return Builder构造器对象
+ */
+ public Builder isComponentMode(boolean componentMode, Component comonent) {
+ ComponentContainer decorView = ComponentUtil.getDecorView(comonent);
+ this.popupInfo.isComponentMode = componentMode && decorView != null;
+ if (decorView != null) {
+ this.popupInfo.contentRoot = decorView.getComponentAt(0);
+ }
+ return this;
+ }
+
+ /**
+ * 获取页面根容器,用于监听软键盘的高度变化0
+ * 若弹窗中没有会被软键盘遮盖住的TextFiled控件,则无需调用此方法
+ *
+ * @param comonent 页面中的任意一个控件
+ * @return Builder构造器对象
*/
- public Builder isComponentMode(boolean componentMode, Component contentRoot) {
- this.popupInfo.isComponentMode = contentRoot != null;
- this.popupInfo.contentRoot = contentRoot;
+ public Builder setComponent(Component comonent) {
+ ComponentContainer decorView = ComponentUtil.getDecorView(comonent);
+ if (decorView != null) {
+ this.popupInfo.contentRoot = decorView.getComponentAt(0);
+ }
return this;
}
diff --git a/library/src/main/java/com/lxj/xpopup/core/AttachPopupView.java b/library/src/main/java/com/lxj/xpopup/core/AttachPopupView.java
index b117f109c2a8fafccab4377a6b1848f8ee704c2b..90929dbac1721e3a760ddf16f412238d3bd0969c 100644
--- a/library/src/main/java/com/lxj/xpopup/core/AttachPopupView.java
+++ b/library/src/main/java/com/lxj/xpopup/core/AttachPopupView.java
@@ -98,12 +98,12 @@ public abstract class AttachPopupView extends BasePopupView {
public float translationY = 0;
// 弹窗显示的位置不能超越Window高度
- float maxY = XPopupUtils.getScreenHeight(getContext());
+ float maxY = XPopupUtils.getAppHeight(getContext());
int overflow = XPopupUtils.vp2px(getContext(), 10);
float centerY = 0;
public void doAttach() {
- maxY = XPopupUtils.getScreenHeight(getContext()) - overflow;
+ maxY = XPopupUtils.getAppHeight(getContext()) - overflow;
final boolean isRTL = XPopupUtils.isLayoutRtl(getContext());
// 0. 判断是依附于某个点还是某个View
if (popupInfo.touchPoint != null) {
@@ -113,7 +113,7 @@ public abstract class AttachPopupView extends BasePopupView {
centerY = popupInfo.touchPoint.getY();
// 依附于指定点,尽量优先放在下方,当不够的时候在显示在上方
if ((popupInfo.touchPoint.getY() + getPopupContentView().getHeight()) > maxY) { // 如果下方放不下,超出window高度
- isShowUp = popupInfo.touchPoint.getY() > XPopupUtils.getScreenHeight(getContext()) / 2;
+ isShowUp = popupInfo.touchPoint.getY() > XPopupUtils.getAppHeight(getContext()) / 2;
} else {
isShowUp = false;
}
@@ -122,7 +122,7 @@ public abstract class AttachPopupView extends BasePopupView {
// 限制最大宽高
ComponentContainer.LayoutConfig params = getPopupContentView().getLayoutConfig();
int maxHeight = (int) (isShowUpToTarget() ? (popupInfo.touchPoint.getY() - overflow)
- : (XPopupUtils.getScreenHeight(getContext()) - popupInfo.touchPoint.getY() - overflow));
+ : (XPopupUtils.getAppHeight(getContext()) - popupInfo.touchPoint.getY() - overflow));
int maxWidth = (int) (isShowLeft ? (XPopupUtils.getWindowWidth(getContext()) - popupInfo.touchPoint.getX() - overflow) : (popupInfo.touchPoint.getX() - overflow));
if (getPopupContentView().getHeight() > maxHeight) {
params.height = maxHeight;
@@ -185,7 +185,7 @@ public abstract class AttachPopupView extends BasePopupView {
// 修正高度,弹窗的高有可能超出window区域
ComponentContainer.LayoutConfig params = getPopupContentView().getLayoutConfig();
- int maxHeight = isShowUpToTarget() ? (rect.top - overflow) : (XPopupUtils.getScreenHeight(getContext()) - rect.bottom - overflow);
+ int maxHeight = isShowUpToTarget() ? (rect.top - overflow) : (XPopupUtils.getAppHeight(getContext()) - rect.bottom - overflow);
int maxWidth = isShowLeft ? (XPopupUtils.getWindowWidth(getContext()) - rect.left - overflow) : (rect.right - overflow);
if (getPopupContentView().getHeight() > maxHeight) {
params.height = maxHeight;
@@ -194,7 +194,6 @@ public abstract class AttachPopupView extends BasePopupView {
params.width = maxWidth;
}
getPopupContentView().setLayoutConfig(params);
-
if (isRTL) {
translationX = isShowLeft ? -(XPopupUtils.getWindowWidth(getContext()) - rect.left - getPopupContentView().getWidth() - defaultOffsetX)
: -(XPopupUtils.getWindowWidth(getContext()) - rect.right + defaultOffsetX);
@@ -240,7 +239,7 @@ public abstract class AttachPopupView extends BasePopupView {
protected boolean isShowUpToTarget() {
if (popupInfo.positionByWindowCenter) {
// 目标在屏幕上半方,弹窗显示在下;反之,则在上
- return centerY > XPopupUtils.getScreenHeight(getContext()) / 2;
+ return centerY > XPopupUtils.getAppHeight(getContext()) / 2;
}
// 默认是根据Material规范定位,优先显示在目标下方,下方距离不足才显示在上方
return (isShowUp || popupInfo.popupPosition == PopupPosition.Top)
diff --git a/library/src/main/java/com/lxj/xpopup/core/BasePopupView.java b/library/src/main/java/com/lxj/xpopup/core/BasePopupView.java
index 8075f2c9d5181916d07c5ccac14ed42a10765dfa..9ef3ba73b99d338c604a626714a1305e91ee6ad5 100644
--- a/library/src/main/java/com/lxj/xpopup/core/BasePopupView.java
+++ b/library/src/main/java/com/lxj/xpopup/core/BasePopupView.java
@@ -11,17 +11,15 @@ import com.lxj.xpopup.animator.ShadowBgAnimator;
import com.lxj.xpopup.animator.TranslateAlphaAnimator;
import com.lxj.xpopup.animator.TranslateAnimator;
import com.lxj.xpopup.enums.PopupStatus;
+import com.lxj.xpopup.impl.FullScreenPopupView;
import com.lxj.xpopup.impl.PartShadowPopupView;
+import com.lxj.xpopup.util.ComponentUtil;
import com.lxj.xpopup.util.EventUtil;
import com.lxj.xpopup.util.KeyboardUtils;
-import com.lxj.xpopup.util.LogUtil;
import com.lxj.xpopup.util.XPopupUtils;
import com.lxj.xpopup.widget.ShadowLayout;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.ability.AbilityPackage;
-import ohos.aafwk.ability.Lifecycle;
-import ohos.aafwk.ability.LifecycleStateObserver;
-import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.Component.BindStateChangedListener;
import ohos.agp.components.ComponentContainer;
@@ -44,7 +42,7 @@ import static com.lxj.xpopup.enums.PopupAnimation.NoAnimation;
* Description: 弹窗基类
* Create by lxj, at 2018/12/7
*/
-public abstract class BasePopupView extends StackLayout implements BindStateChangedListener, Component.TouchEventListener, LifecycleStateObserver {
+public abstract class BasePopupView extends StackLayout implements BindStateChangedListener, Component.TouchEventListener {
public PopupInfo popupInfo;
protected PopupAnimator popupContentAnimator;
@@ -54,6 +52,7 @@ public abstract class BasePopupView extends StackLayout implements BindStateChan
public PopupStatus popupStatus = PopupStatus.Dismiss;
protected boolean isCreated = false;
protected ShadowLayout shadowLayout;
+ public boolean hasMoveUp = false;
private EventHandler handler = new EventHandler(EventRunner.getMainEventRunner());
protected static BasePopupView basePopupView;
@@ -136,26 +135,34 @@ public abstract class BasePopupView extends StackLayout implements BindStateChan
};
private void detachFromHost() {
- if (popupInfo != null && popupInfo.isComponentMode) {
+ if (popupInfo != null) {
+ // 先将popup控件移除
ComponentContainer decorView = (ComponentContainer) getComponentParent();
if (decorView != null) {
decorView.removeComponent(this);
}
- } else {
- if (dialog != null) {
- dialog.destroy();
- }
+ }
+ if (dialog != null) {
+ dialog.destroy();
}
}
public Window getHostWindow() {
if (popupInfo != null && popupInfo.isComponentMode) {
- return ((Ability) getContext()).getWindow();
+ return ((Ability) popupInfo.contentRoot.getContext()).getWindow();
} else {
return dialog == null ? null : dialog.getWindow();
}
}
+ protected ComponentContainer getWindowDecorView() {
+ if (popupInfo.contentRoot != null) {
+ return ComponentUtil.getDecorView(popupInfo.contentRoot);
+ } else {
+ return null;
+ }
+ }
+
protected void initAnimator() {
// 优先使用自定义的动画器
if (popupInfo.customAnimator != null) {
@@ -170,7 +177,7 @@ public abstract class BasePopupView extends StackLayout implements BindStateChan
}
// 3. 初始化动画执行器
- if (popupInfo.hasShadowBg) {
+ if (popupInfo.hasShadowBg && !popupInfo.hasBlurBg && popupInfo.isComponentMode) {
shadowBgAnimator.initAnimator();
}
if (popupInfo.hasBlurBg && blurAnimator != null) {
@@ -187,6 +194,10 @@ public abstract class BasePopupView extends StackLayout implements BindStateChan
return this;
}
popupStatus = PopupStatus.Showing;
+ if (popupInfo.isRequestFocus && popupInfo.contentRoot != null) {
+ // 显示弹窗之前,应该隐藏输入法
+ KeyboardUtils.hideSoftInput(popupInfo.contentRoot);
+ }
if (!popupInfo.isComponentMode && dialog != null && dialog.isShowing()) {
return BasePopupView.this;
}
@@ -199,6 +210,32 @@ public abstract class BasePopupView extends StackLayout implements BindStateChan
public void run() {
// 1. add PopupView to its dialog.
attachToHost();
+
+ // 2.注册对话框监听器
+ KeyboardUtils.registerSoftInputChangedListener(BasePopupView.this, new KeyboardUtils.OnSoftInputChangedListener() {
+ @Override
+ public void onSoftInputChanged(int height) {
+ if (popupInfo != null && popupInfo.xPopupCallback != null) {
+ popupInfo.xPopupCallback.onKeyBoardStateChanged(BasePopupView.this, height);
+ }
+ if (height == 0) { // 说明对话框隐藏
+ XPopupUtils.moveDown(BasePopupView.this);
+ } else {
+ // when show keyboard,move up
+ // 全屏弹窗特殊处理,等show之后再移动
+ if (BasePopupView.this instanceof FullScreenPopupView && popupStatus == PopupStatus.Showing) {
+ return;
+ }
+ if (BasePopupView.this instanceof PartShadowPopupView && popupStatus == PopupStatus.Showing) {
+ return;
+ }
+ XPopupUtils.moveUpToKeyboard(height, BasePopupView.this);
+ hasMoveUp = true;
+ }
+ }
+ });
+
+ // 3.do init,game start.
init();
}
};
@@ -206,9 +243,6 @@ public abstract class BasePopupView extends StackLayout implements BindStateChan
public FullScreenDialog dialog;
private void attachToHost() {
- if (getContext() instanceof Ability) {
- ((Ability) getContext()).getLifecycle().addObserver(this);
- }
if (popupInfo != null && popupInfo.isComponentMode) {
// component实现
ComponentContainer decorView = (ComponentContainer) popupInfo.contentRoot.getComponentParent();
@@ -249,8 +283,8 @@ public abstract class BasePopupView extends StackLayout implements BindStateChan
popupInfo.xPopupCallback.onShow(BasePopupView.this);
}
// 再次检测移动距离
- if (dialog != null) {
- LogUtil.debug("XPopup", "waiting for improvement");
+ if (getHostWindow() != null && KeyboardUtils.getSoftInputHeight(BasePopupView.this) > 0 && !hasMoveUp) {
+ XPopupUtils.moveUpToKeyboard(KeyboardUtils.getSoftInputHeight(BasePopupView.this), BasePopupView.this);
}
}
};
@@ -625,8 +659,10 @@ public abstract class BasePopupView extends StackLayout implements BindStateChan
if (popupInfo.isRequestFocus) {
// 让根布局拿焦点,避免布局内RecyclerView类似布局获取焦点导致布局滚动
- if (popupInfo.decorView != null) {
- LogUtil.debug("XPopup", "waiting for improvement");
+ ComponentContainer windowDecorView = getWindowDecorView();
+ if (windowDecorView != null) {
+ windowDecorView.setFocusable(FOCUS_ADAPTABLE);
+ windowDecorView.setTouchFocusable(true);
}
}
@@ -676,17 +712,6 @@ public abstract class BasePopupView extends StackLayout implements BindStateChan
protected void onShow() {
}
- @Override
- public void onStateChanged(Lifecycle.Event event, Intent intent) {
- onDestroy();
- }
-
- public void onDestroy() {
- onComponentUnboundFromWindow(null);
- detachFromHost();
- destroy();
- }
-
public void destroy() {
if (popupInfo != null) {
popupInfo.atView = null;
@@ -700,9 +725,6 @@ public abstract class BasePopupView extends StackLayout implements BindStateChan
dialog.contentView = null;
dialog = null;
}
- if (getContext() != null && getContext() instanceof Ability) {
- ((Ability) getContext()).getLifecycle().removeObserver(this);
- }
if (blurAnimator != null && blurAnimator.decorBitmap != null) {
if (!blurAnimator.decorBitmap.isReleased()) {
blurAnimator.decorBitmap.release();
@@ -718,9 +740,7 @@ public abstract class BasePopupView extends StackLayout implements BindStateChan
public void onComponentUnboundFromWindow(Component component) {
handler.removeAllEvent();
if (popupInfo != null) {
- if (popupInfo.decorView != null) {
- KeyboardUtils.removeLayoutChangeListener(popupInfo.decorView, BasePopupView.this);
- }
+ KeyboardUtils.removeLayoutChangeListener(BasePopupView.this);
if (!popupInfo.isComponentMode && dialog != null && dialog.isShowing()) {
dialog.destroy();
}
@@ -728,9 +748,6 @@ public abstract class BasePopupView extends StackLayout implements BindStateChan
destroy();
}
}
- if (getContext() != null && getContext() instanceof Ability) {
- ((Ability) getContext()).getLifecycle().removeObserver(this);
- }
popupStatus = PopupStatus.Dismiss;
showSoftInputTask = null;
}
diff --git a/library/src/main/java/com/lxj/xpopup/core/BottomPopupView.java b/library/src/main/java/com/lxj/xpopup/core/BottomPopupView.java
index 724a62efae46e1bd3522a5349b5a76208d2f0baf..9718c13e181a0195fbca9d53d9f4d2615a85fb88 100644
--- a/library/src/main/java/com/lxj/xpopup/core/BottomPopupView.java
+++ b/library/src/main/java/com/lxj/xpopup/core/BottomPopupView.java
@@ -62,7 +62,7 @@ public class BottomPopupView extends BasePopupView {
if (popupInfo.xPopupCallback != null) {
popupInfo.xPopupCallback.onDrag(BottomPopupView.this, value, percent, isScrollUp);
}
- if (popupInfo.hasShadowBg && !popupInfo.hasBlurBg) {
+ if (popupInfo.hasShadowBg && !popupInfo.hasBlurBg && popupInfo.isComponentMode) {
setBackground(ElementUtil.getShapeElement(shadowBgAnimator.calculateBgColor(percent)));
}
}
@@ -105,7 +105,7 @@ public class BottomPopupView extends BasePopupView {
@Override
protected PopupAnimator getPopupAnimator() {
- return new TranslateAnimator(getPopupContentView(), PopupAnimation.TranslateFromBottom);
+ return new TranslateAnimator(getPopupImplView(), PopupAnimation.TranslateFromBottom);
}
@Override
diff --git a/library/src/main/java/com/lxj/xpopup/core/DrawerPopupView.java b/library/src/main/java/com/lxj/xpopup/core/DrawerPopupView.java
index 9b16de106a09e4a812cc6d3e7bafeaad56fb9328..5ef8f21105e0ae941d40c09cf7217ccb90a2792b 100644
--- a/library/src/main/java/com/lxj/xpopup/core/DrawerPopupView.java
+++ b/library/src/main/java/com/lxj/xpopup/core/DrawerPopupView.java
@@ -44,7 +44,7 @@ public abstract class DrawerPopupView extends BasePopupView {
super.initPopupContent();
getPopupImplView().setTranslationX(popupInfo.offsetX);
getPopupImplView().setTranslationY(popupInfo.offsetY);
- drawerLayout.hasShadowBg(popupInfo.hasShadowBg);
+ drawerLayout.hasShadowBg(popupInfo.hasShadowBg && popupInfo.isComponentMode);
drawerLayout.dismissOnTouchOutside(popupInfo.isDismissOnTouchOutside);
drawerLayout.setDrawerPosition(popupInfo.popupPosition == null ? PopupPosition.Left : popupInfo.popupPosition);
drawerLayout.enableDrag(popupInfo.enableDrag);
diff --git a/library/src/main/java/com/lxj/xpopup/core/FullScreenDialog.java b/library/src/main/java/com/lxj/xpopup/core/FullScreenDialog.java
index dd177d1c378c3b95e4753bc87cfa61f71c82039c..c879a1e2180a8300163b30e2ebd286513d438eb1 100644
--- a/library/src/main/java/com/lxj/xpopup/core/FullScreenDialog.java
+++ b/library/src/main/java/com/lxj/xpopup/core/FullScreenDialog.java
@@ -1,7 +1,7 @@
package com.lxj.xpopup.core;
import com.lxj.xpopup.util.LogUtil;
-import com.lxj.xpopup.util.WindowUtil;
+import com.lxj.xpopup.util.XPopupUtils;
import ohos.agp.components.ComponentContainer;
import ohos.agp.window.dialog.CommonDialog;
import ohos.agp.window.service.WindowManager;
@@ -30,7 +30,7 @@ public class FullScreenDialog extends CommonDialog {
getWindow().setLayoutConfig(layoutConfig);
}
setTransparent(true);
- setSize(WindowUtil.getWindowWdith(context), WindowUtil.getWindowHeight(context));
+ setSize(XPopupUtils.getWindowWidth(context), XPopupUtils.getAppHeight(context));
if (!contentView.popupInfo.isRequestFocus) {
// 不获取焦点
LogUtil.debug("XPopup", "waiting for improvement");
diff --git a/library/src/main/java/com/lxj/xpopup/core/PopupInfo.java b/library/src/main/java/com/lxj/xpopup/core/PopupInfo.java
index 1971bf3c9a8c94f666e901280af3861022a831d9..dfd5e547057b3eee96cac3bb2f6f322dd910f8d0 100644
--- a/library/src/main/java/com/lxj/xpopup/core/PopupInfo.java
+++ b/library/src/main/java/com/lxj/xpopup/core/PopupInfo.java
@@ -54,7 +54,7 @@ public class PopupInfo {
public boolean isDestroyOnDismiss = false; // 是否关闭后进行资源释放
public boolean positionByWindowCenter = false; // 是否已屏幕中心进行定位,默认根据Material范式进行定位
public boolean isComponentMode = false; // 是否是Component实现,默认是Dialog实现
- public Component contentRoot; // Component实现时需要传入Ability根布局(控件)
+ public Component contentRoot; // Component实现和监听软键盘高度变化时需要获取Ability根布局(控件)
public Component getAtView() {
return atView;
diff --git a/library/src/main/java/com/lxj/xpopup/util/ComponentUtil.java b/library/src/main/java/com/lxj/xpopup/util/ComponentUtil.java
index 7864c122e309696def0d5534eed39063800e81d0..006f28912b9630a103405246dadf0750357f7e23 100644
--- a/library/src/main/java/com/lxj/xpopup/util/ComponentUtil.java
+++ b/library/src/main/java/com/lxj/xpopup/util/ComponentUtil.java
@@ -15,6 +15,7 @@
package com.lxj.xpopup.util;
import ohos.agp.components.Component;
+import ohos.agp.components.ComponentContainer;
import ohos.agp.components.ComponentParent;
import ohos.agp.utils.Rect;
@@ -47,12 +48,16 @@ public class ComponentUtil {
* @param component 根容器中的任意一个控件
* @return 根容器
*/
- public static Component getDecorView(Component component) {
- ComponentParent componentParent = component.getComponentParent();
- if (componentParent == null) {
- return component;
+ public static ComponentContainer getDecorView(Component component) {
+ if (component != null) {
+ ComponentParent componentParent = component.getComponentParent();
+ if (componentParent == null) {
+ return (ComponentContainer) component;
+ } else {
+ return getDecorView((Component) componentParent);
+ }
} else {
- return getDecorView((Component) componentParent);
+ return null;
}
}
}
diff --git a/library/src/main/java/com/lxj/xpopup/util/KeyboardUtils.java b/library/src/main/java/com/lxj/xpopup/util/KeyboardUtils.java
index 28080db5e72a2fee7948cbe2975c8e4e2ee17cd1..59443f8002101d9f515d14b1eb548442fc424dc0 100644
--- a/library/src/main/java/com/lxj/xpopup/util/KeyboardUtils.java
+++ b/library/src/main/java/com/lxj/xpopup/util/KeyboardUtils.java
@@ -3,6 +3,10 @@ package com.lxj.xpopup.util;
import com.lxj.xpopup.core.BasePopupView;
import ohos.agp.components.Component;
import ohos.agp.components.TextField;
+import ohos.agp.utils.Rect;
+
+import java.util.ArrayList;
+import java.util.HashMap;
/**
* Description:
@@ -11,13 +15,61 @@ import ohos.agp.components.TextField;
public final class KeyboardUtils {
public static int sDecorViewInvisibleHeightPre;
+ private static HashMap listenerMap = new HashMap<>();
private KeyboardUtils() {
- throw new UnsupportedOperationException("u can't instantiate me...");
+
+ }
+
+ /**
+ * Register soft input changed listener.
+ *
+ * @param listener The soft input changed listener.
+ */
+ public static void registerSoftInputChangedListener(final BasePopupView popupView, final OnSoftInputChangedListener listener) {
+ sDecorViewInvisibleHeightPre = getSoftInputHeight(popupView);
+ listenerMap.put(popupView, listener);
+
+ if (popupView.popupInfo.contentRoot != null) {
+ // 设置了页面根容器,则用页面根容器监听页面高度变化
+ popupView.popupInfo.contentRoot.setLayoutRefreshedListener(new Component.LayoutRefreshedListener() {
+ @Override
+ public void onRefreshed(Component component) {
+ component.getContext().getUITaskDispatcher().delayDispatch(new Runnable() {
+ @Override
+ public void run() {
+ int height = getSoftInputHeight(popupView);
+ if (sDecorViewInvisibleHeightPre != height) {
+ //通知所有弹窗的监听器输入法高度变化了
+ for (OnSoftInputChangedListener changedListener : listenerMap.values()) {
+ changedListener.onSoftInputChanged(height);
+ }
+ sDecorViewInvisibleHeightPre = height;
+ }
+ }
+ }, 10);
+ }
+ });
+ } else {
+ // 没有页面根容器,则无法监听软键盘高度变化
+ LogUtil.debug("XPopup", "如果要监听软键盘高度变化,请调用.setComponent(component)方法设置一个页面中的控件");
+ }
}
- public static void removeLayoutChangeListener(Component decorView, BasePopupView popupView) {
+ public static void removeLayoutChangeListener(BasePopupView popupView) {
+ listenerMap.remove(popupView);
+ }
+ /**
+ * 获取软键盘的高度
+ *
+ * @param component 任意一个页面中的控件
+ * @return 高度,单位px
+ */
+ public static int getSoftInputHeight(Component component) {
+ Rect rect = new Rect();
+ component.getWindowVisibleRect(rect);
+ return rect.bottom == 0 ? 0 : XPopupUtils.getScreenHeight(component.getContext()) - rect.bottom;
}
/**
@@ -32,8 +84,19 @@ public final class KeyboardUtils {
}
}
+ /**
+ * 隐藏输入法
+ *
+ * @param component 布局中的任意一个控件
+ */
public static void hideSoftInput(Component component) {
-
+ if (component != null) {
+ ArrayList textFields = new ArrayList<>();
+ XPopupUtils.findAllEditText(textFields, ComponentUtil.getDecorView(component));
+ for (int i = 0; i < textFields.size(); i++) {
+ textFields.get(i).clearFocus();
+ }
+ }
}
public interface OnSoftInputChangedListener {
diff --git a/library/src/main/java/com/lxj/xpopup/util/WindowUtil.java b/library/src/main/java/com/lxj/xpopup/util/WindowUtil.java
deleted file mode 100644
index 6e276744c9cf38bdabe586f2dd23c23643366f52..0000000000000000000000000000000000000000
--- a/library/src/main/java/com/lxj/xpopup/util/WindowUtil.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2021 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.lxj.xpopup.util;
-
-import ohos.app.Context;
-
-/**
- * 窗口工具类
- */
-public class WindowUtil {
-
- /**
- * 获取屏幕宽度
- *
- * @param context 上下文
- * @return 屏幕宽度,单位px
- */
- public static int getWindowWdith(Context context) {
- return context.getResourceManager().getDeviceCapability().width * context.getResourceManager().getDeviceCapability().screenDensity / 160;
- }
-
- /**
- * 获取屏幕高度
- *
- * @param context 上下文
- * @return 屏幕高度,单位px
- */
- public static int getWindowHeight(Context context) {
- return context.getResourceManager().getDeviceCapability().height * context.getResourceManager().getDeviceCapability().screenDensity / 160;
- }
-
-}
diff --git a/library/src/main/java/com/lxj/xpopup/util/XPopupUtils.java b/library/src/main/java/com/lxj/xpopup/util/XPopupUtils.java
index 0c6d43556e24fc6bed439c28e4c9d3ed88b4f7c0..233cbd416ce12348ad3f48b66f5880c4768cba88 100644
--- a/library/src/main/java/com/lxj/xpopup/util/XPopupUtils.java
+++ b/library/src/main/java/com/lxj/xpopup/util/XPopupUtils.java
@@ -1,8 +1,16 @@
package com.lxj.xpopup.util;
import com.lxj.xpopup.core.AttachPopupView;
+import com.lxj.xpopup.core.BasePopupView;
+import com.lxj.xpopup.core.BottomPopupView;
+import com.lxj.xpopup.core.CenterPopupView;
+import com.lxj.xpopup.core.PositionPopupView;
import com.lxj.xpopup.enums.ImageType;
+import com.lxj.xpopup.impl.FullScreenPopupView;
+import com.lxj.xpopup.impl.PartShadowPopupView;
import com.lxj.xpopup.interfaces.XPopupImageLoader;
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
@@ -17,6 +25,8 @@ import ohos.agp.render.Texture;
import ohos.agp.utils.Color;
import ohos.agp.utils.Rect;
import ohos.agp.utils.RectFloat;
+import ohos.agp.window.service.Display;
+import ohos.agp.window.service.DisplayManager;
import ohos.app.Context;
import ohos.app.Environment;
import ohos.eventhandler.EventHandler;
@@ -61,10 +71,22 @@ public class XPopupUtils {
* 获取屏幕的高度,包含状态栏,导航栏
*
* @param context 上下文
- * @return 屏幕的高度,包含状态栏,导航栏
+ * @return 高度,单位px
*/
public static int getScreenHeight(Context context) {
- return context.getResourceManager().getDeviceCapability().height * context.getResourceManager().getDeviceCapability().screenDensity / 160;
+ Display display = DisplayManager.getInstance().getDefaultDisplay(context).get();
+ return display.getRealAttributes().height;
+ }
+
+ /**
+ * 获取应用界面可见高度,不包状态栏、导航栏
+ *
+ * @param context 上下文
+ * @return 高度,单位px
+ */
+ public static int getAppHeight(Context context) {
+ Display display = DisplayManager.getInstance().getDefaultDisplay(context).get();
+ return display.getAttributes().height;
}
/**
@@ -79,13 +101,14 @@ public class XPopupUtils {
}
/**
- * 获取状态栏高度,暂无实现,需要开发者传入
+ * 获取状态栏高度
*
- * @param attachPopupView AttachPopupView
- * @return 状态栏高度
+ * @param component 任意一个处于布局中的控件
+ * @return 状态栏高度,单位px
*/
- public static int getStatusBarHeight(AttachPopupView attachPopupView) {
- return 0;
+ public static int getStatusBarHeight(Component component) {
+ int[] locationOnScreen = ComponentUtil.getDecorView(component).getLocationOnScreen();
+ return locationOnScreen[1];
}
/**
@@ -93,8 +116,11 @@ public class XPopupUtils {
*
* @return the navigation bar's height
*/
- public static int getNavBarHeight() {
- return 0;
+ public static int getNavBarHeight(Component component) {
+ int screenHeight = getScreenHeight(component.getContext());
+ int appHeight = getAppHeight(component.getContext());
+ int statusBarHeight = getStatusBarHeight(component);
+ return screenHeight - appHeight - statusBarHeight;
}
/**
@@ -205,7 +231,7 @@ public class XPopupUtils {
public static void findAllEditText(ArrayList list, ComponentContainer group) {
for (int i = 0; i < group.getChildCount(); i++) {
Component component = group.getComponentAt(i);
- if (component instanceof TextField && component.getVisibility() == Component.VISIBLE) {
+ if (component instanceof TextField) {
list.add((TextField) component);
} else if (component instanceof ComponentContainer) {
findAllEditText(list, (ComponentContainer) component);
@@ -213,6 +239,116 @@ public class XPopupUtils {
}
}
+ private static int correctKeyboardHeight = 0;
+
+ public static void moveUpToKeyboard(final int keyboardHeight, final BasePopupView pv) {
+ correctKeyboardHeight = keyboardHeight;
+ moveUpToKeyboardInternal(correctKeyboardHeight, pv);
+ }
+
+ private static void moveUpToKeyboardInternal(int keyboardHeight, BasePopupView pv) {
+ if (pv.popupInfo == null || !pv.popupInfo.isMoveUpToKeyboard) {
+ return;
+ }
+ // 暂时忽略PartShadow弹窗和AttachPopupView
+ if (pv instanceof PositionPopupView || pv instanceof AttachPopupView) {
+ return;
+ }
+ // 判断是否盖住输入框
+ ArrayList allEts = new ArrayList<>();
+ findAllEditText(allEts, pv);
+ TextField focusEt = null;
+ for (TextField et : allEts) {
+ if (et.isFocused()) {
+ focusEt = et;
+ break;
+ }
+ }
+
+ int dy = 0;
+ int popupHeight = pv.getPopupContentView().getHeight();
+ int popupWidth = pv.getPopupContentView().getWidth();
+ if (pv.getPopupImplView() != null) {
+ popupHeight = Math.min(popupHeight, pv.getPopupImplView().getEstimatedHeight());
+ popupWidth = Math.min(popupWidth, pv.getPopupImplView().getEstimatedWidth());
+ }
+
+ int screenHeight = pv.getEstimatedHeight();
+ int focusEtTop = 0;
+ int focusBottom = 0;
+ if (focusEt != null) {
+ int[] locations = focusEt.getLocationOnScreen();
+ focusEtTop = locations[1];
+ focusBottom = focusEtTop + focusEt.getEstimatedHeight();
+ }
+ // 执行上移
+ if (pv instanceof FullScreenPopupView || (popupWidth == XPopupUtils.getWindowWidth(pv.getContext()) && popupHeight == screenHeight)) {
+ // 如果是全屏弹窗,特殊处理,只要输入框没被盖住,就不移动
+ if (focusBottom + keyboardHeight < screenHeight) {
+ return;
+ }
+ }
+ if (pv instanceof FullScreenPopupView) {
+ int overflowHeight = focusBottom + keyboardHeight - screenHeight;
+ if (focusEt != null && overflowHeight > 0) {
+ dy = overflowHeight;
+ }
+ } else if (pv instanceof CenterPopupView) {
+ int popupBottom = (screenHeight + popupHeight) / 2;
+ int targetY = popupBottom + keyboardHeight - screenHeight;
+ if (focusEt != null && focusEtTop - targetY < 0) {
+ targetY += focusEtTop - targetY - getStatusBarHeight(pv); // 限制不能被状态栏遮住
+ }
+ dy = Math.max(0, targetY);
+ } else if (pv instanceof BottomPopupView) {
+ dy = keyboardHeight;
+ if (focusEt != null && focusEtTop - dy < 0) {
+ dy += focusEtTop - dy - getStatusBarHeight(pv); // 限制不能被状态栏遮住
+ }
+ }
+
+ // dy=0说明没有触发移动,有些弹窗有translationY,不能影响它们
+ if (dy == 0 && pv.getPopupContentView().getTranslationY() != 0) {
+ return;
+ }
+
+ int finalDy = dy;
+ AnimatorValue animatorValue = new AnimatorValue();
+ animatorValue.setDuration(200);
+ animatorValue.setCurveType(Animator.CurveType.OVERSHOOT);
+ animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ pv.getPopupContentView().setTranslationY(-finalDy * v);
+ }
+ });
+ animatorValue.start();
+ }
+
+ public static void moveDown(BasePopupView pv) {
+ // 暂时忽略PartShadow弹窗和AttachPopupView
+ if (pv instanceof PositionPopupView || pv instanceof AttachPopupView) {
+ return;
+ }
+ Component animComponent;
+ if (pv instanceof PartShadowPopupView) {
+ animComponent = pv.getPopupImplView();
+ } else {
+ animComponent = pv.getPopupContentView();
+ }
+ float translationY = animComponent.getTranslationY();
+ AnimatorValue animatorValue = new AnimatorValue();
+ animatorValue.setDuration(100);
+ animatorValue.setCurveType(Animator.CurveType.OVERSHOOT);
+ animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ pv.getPopupContentView().setTranslationY((1 - v) * translationY);
+ }
+ });
+ animatorValue.start();
+ }
+
private static Context mContext;
public static void saveBmpToAlbum(final Context context, final XPopupImageLoader imageLoader, final String url) {
diff --git a/screenshot/attach1.gif b/screenshot/attach1.gif
index a0b8913df58eff2553d0faf9d524561b08cee99d..ad3646572228d8ed332d2b62887116b863b8c2bf 100644
Binary files a/screenshot/attach1.gif and b/screenshot/attach1.gif differ
diff --git a/screenshot/attach2.gif b/screenshot/attach2.gif
index fb3a58fb2f558d11dafc0c67ed377b37b62f1e6c..cee88317c6202f244a596e8a4418726b60429775 100644
Binary files a/screenshot/attach2.gif and b/screenshot/attach2.gif differ
diff --git a/screenshot/bottom1.gif b/screenshot/bottom1.gif
index 78762dc3f70116b39d56b95e08e9d02bb17b233a..c504df02ebf5b6bd8c45958d3f00d77b97392e48 100644
Binary files a/screenshot/bottom1.gif and b/screenshot/bottom1.gif differ
diff --git a/screenshot/bottom2.gif b/screenshot/bottom2.gif
index 3469a71abcbbdedffd52f7936f97936124be57d6..b8468228b005a8997795bdb4e06aabc3bdc962e7 100644
Binary files a/screenshot/bottom2.gif and b/screenshot/bottom2.gif differ
diff --git a/screenshot/full.gif b/screenshot/full.gif
index de2dd8797c0e7870825ed27d13605e583bce01cd..d388ea7df1db80a09d2705f9ed651cf59c0980bd 100644
Binary files a/screenshot/full.gif and b/screenshot/full.gif differ
diff --git a/screenshot/input.gif b/screenshot/input.gif
index faf0ec2c9f38922bf742ff8710d5a0abaf6f3f55..2a27dc243d858f9042976bf4d3f3ce2db9b243ec 100644
Binary files a/screenshot/input.gif and b/screenshot/input.gif differ
diff --git a/screenshot/inset1.gif b/screenshot/inset1.gif
index c37650c5ede4f7ce3e25d36019ceaa18314c9385..953dd0c0ef3af8850d79a3f358d961ed7944f312 100644
Binary files a/screenshot/inset1.gif and b/screenshot/inset1.gif differ
diff --git a/screenshot/inset2.gif b/screenshot/inset2.gif
index 70e47f0e8c42b38490bb9ccf08658b3d3b41df7e..d0b6057fb28f96d037a8ade66a0d636b49bdcce7 100644
Binary files a/screenshot/inset2.gif and b/screenshot/inset2.gif differ
diff --git a/screenshot/search.gif b/screenshot/search.gif
index 39bd6e96e8d12bfa2ab47ec683da4fba392bdbac..050c0895e2c3f058d5aa0039788836806c735f2d 100644
Binary files a/screenshot/search.gif and b/screenshot/search.gif differ