当前位置: 首页 > 知识库问答 >
问题:

如何从Firebase数据库android中检索单选按钮的值

易招
2023-03-14

大家好,我是新来的,新来的android开发,首先我想道歉,如果这是问和回答之前。我试图建立一个android应用程序,在用户html" target="_blank">配置文件中,我有2个性别,男性和女性的单选按钮。

    saveUserProfile.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String dogBirthdate = displayDogBirthday.getText().toString();
            String dogGender = radioBtnDogGender.getText().toString();
            String dogNeutered = radioBtnNeutered.getText().toString();
            String aboutTheDog = aboutDog.getText().toString();

            progressBar.setVisibility(View.VISIBLE);

            //userId = fireAuth.getCurrentUser().getUid();
            documentReference = fireStore.collection("users").document(userId);
            Map<String, Object> user = new HashMap<>();
            user.put("dogBirthdate", dogBirthdate);
            user.put("dogGender", dogGender);
            user.put("dogNeutered", dogNeutered);
            user.put("aboutDog", aboutTheDog);

这是单选按钮的选择

public void radioBtnGenderClick(View view) {
    int radioBtnDogGenderId = radioGroupDogGender.getCheckedRadioButtonId();
    radioBtnDogGender = (RadioButton) findViewById(radioBtnDogGenderId);

    Toast.makeText(getBaseContext(),radioBtnDogGender.getText(),Toast.LENGTH_LONG).show();
}

我能够将性别值作为文本传回用户配置文件屏幕

