在我的應用程序中,我有一個部分(片段),我想通過ListView顯示植物及其數量(存儲在Firebase上)。 通過使用浮動操作按鈕,我允許更新與工廠相關的數量,如果它已經在數據庫中,否則添加它。使用Firebase的ListView和自定義適配器
這裏我的頭兩個問題:
#1 此片段顯示在主要活動,因此在啓動時,我想從數據庫中檢索到的數據被立即顯示出來,但是這並未」不會發生,只有在添加/更新工廠後纔會顯示。
#2 這裏是我的代碼:
public class MyVegGardenFragment extends Fragment {
private View v;
private ListView listView;
private DatabaseReference database;
private FirebaseAuth auth;
private FirebaseUser us;
private Map<String, Integer> myVegGarden;
private ArrayList<String> plantsList = new ArrayList<>();
private ArrayList<Integer> quantityList = new ArrayList<>();
private MyVegGardenAdapter adapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
myVegGarden = new HashMap<>();
database = FirebaseDatabase.getInstance().getReference();
auth = FirebaseAuth.getInstance();
us = auth.getCurrentUser();
database.addValueEventListener(new ValueEventListener() {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
User u = dataSnapshot.child("users").child(us.getUid()).getValue(User.class);
if (u != null) {
myVegGarden = u.getMyVegGarden();
if (myVegGarden != null) {
for(Map.Entry<String, Integer> entry : myVegGarden.entrySet()) {
plantsList.add(entry.getKey());
quantityList.add(entry.getValue());
}
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
v = inflater.inflate(R.layout.myveggarden_fragment_layout, container, false);
listView = (ListView) v.findViewById(R.id.myVegGarden_list_view);
adapter = new MyVegGardenAdapter(getActivity(), plantsList, quantityList);
listView.setAdapter(adapter);
FloatingActionButton fab = (FloatingActionButton) v.findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder builder;
// [...] leaving code for AlertDialog working correctly
builder.setPositiveButton("PLANT", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
final String plant = options[plant_picker.getValue()];
final int quantity = quantity_picker.getValue();
if(!adapter.getPlantsList().contains(plant)){
adapter.add(plant, quantity);
}
else {
adapter.updateIfPresent(plant, quantity);
}
//update db value
database.addValueEventListener(new ValueEventListener() {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
User u = dataSnapshot.child("users").child(us.getUid()).getValue(User.class);
if (u != null) {
myVegGarden = u.getMyVegGarden();
if (myVegGarden != null) {
myVegGarden.put(plant, quantity);
}
else {
myVegGarden = new HashMap<>();
myVegGarden.put(plant, quantity);
}
database.child("users").child(us.getUid()).child("myVegGarden").setValue(myVegGarden);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
dialog.dismiss();
}
});
builder.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
} });
AlertDialog dialog = builder.create();
dialog.show();
}
});
return v;
}
}
public class MyVegGardenAdapter extends BaseAdapter {
private Context context;
private LayoutInflater inflater;
private ArrayList<String> dataSource;
private ArrayList<Integer> quantity;
public MyVegGardenAdapter(Context context, ArrayList<String> items, ArrayList<Integer> quantity) {
this.context = context;
dataSource = items;
this.quantity = quantity;
//line 31
inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void add(String plant, Integer qty) {
dataSource.add(plant);
quantity.add(qty);
notifyDataSetChanged();
}
public void updateIfPresent(String plant, Integer qty) {
quantity.set(dataSource.indexOf(plant), qty);
notifyDataSetChanged();
}
public List<String> getPlantsList() { return dataSource; }
@Override
public int getCount() {
return dataSource.size();
}
@Override
public Object getItem(int position) {
return dataSource.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
public Object getQuantity(int position) {
return quantity.get(position);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get view for row item
View rowView = inflater.inflate(R.layout.listview_row, parent, false);
// Get title element
TextView firstLine = (TextView) rowView.findViewById(R.id.firstLine);
// Get subtitle element
TextView secondLine = (TextView) rowView.findViewById(R.id.secondLine);
// Get icon element
ImageView icon = (ImageView) rowView.findViewById(R.id.list_icon);
String plant = (String) getItem(position);
Integer quantity = (Integer) getQuantity(position);
firstLine.setText(plant);
secondLine.setText(Html.fromHtml("<b>Quantity: </b>" + quantity));
switch(plant) {
case "Bean":
icon.setImageResource(R.drawable.ic_bean_48dp); break;
case "Cabbage":
icon.setImageResource(R.drawable.ic_cabbage_48dp); break;
case "Carrot":
icon.setImageResource(R.drawable.ic_carrot_48dp); break;
case "Cucumber":
icon.setImageResource(R.drawable.ic_cucumber_48dp); break;
case "Eggplant":
icon.setImageResource(R.drawable.ic_eggplant_48dp); break;
case "Lettuce":
icon.setImageResource(R.drawable.ic_lettuce_48dp); break;
case "Pea":
icon.setImageResource(R.drawable.ic_pea_48dp); break;
case "Pepper":
icon.setImageResource(R.drawable.ic_pepper_48dp); break;
case "Radish":
icon.setImageResource(R.drawable.ic_radish_48dp); break;
case "Tomato":
icon.setImageResource(R.drawable.ic_tomato_48dp); break;
}
return rowView;
}
}
嗯...數據庫總是正確更新,但:有時plantsList和quantityLists插入副本,所以植物出現兩次或三次,我不想要它。
編輯: 我成功地解決了這兩個問題。 現在只是以下問題。相當經常發生這樣的錯誤:
10-19 19:28:52.460 19148-19148/.veggarden E/AndroidRuntime:致命異常:主 工藝:.veggarden,PID:19148 顯示java.lang.NullPointerException :嘗試在 .veggarden.MyVegGardenAdapter上一個空 對象引用 調用虛擬方法 'java.lang.Object中 android.content.Context.getSystemService(java.lang.String中)'(MyVegGardenAdapter.java:31) at .veggarden.MyVegGardenFragment $ 1.onDataChange(MyVegGardenFragment.java:85) at com.google.android.gms.internal.zzbmz.zza(Unknown Source) at com.google.android.gms.internal.zzbnz.zzYj(Unknown Source) at com.google.android.gms.internal.zzboc $ 1.run(Unknown Source) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6077) at java.lang.reflect.Method.invoke(Native Method) atcom.android.internal.os.ZygoteInit.main(ZygoteInit。)。com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:866) com.android.internal.os.ZygoteInit.main(ZygoteInit。Java的:756)
直到現在出現此錯誤:
- 第一次我嘗試添加植物時,我刪除了我廠從DB(背景不爲空,但加入後植物是)
- ,當我去到另一個片段通過底部的工具欄,然後我回到這個片段添加植物
- 添加許多植物時(很少和不那麼肯定)
這裏我了最新代碼:
public class MyVegGardenFragment extends Fragment {
private View v;
private ListView listView;
private DatabaseReference database;
private FirebaseAuth auth;
private FirebaseUser us;
private Map<String, Integer> myVegGarden;
private ArrayList<String> plantsList = new ArrayList<>();
private ArrayList<Integer> quantityList = new ArrayList<>();
private MyVegGardenAdapter adapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
myVegGarden = new HashMap<>();
database = FirebaseDatabase.getInstance().getReference();
auth = FirebaseAuth.getInstance();
us = auth.getCurrentUser();
v = inflater.inflate(R.layout.myveggarden_fragment_layout, container, false);
listView = (ListView) v.findViewById(R.id.myVegGarden_list_view);
database.addValueEventListener(new ValueEventListener() {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
plantsList = new ArrayList<String>();
quantityList = new ArrayList<Integer>();
User u = dataSnapshot.child("users").child(us.getUid()).getValue(User.class);
if (u != null) {
myVegGarden = u.getMyVegGarden();
if (myVegGarden != null) {
for(Map.Entry<String, Integer> entry : myVegGarden.entrySet()) {
plantsList.add(entry.getKey());
quantityList.add(entry.getValue());
}
}
**line 85**
adapter = new MyVegGardenAdapter(getActivity(), plantsList, quantityList);
listView.setAdapter(adapter);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
FloatingActionButton fab = (FloatingActionButton) v.findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder builder;
// [...] leaving code for AlertDialog working correctly
builder.setPositiveButton("PLANT", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
final String plant = options[plant_picker.getValue()];
final int quantity = quantity_picker.getValue();
if(!adapter.getPlantsList().contains(plant)){
adapter.add(plant, quantity);
}
else {
adapter.updateIfPresent(plant, quantity);
}
if (myVegGarden != null) {
myVegGarden.put(plant, quantity);
database.child("users").child(us.getUid()).child("myVegGarden").setValue(myVegGarden);
}
else {
myVegGarden = new HashMap<String, Integer>();
myVegGarden.put(plant, quantity);
database.child("users").child(us.getUid()).child("myVegGarden").setValue(myVegGarden);
}
dialog.dismiss();
}
});
builder.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
} });
AlertDialog dialog = builder.create();
dialog.show();
}
});
return v;
}
適配器是和以前一樣。
我希望有人能幫助我。
我解決了我的問題,也感謝你。現在只剩下一個問題,請看看,如果可以的話,我會很感激。 – Benny