点击ListView项时如何向Firebase传递多个值?安卓开发新手求助
方案1:点击ListView单条条目直接存储到Firebase
你只需要给ListView添加条目点击监听器,点击时拿到对应条目的内容写入Firebase即可,修改后的完整代码如下:
package android.example.mentoring_app; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.Toast; import com.google.firebase.database.ChildEventListener; import com.google.firebase.database.DataSnapshot; import com.google.firebase.database.DatabaseError; import com.google.firebase.database.DatabaseReference; import com.google.firebase.database.FirebaseDatabase; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; public class secondSem extends AppCompatActivity { ListView Lview; ArrayList<String> Alist=new ArrayList<>(); DatabaseReference mRef, saveRef; // 新增saveRef作为存储选中内容的节点引用 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second_sem); // 把适配器改成final,方便内部类访问,也可以提升为类成员变量 final ArrayAdapter<String> ad=new ArrayAdapter<>(secondSem.this, android.R.layout.simple_list_item_1,Alist); Lview=findViewById(R.id.scndl); Lview.setAdapter(ad); mRef= FirebaseDatabase.getInstance().getReference("students").child("2nd sem"); // 初始化存储节点,示例存储到students/selected_subjects下,你可以自行修改路径 saveRef = FirebaseDatabase.getInstance().getReference("students").child("selected_subjects"); // 新增条目点击监听 Lview.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // 获取点击的条目内容 String selectedItem = Alist.get(position); // 写入Firebase,用push()生成唯一key避免覆盖数据,你也可以用自定义key saveRef.push().setValue(selectedItem, new DatabaseReference.CompletionListener() { @Override public void onComplete(@Nullable @org.jetbrains.annotations.Nullable DatabaseError error, @NonNull @NotNull DatabaseReference ref) { if(error == null){ Toast.makeText(secondSem.this, "存储成功", Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(secondSem.this, "存储失败:"+error.getMessage(), Toast.LENGTH_SHORT).show(); } } }); } }); mRef.addChildEventListener(new ChildEventListener() { @Override public void onChildAdded(@NonNull @NotNull DataSnapshot snapshot, @Nullable @org.jetbrains.annotations.Nullable String previousChildName) { String value=snapshot.getValue(String.class); Alist.add(value); ad.notifyDataSetChanged(); } @Override public void onChildChanged(@NonNull @NotNull DataSnapshot snapshot, @Nullable @org.jetbrains.annotations.Nullable String previousChildName) { ad.notifyDataSetChanged(); } @Override public void onChildRemoved(@NonNull @NotNull DataSnapshot snapshot) { } @Override public void onChildMoved(@NonNull @NotNull DataSnapshot snapshot, @Nullable @org.jetbrains.annotations.Nullable String previousChildName) { } @Override public void onCancelled(@NonNull @NotNull DatabaseError error) { } }); } }
方案2:使用CheckBox实现多选后批量存储
如果需要选多个条目一次性提交,可以用CheckBox方案,修改步骤如下:
- 新建列表项布局
res/layout/item_checkbox.xml
<?xml version="1.0" encoding="utf-8"?> <CheckBox xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/checkBox" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="16dp" android:textSize="16sp"/>
- 在你现有页面布局
activity_second_sem.xml底部添加一个提交按钮
<Button android:id="@+id/btnSubmit" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/scndl" android:text="提交选中内容"/>
- 修改Activity代码,自定义适配器记录选中状态,点击按钮批量提交:
package android.example.mentoring_app; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import android.content.Context; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.CheckBox; import android.widget.ListView; import android.widget.Toast; import com.google.firebase.database.ChildEventListener; import com.google.firebase.database.DataSnapshot; import com.google.firebase.database.DatabaseError; import com.google.firebase.database.DatabaseReference; import com.google.firebase.database.FirebaseDatabase; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.HashMap; public class secondSem extends AppCompatActivity { ListView Lview; Button btnSubmit; ArrayList<String> Alist=new ArrayList<>(); ArrayList<Boolean> checkStatus = new ArrayList<>(); // 存储每个条目的选中状态 DatabaseReference mRef, saveRef; CheckboxAdapter ad; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second_sem); Lview=findViewById(R.id.scndl); btnSubmit = findViewById(R.id.btnSubmit); ad = new CheckboxAdapter(this, Alist, checkStatus); Lview.setAdapter(ad); mRef= FirebaseDatabase.getInstance().getReference("students").child("2nd sem"); saveRef = FirebaseDatabase.getInstance().getReference("students").child("selected_subjects"); // 提交按钮点击事件 btnSubmit.setOnClickListener(v -> { HashMap<String, Object> batchData = new HashMap<>(); for (int i = 0; i < Alist.size(); i++) { if(checkStatus.get(i)){ // 用条目内容作为key避免重复,也可以用push()生成唯一key batchData.put(Alist.get(i), true); } } if(batchData.isEmpty()){ Toast.makeText(this, "请先选择条目", Toast.LENGTH_SHORT).show(); return; } // 批量写入Firebase saveRef.updateChildren(batchData, (error, ref) -> { if(error == null){ Toast.makeText(secondSem.this, "批量提交成功", Toast.LENGTH_SHORT).show(); // 提交后重置选中状态 for (int i = 0; i < checkStatus.size(); i++) { checkStatus.set(i, false); } ad.notifyDataSetChanged(); }else{ Toast.makeText(secondSem.this, "提交失败:"+error.getMessage(), Toast.LENGTH_SHORT).show(); } }); }); mRef.addChildEventListener(new ChildEventListener() { @Override public void onChildAdded(@NonNull @NotNull DataSnapshot snapshot, @Nullable @org.jetbrains.annotations.Nullable String previousChildName) { String value=snapshot.getValue(String.class); Alist.add(value); checkStatus.add(false); // 新增条目默认未选中 ad.notifyDataSetChanged(); } @Override public void onChildChanged(@NonNull @NotNull DataSnapshot snapshot, @Nullable @org.jetbrains.annotations.Nullable String previousChildName) { ad.notifyDataSetChanged(); } @Override public void onChildRemoved(@NonNull @NotNull DataSnapshot snapshot) { } @Override public void onChildMoved(@NonNull @NotNull DataSnapshot snapshot, @Nullable @org.jetbrains.annotations.Nullable String previousChildName) { } @Override public void onCancelled(@NonNull @NotNull DatabaseError error) { } }); } // 自定义带CheckBox的适配器 class CheckboxAdapter extends ArrayAdapter<String> { ArrayList<String> items; ArrayList<Boolean> checkStatus; Context context; public CheckboxAdapter(Context context, ArrayList<String> items, ArrayList<Boolean> checkStatus) { super(context, R.layout.item_checkbox, items); this.context = context; this.items = items; this.checkStatus = checkStatus; } @NonNull @Override public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { if(convertView == null){ convertView = getLayoutInflater().inflate(R.layout.item_checkbox, parent, false); } CheckBox checkBox = convertView.findViewById(R.id.checkBox); checkBox.setText(items.get(position)); checkBox.setChecked(checkStatus.get(position)); // 监听CheckBox状态变化 checkBox.setOnCheckedChangeListener((buttonView, isChecked) -> checkStatus.set(position, isChecked)); return convertView; } } }
注意事项
- 测试阶段可以先将Firebase Realtime Database的规则设置为允许读写,避免权限问题导致存储失败,上线前记得修改为符合业务逻辑的权限规则
- 如果需要存储用户维度的独有数据,可以在存储路径中加入用户的UID,比如
students/[用户UID]/selected_subjects,避免不同用户的数据混在一起
内容的提问来源于stack exchange,提问作者sanjana s bharadwaj
相关产品推荐
相关产品推荐

