You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android React Native集成Google Pay PayButton异常问题求助

React Native集成Google Pay原生PayButton的显示问题排查

问题背景

在React Native 0.73.2应用中集成Google Pay API的原生PayButton,编写了如下Android桥接代码:

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。

问题现象

  • 应用首次启动时,按钮正常显示并可交互;后续启动时,按钮仅显示几秒后变为不可见,但仍能响应点击事件。重装应用可恢复,重启后问题复现。
  • 调用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时无此错误。
  • 修正allowedPaymentMethods为合法配置后,按钮不再消失,但原本应显示卡号的位置为空,Logcat无相关错误。
  • 按钮显示为空时,修改React Native端组件的style属性(如width从100%改为101%)并重新打包,按钮可正常显示卡号,但无法在不重新打包的情况下恢复正常显示。

排查与解决方案

1. 修复主题上下文传递问题

PayButton内部可能未正确继承当前应用的AppCompat主题,显式传入主题包装的上下文初始化按钮:

@Override
protected PayButton createViewInstance(@NonNull ThemedReactContext themedReactContext) {
    // 用应用的AppCompat主题包装上下文
    Context themedContext = new ContextThemeWrapper(themedReactContext, R.style.AppTheme);
    PayButton button = new PayButton(themedContext);
    button.setOnClickListener(v -> {
        WritableMap map = Arguments.createMap();
        themedReactContext.getJSModule(RCTEventEmitter.class).receiveEvent(v.getId(), "onPress", map);
    });
    buildButton(button);
    return button;
}

确保R.style.AppTheme是项目中已配置的AppCompat主题。

2. 配置合法的allowedPaymentMethods

之前传入的空数组"[]"不符合Google Pay规范,需传入符合要求的JSON字符串。以卡支付为例:

private void buildButton(PayButton button) {
    String allowedPaymentMethods = "{" +
        "\"type\": \"CARD\"," +
        "\"parameters\": {" +
            "\"allowedAuthMethods\": [\"PAN_ONLY\", \"CRYPTOGRAM_3DS\"]," +
            "\"allowedCardNetworks\": [\"AMEX\", \"DISCOVER\", \"MASTERCARD\", \"VISA\"]" +
        "}," +
        "\"tokenizationSpecification\": {" +
            "\"type\": \"PAYMENT_GATEWAY\"," +
            "\"parameters\": {" +
                "\"gateway\": \"your-gateway-id\"," +
                "\"gatewayMerchantId\": \"your-merchant-id\"" +
            "}" +
        "}" +
    "}";
    button.initialize(ButtonOptions.newBuilder()
            .setButtonTheme(theme)
            .setButtonType(type)
            .setCornerRadius(cornerRadius)
            .setAllowedPaymentMethods(allowedPaymentMethods)
            .build());
}

替换your-gateway-id和your-merchant-id为实际业务参数,若使用直接令牌化方案,需调整对应的配置内容。

3. 强制按钮重绘解决布局延迟

根据修改style触发重绘可恢复显示的现象,在按钮初始化后手动触发布局更新和重绘:

@Override
protected PayButton createViewInstance(@NonNull ThemedReactContext themedReactContext) {
    Context themedContext = new ContextThemeWrapper(themedReactContext, R.style.AppTheme);
    PayButton button = new PayButton(themedContext);
    button.setOnClickListener(v -> {
        WritableMap map = Arguments.createMap();
        themedReactContext.getJSModule(RCTEventEmitter.class).receiveEvent(v.getId(), "onPress", map);
    });
    buildButton(button);
    // 延迟触发重绘,确保视图已挂载完成
    button.post(() -> {
        button.requestLayout();
        button.invalidate();
    });
    return button;
}

4. 适配React Native视图生命周期

将PayButton的初始化逻辑移到视图挂载完成后的生命周期方法中,避免因视图未完全渲染导致的显示问题:

private boolean isButtonInitialized = false;

@Override
public void onAfterUpdateTransaction(@NonNull PayButton view) {
    super.onAfterUpdateTransaction(view);
    if (!isButtonInitialized) {
        buildButton(view);
        view.post(() -> {
            view.requestLayout();
            view.invalidate();
        });
        isButtonInitialized = true;
    }
}

5. 测试Google Pay SDK版本兼容性

部分高版本Google Pay SDK可能与React Native 0.73存在兼容性问题,尝试降级SDK版本,修改app/build.gradle:

implementation 'com.google.android.gms:play-services-wallet:19.0.0'

内容的提问来源于stack exchange,提问作者ausavi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 15:01:28