需要帮助在我的应用程序中刷新我的数据库 ListView

Need Help Refreshing my database ListView in my app

我的应用程序布局显然不是正常布局,因此我无法将我的列表适配器设置为在进行编辑时自动更新。

我在这个 Java 文件中对我的数据库进行编辑,该文件由自己的 activity 和布局控制。

    public void onClick(View view){
    if (view == findViewById(R.id.addsave)) {
        RecipeRepo repo = new RecipeRepo(this);
        Recipe recipe = new Recipe();
        if (editTextName.getText().toString().equals("")) {
            editTextName.setError("Recipe name required!");
            return;
        } else {
            recipe.name = editTextName.getText().toString();
        }
        if (textImagePath.getText().toString().equals("") ) {
            recipe.image = ("");
        }else{
            recipe.image = textImagePath.getText().toString();
        }
        recipe.category = staticSpinner.getSelectedItem().toString();
        if (editTextIngredients.getText().toString().equals("")) {
            editTextIngredients.setError("Ingredient required!");
            return;
        } else {
            recipe.ingredients = editTextIngredients.getText().toString();
        }
        if (editTextInstruct.getText().toString().equals("")) {
            editTextIngredients.setError("Instruction required!");
            return;
        } else {
            recipe.instructions = editTextInstruct.getText().toString();
        }
        recipe.cooktemp = editTextCookTemp.getText().toString();
        recipe.cooktime = editTextCookTime.getText().toString();
        recipe.serves = editTextServings.getText().toString();
        recipe.recipe_Id = _Recipe_Id;

        if (_Recipe_Id == 0) {
            _Recipe_Id = repo.insert(recipe);

            Toast.makeText(this, "New Recipe Added", Toast.LENGTH_SHORT).show();
            finish();

它实际上在这个 java 文件中插入和更新

    int insert(Recipe recipe){

    //Open connection to write data
    SQLiteDatabase db = dbHelper.getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put(Recipe.KEY_SERVES, recipe.serves);
    values.put(Recipe.KEY_COOKTIME, recipe.cooktime);
    values.put(Recipe.KEY_COOKTEMP, recipe.cooktemp);
    values.put(Recipe.KEY_INSTRUCT, recipe.instructions);
    values.put(Recipe.KEY_INGREDIENTS, recipe.ingredients);
    values.put(Recipe.KEY_CATEGORY, recipe.category);
    values.put(Recipe.KEY_IMAGE, recipe.image);
    values.put(Recipe.KEY_NAME, recipe.name);

    //Inserting Row
    long recipe_Id = db.insert(Recipe.TABLE, null, values);
    db.close();// Closing database connection
    return (int) recipe_Id;
}

void delete(int recipe_Id){

    SQLiteDatabase db = dbHelper.getWritableDatabase();
    db.delete(Recipe.TABLE, Recipe.KEY_ID + "=?", new String[] {String.valueOf(recipe_Id)});
    db.close();
}

void update(Recipe recipe){

    SQLiteDatabase db = dbHelper.getWritableDatabase();
    ContentValues values = new ContentValues();

    values.put(Recipe.KEY_SERVES, recipe.serves);
    values.put(Recipe.KEY_COOKTIME, recipe.cooktime);
    values.put(Recipe.KEY_COOKTEMP, recipe.cooktemp);
    values.put(Recipe.KEY_INSTRUCT, recipe.instructions);
    values.put(Recipe.KEY_INGREDIENTS, recipe.ingredients);
    values.put(Recipe.KEY_CATEGORY, recipe.category);
    values.put(Recipe.KEY_IMAGE, recipe.image);
    values.put(Recipe.KEY_NAME, recipe.name);

    db.update(Recipe.TABLE, values, Recipe.KEY_ID + "=?", new String[]{String.valueOf(recipe.recipe_Id)});
    db.close();
}

最后,它从这个 Java 文件和单独的布局中放入列表视图。这是我的适配器所在的位置,但我根本无法让 notifyDataSetChanged() 在这里工作......因为它甚至不会出现。

     public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.
    int id = item.getItemId();
    RecipeRepo repo = new RecipeRepo(this);

    if (id == R.id.nav_meat) {

        final ArrayList<HashMap<String, String>> recipeList = repo.getRecipeMeat();


        if(recipeList.size()!=0) {
            ListView lv = (ListView) findViewById(R.id.list);
            lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    recipe_Id = (TextView) view.findViewById(R.id.recipe_Id);
                    String recipeId = recipe_Id.getText().toString();
                    Intent objIndent = new Intent(getApplicationContext(), RecipeDetail.class);
                    objIndent.putExtra("recipe_Id", Integer.parseInt(recipeId));
                    startActivity(objIndent);
                }
            });
            ListAdapter adapter = new SimpleAdapter(SousChef.this, recipeList, R.layout.view_recipe_entry, new String[]{"id", "category", "name"}, new int[]{R.id.recipe_Id, R.id.recipe_list_category, R.id.recipe_list_name});
            lv.setAdapter(adapter);
        }else {
            Toast.makeText(this, "No recipe!", Toast.LENGTH_SHORT).show();
        }
    } else if (id == R.id.nav_veg) {

        final ArrayList<HashMap<String, String>> recipeList = repo.getRecipeVeg();
        if(recipeList.size()!=0) {
            ListView lv = (ListView) findViewById(R.id.list);
            lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    recipe_Id = (TextView) view.findViewById(R.id.recipe_Id);
                    String recipeId = recipe_Id.getText().toString();
                    Intent objIndent = new Intent(getApplicationContext(), RecipeDetail.class);
                    objIndent.putExtra("recipe_Id", Integer.parseInt(recipeId));
                    startActivity(objIndent);
                }
            });
            ListAdapter adapter = new SimpleAdapter(SousChef.this, recipeList, R.layout.view_recipe_entry, new String[]{"id", "category", "name"}, new int[]{R.id.recipe_Id, R.id.recipe_list_category, R.id.recipe_list_name});
            lv.setAdapter(adapter);

        }else {
            Toast.makeText(this, "No recipe!", Toast.LENGTH_SHORT).show();
        }

因此,任何关于将其设置为自动更新的建议都将是一个巨大的帮助。几天来,我一直在为此绞尽脑汁,现在正在查看不同的示例以及其他示例,但是没有任何设置与此非常相似,它不允许我将所有内容都放在一个文件中。

提前谢谢你。

类别选择图像: Category picking Image

在适配器加载的 onCreate() 中获得响应后,您可以从更改数据库文件中广播 Intent class

    Intent intent = new Intent("key_to_identify_the_broadcast");
    Bundle bundle = new Bundle();
    bundle.putString("edttext", "changed");
    intent.putExtra("bundle_key_for_intent", bundle);
    context.sendBroadcast(intent);

然后您可以使用 BroadcastReceiver class

在片段中接收捆绑包
private final BroadcastReceiver mHandleMessageReceiver = new 
BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle bundle = 
            intent.getExtras().getBundle("bundle_key_for_intent");
            if(bundle!=null){
                String edttext = bundle.getString("edttext");
            }
            //you can call any of your methods for using this bundle for your use case
    }
};

在您的适配器的 onCreate() 中添加 class 您需要先注册广播接收器,否则将不会触发此广播接收器

IntentFilter filter = new IntentFilter("key_to_identify_the_broadcast");
getActivity().getApplicationContext().
               registerReceiver(mHandleMessageReceiver, filter);

最后您可以取消注册接收器以避免任何异常

@Override
public void onDestroy() {
    try {

         getActivity().getApplicationContext().
             unregisterReceiver(mHandleMessageReceiver);

    } catch (Exception e) {
        Log.e("UnRegister Error", "> " + e.getMessage());
    }
    super.onDestroy();
}

肯定有更多的答案,但这可能会有所帮助,

Quick Example for the proposed solution

简短说明

里面 MainActivity

//create a public static adapter
public static ListAdapter adapter

里面 onCreateView()

//Create your adapter and set it to the right ListView
ListView lv = findViewById(R.id.listView_in_xml);
adapter = new SimpleAdapter(...)
lv.setAdapter(adapter)

CustomAdapter 里面,在你的情况下我假设是 SimpleAdapter

//add a public method to be called so that the Adapter updates and displays the new data
public void updateMethod(){
   //update your List<Recipe> that I would guess you have calling the database again 
   //if needed update your getCount() return value so that it returns the number of childs in your ListView which most of the cases is just the List<Recipe>.size()
   //notifyDataSetChanged()
}

在你的DB HANDLER CLASS

里面
//in every update, add, delete or any method that requires the ListView to Update just call the created method,
MainActivity.CustomAdapter.updateMethod();

问题

您必须确保 public static adapter 已初始化且不为空,或者只需检查 adapter 是否不是 null 并更新,因为如果适配器是null activity 尚未启动,因此无需触发 updateMethod()

其他解决方案

不是创建 public static adapter,而是创建 public static boolean,然后每当数据更改时,都会从数据库中将该布尔值设置为 true。 最后,每当您恢复 activity 检查该布尔值并在需要时更新您的 ListViewAdapter。

我知道的更复杂的解决方案,因为我使用它

使用 TaskAsyncTaskLoader,它利用 MainActivity 中的 Loader 并实现 LoaderManager.LoaderCallbacks.

您可以选择 Loaderpublic static Loader 并在您的 DBHandler 中触发加载程序再次加载数据或使用您想要的任何其他逻辑。

工作证明建议的解决方案,