userId = fireAuth.getCurrentUser().getUid();

    documentReference = fireStore.collection("users").document(userId);
    documentReference.addSnapshotListener(new EventListener<DocumentSnapshot>() {
        @Override
        public void onEvent(@Nullable DocumentSnapshot value, @Nullable FirebaseFirestoreException error) {
            dogName.setText(value.getString("dogName"));
            aboutDog.setText(value.getString("aboutDog"));
            displayDogBirthday.setText(value.getString("dogBirthdate"));

            String gender = value.getString("dogGender");
            if (gender.equalsIgnoreCase("Male")){
                radioBtnMale.setChecked(true);


            }else if (gender.equalsIgnoreCase("Female")){
                radioBtnFemale.setChecked(true);
            }

当我进入“编辑用户配置文件”时,正确的单选按钮显示为选中状态,但是当我单击“保存配置文件”时,应用程序崩溃,就像没有选中单选按钮一样。如果我重新点击编辑个人资料页面中的同一个单选按钮,一切正常。

我如何修复它,以便用户不必重新单击单选按钮(除非他想更改选择),并且在保存配置文件时,它会将按钮识别为选中状态?

我认为问题是,当将单选按钮值传递到数据库时,使用的是“无线电BtnDog性别”,当从数据库传递值时,使用的是“无线电BtmMan”/“无线电Btn女性”。

如何将该值传递到“RadioBTNDogender”而不是特定的男性/女性单选按钮?

以下是xml代码:

<RadioGroup
    android:id="@+id/radioGroupDogGender"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.488"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintVertical_bias="0.459">

    <RadioButton
        android:id="@+id/radioBtnMale"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="radioBtnGenderClick"
        android:text="Male" />

    <RadioButton
        android:id="@+id/radioBtnFemale"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="radioBtnGenderClick"
        android:text="Female" />

</RadioGroup>

以下是应用程序崩溃时的堆栈跟踪(按保存配置文件而不重新单击单选按钮):

2021-03-11 14:54:59.303 13459-13459/com.example.loginandregfirebase E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.loginandregfirebase, PID: 13459
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.CharSequence android.widget.RadioButton.getText()' on a null object reference
    at com.example.loginandregfirebase.EditUserProfilePage$7.onClick(EditUserProfilePage.java:205)
    at android.view.View.performClick(View.java:7448)
    at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
    at android.view.View.performClickInternal(View.java:7425)
    at android.view.View.access$3600(View.java:810)
    at android.view.View$PerformClick.run(View.java:28305)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:223)
    at android.app.ActivityThread.main(ActivityThread.java:7656)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

正如我在评论中提到的,性别单选按钮与新代码配合良好,当我试图对绝育单选按钮执行相同的代码时,我遇到了一个新问题,绝育单选按钮保持空,当我实际按下其中一个按钮时,应用程序重新启动,而绝育单选按钮保持空,在Neuted(绝育)下的视图配置文件中显示“未指定”,这是性别和绝育单选按钮的代码

            radioGroupDogGender.clearCheck();
            radioGroupNeutered.clearCheck();
            String gender = value.getString("dogGender");

            if (gender == null || gender.equalsIgnoreCase("Unspecified gender")){
                // gender unknown, leave unselected
                radioGroupDogGender = null;
            }else

            if (gender.equalsIgnoreCase("Male")){
                radioBtnMale.setChecked(true);
                radioBtnDogGender = radioBtnMale;


            }else if (gender.equalsIgnoreCase("Female")){
                radioBtnFemale.setChecked(true);
                radioBtnDogGender = radioBtnFemale;
            }

            String neutered = value.getString("dogNeutered");

            if (neutered == null || neutered.equalsIgnoreCase("Unspecified")){
                // neutered unknown, leave unselected
                radioGroupNeutered = null;
            }else

            if (neutered.equalsIgnoreCase("Yes")){
                radioBtnNeuteredYes.setChecked(true);
                radioBtnNeutered = radioBtnNeuteredYes;
            }else if (neutered.equalsIgnoreCase("No")){
                radioBtnNeuteredNo.setChecked(true);
                radioBtnNeutered = radioBtnNeuteredNo;
            }




saveUserProfile.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String dogBirthdate = displayDogBirthday.getText().toString();
            String dogGender = radioBtnDogGender != null ? radioBtnDogGender.getText().toString():"unspecified gender";
            //String dogGender = radioBtnDogGender.getText().toString();
            String dogNeutered = radioBtnNeutered != null ? radioBtnNeutered.getText().toString(): "unspecified";
            //String dogNeutered = radioBtnNeutered.getText().toString();
            String aboutTheDog = aboutDog.getText().toString();

            progressBar.setVisibility(View.VISIBLE);

            //userId = fireAuth.getCurrentUser().getUid();
            documentReference = fireStore.collection("users").document(userId);
            Map<String, Object> user = new HashMap<>();
            user.put("dogBirthdate", dogBirthdate);
            user.put("dogGender", dogGender);
            user.put("dogNeutered", dogNeutered);
            user.put("aboutDog", aboutTheDog);


public void radioBtnGenderClick(View view) {
    int radioBtnDogGenderId = radioGroupDogGender.getCheckedRadioButtonId();
    if (radioBtnDogGenderId == -1){
        //gender deselected
        Toast.makeText(getBaseContext(),"gender deselected", Toast.LENGTH_LONG).show();
    }else {
        radioBtnDogGender = (RadioButton) findViewById(radioBtnDogGenderId);

        Toast.makeText(getBaseContext(), radioBtnDogGender.getText(), Toast.LENGTH_LONG).show();
    }
}

public void radioBtnNeutered(View view) {
    int radioBtnNeuteredId = radioGroupNeutered.getCheckedRadioButtonId();
    if (radioBtnNeuteredId == -1){
        Toast.makeText(getBaseContext(),"neutered deselected",Toast.LENGTH_LONG).show();
    }else {
        radioBtnNeutered = (RadioButton) findViewById(radioBtnNeuteredId);

        Toast.makeText(getBaseContext(), radioBtnNeutered.getText(), Toast.LENGTH_LONG).show();
    }
}

我忘了什么吗?或者绝育单选按钮需要不同的代码吗?

共有1个答案

郗缪文
2023-03-14

首先,在onEvent处理程序中,您忽略了error的值,这可能会导致您在尝试访问value的潜在null值时崩溃。onEvent处理程序的第一行应该检查侦听器是否失败。

public void onEvent(@Nullable DocumentSnapshot value, @Nullable FirebaseFirestoreException error) {
    if (error != null) {
        // something has gone wrong, handle it
        return;
    }

    // no errors, continue
    // ...
}

错误也可能来自以下几行:

String gender = value.getString("dogGender");
if (gender.equalsIgnoreCase("Male")){
    radioBtnMale.setChecked(true);
} else if (gender.equalsIgnoreCase("Female")) {
    radioBtnFemale.setChecked(true);
}

当您的用户第一次加载他们的配置文件时,dog性别的值可能是null。当它是null时,您尝试调用null.equalsIgnoreCase(...),这将抛出一个NullPointerExctive。相反,您应该在将其与女性男性进行比较之前检查它是否为null。此外,当以编程方式更改当前选择的单选按钮时,它不会调用无线电BtnGenderClick监听器,这意味着无线电BtnDog性别不会更新-所以我们在这里更新它。

radioGroupDogGender.clearCheck();
String gender = value.getString("dogGender");
if (gender == null || gender.equalsIgnoreCase("Unspecified")) {
    // gender unknown, leave unselected
    radioBtnDogGender = null;
} else if (gender.equalsIgnoreCase("Male")) {
    radioBtnMale.setChecked(true);
    radioBtnDogGender = radioBtnMale;
} else if (gender.equalsIgnoreCase("Female")) {
    radioBtnFemale.setChecked(true);
    radioBtnDogGender = radioBtnFemale;
}

当我键入这个时,现在您已经为错误提供了堆栈跟踪,我们实际上可以看到导致错误的行是:

public void radioBtnGenderClick(View view) {
    int radioBtnDogGenderId = radioGroupDogGender.getCheckedRadioButtonId();
    radioBtnDogGender = (RadioButton) findViewById(radioBtnDogGenderId);

    Toast.makeText(getBaseContext(),radioBtnDogGender.getText(),Toast.LENGTH_LONG).show();
}

saveUserProfile.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // ...
        String dogGender = radioBtnDogGender.getText().toString();
        // ...
    }
}

