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

时间:2017-10-21 05:29:40

标签: java android listview auto-update

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

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

    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

2 个答案:

答案 0 :(得分:1)

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

<强> 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并更新,因为如果适配器是{{ 1}}该活动尚未启动,因此无需触发null

其他解决方案

不是创建updateMethod()创建public static adapter,而是每当数据更改将数据库中的布尔值设置为true时。 最后,每当您恢复活动时,请检查该布尔值,并在需要时更新ListViewAdapter。

我知道工作的更复杂的解决方案我使用它

使用public static boolean使用TaskAsyncTaskLoader中的Loader并实施MainActivity

或者,您可以LoaderManager.LoaderCallbacks成为Loader并在public static Loader内触发加载程序再次加载数据或使用您想要的任何其他逻辑。

工作证明建议解决方案 enter image description here

答案 1 :(得分:0)

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

    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类

接收片段中的包
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()中,您需要先注册广播接收器,否则不会触发此广播接收器

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();
}
相关问题