2017-10-21 148 views
0

我的应用程序布局显然不是一个正常的布局,所以我无法设置我的列表适配器自动更新时进行编辑。需要帮助刷新我的数据库ListView在我的应用程序

我在自己的活动和布局中控制的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

回答

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和更新,因为如果适配器该活动尚未启动,因此无需触发updateMethod()

其他解决方案

而是创建一个public static adapter创建public static boolean,那么只要数据进行修改的布尔值设置为true,从数据库中。 最后,每当你恢复你的活动时检查该布尔值,并在需要时更新你的ListViewAdapter。

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

使用TaskAsyncTaskLoader它采用了LoaderMainActivity并实现LoaderManager.LoaderCallbacks

(可选)您可以使Loaderpublic static Loader并在您的DBHandler内触发加载程序以再次加载数据或使用任何其他您需要的逻辑。工作的

证明建议的解决方案, enter image description here

+0

谢谢你的回答,我会尽快给你一个尝试,为迟到的回应感到抱歉,我一直很忙。 – Koumintang

+0

我看到的主要问题是,我的SimpleAdapter被多次调用,它被设置为屏幕左侧的滑动导航栏。所以它适用于肉类,意大利面类,饮料类等......我的更新方法最终会变得一样长,然后用一堆检查检查哪些项更新的类别。 – Koumintang

+0

@Koumintang你是说你并没有真正更新数据库中的值,而是选择了一个类别,然后ListView应该显示数据库中该类别的项目? – ArtiomLK

0

您可以播放从变动数据库文件意图你在OnCreate响应()适配器加载类

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()addi NG类,你需要先否则该广播接收器不会被触发

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(); 
} 
+0

谢谢您的回复,我会很快给它一个尝试。对不起,我刚刚忙得很晚。 – Koumintang

相关问题