如上所述,当您使用setChecked()更新所选单选按钮时,不会调用radioBtnGenderClick侦听器,因此radiogroupdogender可以是null,直到用户单击其中一个性别选项,除非您在上面手动设置radiobtndogender的地方应用更改。当执行radioBtnGenderClick侦听器时,在radioGroupDogGender中没有活动选择的单选按钮,radioGroupDogGender。getCheckedRadioButtonId()返回值-1。在下一行中,调用findviewbyd(-1),然后将radiobtndogender的值设置为null。接下来,您可以有效地调用((RadioButton)null)。getText()抛出一个NullPointerException

public void radioBtnGenderClick(View view) {
    int radioBtnDogGenderId = radioGroupDogGender.getCheckedRadioButtonId();
    if (radioBtnDogGenderId == -1) {
        // gender deselected
        Toast.makeText(getBaseContext(),"Gender deselected",Toast.LENGTH_LONG).show();
    } else {
        radioBtnDogGender = (RadioButton) findViewById(radioBtnDogGenderId);
        Toast.makeText(getBaseContext(),radioBtnDogGender.getText(),Toast.LENGTH_LONG).show();
    }
}

类似地,您还假设saveUserProfile按钮的onClickListener中的radiobtndogender不是null

String dogGender = radioBtnDogGender != null ? radioBtnDogGender.getText().toString() : "Unspecified";
 类似资料:
  • 我试图创建一个简单的程序,从用户的名字,手机号码和电子邮件地址,然后把数据在Firebase实时数据库。 有3个输入框和一个按钮,按一下就可以完成上面的操作。代码如下: 我这样设置了消防基地:

  • 假设我有一个firebase节点,它是dbref=firebase。ref('/Transfer_Request/{pushID]/')。 客户端写入两个值;从_ID和到_ID到dbref。如何从Firebase云函数中获取from_ID和to_ID的单个值? 我的代码: 我得到两个错误: 1) 类型错误:admin。数据库(…)。set不是导出时的函数。转车票。功能。数据库对象处的ref.onW

  • 我正在两个标记之间画一条路线,我想保存那条路线。为此,我将包含lat和lng的ArrayList保存在Firebase数据库中。但我在取回航路点时遇到了问题。我是这样插入的: 在检索数据时,我尝试执行以下操作:

  • 问题内容: 我正在法国学习,所以很难找到法语教程来解决我的问题。因此,我不得不问我的问题,希望有一个令人满意的解决方案。 我的问题是我在firebase上读取数据时遇到了麻烦,并且花了三天时间。 我有这样的结构: 我已经开始编写一些代码,可以恢复密钥,但是无法恢复这些值“ nom”,“ argent”等。 问题答案: John的替代方法是使用来获取每个属性:

  • firebase数据库最近的更新似乎有一些变化。我的项目在firebase\u数据库:^7.0.0版本下运行良好,但在firebase数据库的更新版本中,我无法更新项目代码。 以下是v7的工作版本 firebase\u数据库^9.0.12上的同一代码出现错误。我收到的错误在`(DataSnapShot snap)async{…}上错误是 无法将参数类型“Future Function(DataSn

  • 问题内容: 我有一个带有这样的树的firebase数据库 等等… 在我的应用程序中,用户下载项目,而项目下载时,电视主题将从URL播放。当单个项目发生价值事件时,我可以使其正常运行。我希望它从列表中随机选择一个值。如何做到这一点? 由于我的应用程序不包含任何内容,因此编辑可以使用回收视图方法 这是我的单项代码 问题答案: 要解决此问题,请使用以下代码行: 然后使用循环使用随机数提取该值: