我正在尝试将 Google Pay API 的本机 PayButton 与我的 React Native 应用程序集成,我认为这个 Android React Native 桥一切都很好:
public class GooglePayButtonManager extends SimpleViewManager<PayButton> {
public static final String REACT_CLASS = "GooglePayButton";
ReactApplicationContext mCallerContext;
public GooglePayButtonManager(ReactApplicationContext reactContext) {
mCallerContext = reactContext;
}
@Override
public String getName() {
return REACT_CLASS;
}
private int theme = ButtonConstants.ButtonTheme.DARK;
private int type = ButtonConstants.ButtonType.BUY;
private int cornerRadius = 20;
@Override
protected PayButton createViewInstance(@NonNull ThemedReactContext themedReactContext) {
PayButton button = new PayButton(themedReactContext);
button.setOnClickListener(v -> {
WritableMap map = Arguments.createMap();
themedReactContext.getJSModule(RCTEventEmitter.class).receiveEvent(v.getId(), "onPress", map);
});
buildButton(button);
return button;
}
private void buildButton(PayButton button) {
button.initialize(ButtonOptions.newBuilder()
.setButtonTheme(theme)
.setButtonType(type)
.setCornerRadius(cornerRadius)
.setAllowedPaymentMethods("[]")
.build());
}
}
但现在我注意到它只适用于按钮的这种变体,这是我在第一次启动应用程序时得到的:
之后它就变得不可见,但仍然可以点击。如果我重新安装应用程序,我会再次获得第一个版本,并且正常工作,然后重新启动后会发生同样的情况。
有谁知道这可能是什么原因造成的? Google Pay 的 Gradle 包版本为 19.2.1,React Native 版本为 0.73.2。
我注意到的一件事是,在这两个版本中,当调用 PayButton 的
.initialize()
时,我都会在 Logcat 中收到此错误:
View class android.support.v7.widget.AppCompatTextView is an AppCompat widget that can only be used with a Theme.AppCompat theme (or descendant).
这很奇怪,因为主题定义正确,是 AppCompat 的后代。另外,如果我返回实际的 AppCompatTextView 而不是同一类的 PayButton,我也不会收到错误。
感谢任何帮助,谢谢。
编辑:在实际通过@Domi提到的正确的
allowedPaymentMethods
后,按钮不再消失。但现在,当按钮加载时,显示的不是卡的数字,而是空白,LogCat 中没有特别的错误:
EDIT2:我对此感到抓狂 - 我发现当上面的空数字变体被渲染时,如果我从 React Native 端更改组件的
style
属性中的任何内容(例如,将 width
从 100% 更改为 101) %) 并再次重新捆绑,然后按钮将使用数字正确呈现:) 但我无法重新创建它以在不重新捆绑任何内容的情况下正确渲染。
事实证明,这是一个 React Native 的 bug。更多详情请看这里:
https://github.com/facebook/react-native/issues/17968
作为解决方法,您可以包装 Google Pay
PayButton
,然后通过在包装器中覆盖 measure()
来触发 layout()
和 requestLayout()
:
@Override
public void requestLayout() {
super.requestLayout();
post(measureAndLayout);
}
private final Runnable measureAndLayout =
() -> {
measure(
View.MeasureSpec.makeMeasureSpec(getWidth(), View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(getHeight(), View.MeasureSpec.EXACTLY));
layout(getLeft(), getTop(), getRight(), getBottom());
};
检查 Stripe 如何为其 React Native 组件解决这个问题: