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

RecyclerView不显示数据库数据 求技术排查

问题排查:RecyclerView显示空白但数据已写入数据库

之前可正常向餐食数据库添加新条目并显示在列表中,修复列表删除功能后,新输入的数据虽已写入数据库,但RecyclerView仅显示空白。尝试多种notifyDataSetChanged()调用方式仍无效,怀疑问题出在MainActivity或RatedDishAdapter中,相关代码如下:

MainActivity.java

package com.example.restaurantrater;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    EditText Restaurant_name;
    EditText Restaurant_address;
    Button save_btn;

    private RestaurantDBhelper dbHelper;
    private RecyclerView recyclerView;
    private RatedDishAdapter adapter;

    private static int restIDcount = 0;
    private ArrayList<RatedDish> ratedDishes;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        dbHelper = new RestaurantDBhelper(this);

        Restaurant_name = findViewById(R.id.restaurant_name);
        Restaurant_address = findViewById(R.id.streetaddress);
        save_btn = findViewById(R.id.save_dish);

        save_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String nrestaurant_n = Restaurant_name.getText().toString();
                String nrestaurant_a = Restaurant_address.getText().toString();

                restIDcount++;

                // Insert restaurant details into the database
                long result = dbHelper.insertRestaurant(nrestaurant_n, nrestaurant_a);
                if (result != -1) {
                    // Restaurant inserted successfully, navigate to DishRater
                    Intent intent = new Intent(MainActivity.this, DishRater.class);
                    intent.putExtra("restaurantid", restIDcount);
                    startActivity(intent);
                } else {
                    // Failed to insert restaurant
                    // Handle error, show toast or log error
                }
            }
        });

        // RecyclerView setup
        recyclerView = findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        // Initialize adapter for RecyclerView
        ratedDishes = new ArrayList<>();
        adapter = new RatedDishAdapter(ratedDishes, this);
        recyclerView.setAdapter(adapter);

        // Set up click listener for delete actions in the adapter
        adapter.setOnItemClickListener(new RatedDishAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(int position) {
                // Handle item click if needed
            }

            @Override
            public void onDeleteClick(int position) {
                RatedDish deletedDish = ratedDishes.get(position);
                boolean isDeleted = dbHelper.deleteDish(deletedDish.getId());
                if (isDeleted) {
                    Toast.makeText(MainActivity.this, "Dish deleted successfully", Toast.LENGTH_SHORT).show();
                    // Remove the deleted item from the RecyclerView
                    ratedDishes.remove(position);
                    adapter.notifyItemRemoved(position);
                } else {
                    Toast.makeText(MainActivity.this, "Failed to delete dish", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

   @Override
    protected void onResume() {
        super.onResume();
        // Retrieve list of rated meals from the database
        retrieveRatedDishesFromDatabase();
        // Update the adapter with the new list of rated dishes
        adapter.updateData(ratedDishes);
    }

    private void retrieveRatedDishesFromDatabase() {
        // Call getAllRatedDishes() method from RestaurantDBhelper
        ratedDishes.clear();
        ratedDishes.addAll(dbHelper.getAllRatedDishes());
        adapter.updateData(ratedDishes);
    }
}

RatedDishAdapter.java

package com.example.restaurantrater;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;

public class RatedDishAdapter extends RecyclerView.Adapter<RatedDishAdapter.RatedDishViewHolder> {

    private ArrayList<RatedDish> ratedDishes;
    private OnItemClickListener clickListener; // Define listener
    private Context context; // Add context field
    private RestaurantDBhelper dbHelper; // Add dbHelper field

    public RatedDishAdapter(ArrayList<RatedDish> ratedDishes, Context context) {
        this.ratedDishes = ratedDishes;
        this.context = context; // Initialize context
        this.dbHelper = new RestaurantDBhelper(context); // Initialize dbHelper
    }

    public interface OnItemClickListener {
        void onItemClick(int position);
        void onDeleteClick(int position);
    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        this.clickListener = listener;
    }

    @NonNull
    @Override
    public RatedDishViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_rated_dish, parent, false);
        return new RatedDishViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull RatedDishViewHolder holder, int position) {
        RatedDish ratedDish = ratedDishes.get(position);
        holder.textDishName.setText(ratedDish.getName());
        holder.textRating.setText(String.valueOf(ratedDish.getRating()));

        // Set click listener for the delete button
        holder.deleteButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (clickListener != null) {
                    int position = holder.getAdapterPosition();
                    if (position != RecyclerView.NO_POSITION) {
                        clickListener.onDeleteClick(position);
                    }
                }
            }
        });
    }

    @Override
    public int getItemCount() {
        return ratedDishes.size();
    }

    public class RatedDishViewHolder extends RecyclerView.ViewHolder {
        public TextView textDishName;
        public TextView textRating;
        public Button deleteButton;

        public RatedDishViewHolder(@NonNull View itemView) {
            super(itemView);
            textDishName = itemView.findViewById(R.id.textViewDishName);
            textRating = itemView.findViewById(R.id.textViewRating);
            deleteButton = itemView.findViewById(R.id.buttonDelete);

            // Set click listener for the delete button
            deleteButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (clickListener != null) {
                        int position = getAdapterPosition();
                        if (position != RecyclerView.NO_POSITION) {
                            clickListener.onDeleteClick(position);
                        }
                    }
                }
            });

            // Set click listener on the item view
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (clickListener != null) {
                        int position = getAdapterPosition();
                        if (position != RecyclerView.NO_POSITION) {
                            clickListener.onItemClick(position);
                        }
                    }
                }
            });
        }
    }

    // Update the data in the adapter
    public void updateData(ArrayList<RatedDish> newData) {
        ratedDishes.clear();
        ratedDishes.addAll(newData);
        notifyDataSetChanged();
    }
}

核心问题及修复方案

1. 重复调用updateData导致数据被清空

在onResume方法中,你先调用了retrieveRatedDishesFromDatabase(),这个方法内部已经调用了adapter.updateData(ratedDishes),而之后又在onResume里再次调用adapter.updateData(ratedDishes)。由于updateData方法会先执行ratedDishes.clear(),等于刚从数据库加载的数据立刻被清空,最终RecyclerView没有数据可显示。

修复:
修改onResume方法,移除重复的updateData调用:

@Override
protected void onResume() {
    super.onResume();
    retrieveRatedDishesFromDatabase();
}

2. 潜在问题:餐厅ID维护错误

你用静态变量restIDcount维护餐厅ID,App重启后这个值会重置为0,导致传递给DishRater的ID错误。应该直接使用数据库插入返回的result值(这是数据库自动生成的主键ID):

long result = dbHelper.insertRestaurant(nrestaurant_n, nrestaurant_a);
if (result != -1) {
    Intent intent = new Intent(MainActivity.this, DishRater.class);
    intent.putExtra("restaurantid", (int)result); // 使用数据库返回的真实ID
    startActivity(intent);
}

3. 重复设置删除按钮监听

在RatedDishAdapter中,你同时在onBindViewHolder和RatedDishViewHolder构造方法里设置了删除按钮的点击监听,会导致点击事件被重复触发。修复: 移除onBindViewHolder中的删除按钮监听代码,只保留ViewHolder构造里的监听即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 10:47:09