【发布时间】:2018-02-07 07:15:56
【问题描述】:
我在RecyclerView和选择项目时,活动将显示该配方的详细信息(即产量,方向,评级,收藏夹等)。
每个食谱的一般信息都在一个表(食谱)中,而成分在另一个表(成分)中,一个单独的表(食谱成分)用于将食谱与成分链接起来,从而创建多对多关系。
当通过在另一个线程上使用AsyncTaskLoader 显示详细信息活动时,我正在尝试在另一个 RecyclerView 中检索成分列表。但是,我似乎不知道如何调用加载程序并返回特定配方的成分列表。
我的 SQL 查询确实返回了指定配方项目的成分列表(在 DB 浏览器中通过“执行 SQL”选项卡检查 SQLite)。
我有以下几点:
RecipeDisplayActivity.java
public class RecipeDisplayActivity extends AppCompatActivity {
private ArrayList<Ingredient> _ingredientsInRecipe = new ArrayList();
private DBHandler _repository;
private ProgressBar _progressIngredient;
private ProgressBar _progressDirections;
private Recipe _recipe;
private RecipeIngredientAdapter _adapterIngredient;
private RecyclerView _rvIngredient;
private TextView _lblIngredientMessage;
private TextView _lblRecipeCategory;
private TextView _lblRecipeDirections;
TextView _lblRecipeTitle;
private static final int RECIPE_INFORMATION_LOADER_ID = 173281;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recipe_display);
initControls(savedInstanceState);
}
private void initControls(Bundle savedInstanceState) {
this._repository = DBHandler.getInstance(this);
int recipeId = getIntent().getIntExtra(UIConsts.Bundles.RECIPE_KEY_ID, -1);
if (recipeId > 0) {
this._recipe = this._repository.recipes.getById(recipeId);
} else {
throw new IllegalStateException("RECIPE_KEY_ID not provided.");
}
setTitle(this._recipe.getTitle());
this._lblRecipeTitle = (TextView) findViewById(R.id.lblRecipeTitle);
this._lblRecipeTitle.setText(this._recipe.getTitle());
this._lblRecipeCategory = (TextView) findViewById(R.id.lblRecipeCategory);
this._lblRecipeCategory.setText(this._recipe.getCategory());
this._lblRecipeDirections = (TextView) findViewById(R.id.lblRecipeDirections);
this._lblRecipeDirections.setText(this._recipe.getDirections());
final RatingBar ratingUser = (RatingBar) findViewById(R.id.ratingUser);
ratingUser.setRating(this._recipe.displayRating());
final ImageButton imgbtnFavoriteRecipe = (ImageButton) findViewById(R.id.imgbtnFavoriteRecipe);
if (this._recipe.isFavorite()) {
imgbtnFavoriteRecipe.setColorFilter(Utils.CustomColors.FAVORITE);
} else {
imgbtnFavoriteRecipe.setColorFilter(Color.rgb(80, 80, 80));
}
this._progressIngredient = (ProgressBar) findViewById(R.id.progressIngredient);
this._lblIngredientMessage = (TextView) findViewById(R.id.lblIngredientMessage);
this._rvIngredient = (RecyclerView) findViewById(R.id.rvIngredient);
this._rvIngredient.setHasFixedSize(true);
this._rvIngredient.setNestedScrollingEnabled(false);
this._rvIngredient.setLayoutManager(new LinearLayoutManager(this));
this._adapterIngredient = new RecipeIngredientAdapter(this._ingredientsInRecipe, this);
this._rvIngredient.setAdapter(this._adapterIngredient);
this._progressDirections = (ProgressBar) findViewById(R.id.progressDirections);
if (this._recipe.getId() != null) {
this._progressIngredient.setVisibility(View.GONE);
this._lblIngredientMessage.setText(R.string.recipe_no_ingredients);
this._lblIngredientMessage.setVisibility(View.GONE);
this._progressDirections.setVisibility(View.GONE);
loadFullRecipeInformation();
}
}
public void loadFullRecipeInformation() {
getSupportLoaderManager().initLoader(RECIPE_INFORMATION_LOADER_ID, null, new LoaderManager.LoaderCallbacks<Recipe>() {
public Loader<Recipe> onCreateLoader(int id, Bundle args) {
return new FullRecipeInformationLoader(RecipeDisplayActivity.this.getApplicationContext(), RecipeDisplayActivity.this._recipe.getId());
}
public void onLoadFinished(Loader<Recipe> loader, Recipe recipe) {
if (recipe == null) {
Exception exception = ((FullRecipeInformationLoader) loader).getException();
if (exception == null) {
return;
}
RecipeDisplayActivity.this._progressIngredient.setVisibility(View.GONE);
RecipeDisplayActivity.this._lblIngredientMessage.setText(R.string.general_msg_something_went_wrong);
RecipeDisplayActivity.this._lblIngredientMessage.setVisibility(View.VISIBLE);
Toast.makeText(RecipeDisplayActivity.this, R.string.general_msg_something_went_wrong, Toast.LENGTH_LONG).show();
return;
}
recipe.setId(RecipeDisplayActivity.this._recipe.getId());
recipe.setRating(RecipeDisplayActivity.this._recipe.getRating());
recipe.setFavorite(RecipeDisplayActivity.this._recipe.isFavorite());
recipe.setTimeAdded(RecipeDisplayActivity.this._recipe.getTimeAdded());
RecipeDisplayActivity.this._recipe = recipe;
RecipeDisplayActivity.this._adapterIngredient.notifyDataSetChanged();
RecipeDisplayActivity.this.displayListStateIngredients();
}
public void onLoaderReset(Loader<Recipe> loader) {
}
}).forceLoad();
}
private void displayListStateIngredients() {
this._progressIngredient.setVisibility(View.GONE);
if (this._ingredientsInRecipe.size() < 1) {
this._rvIngredient.setVisibility(View.GONE);
this._lblIngredientMessage.setText(R.string.recipe_no_ingredients);
this._lblIngredientMessage.setVisibility(View.VISIBLE);
return;
}
this._lblIngredientMessage.setVisibility(View.GONE);
this._rvIngredient.setVisibility(View.VISIBLE);
}
}
RecipeIngredientAdapter.java
public class RecipeIngredientAdapter extends RecyclerView.Adapter<RecipeIngredientAdapter.ViewHolder> {
private Activity _activity;
private ArrayList<Ingredient> _ingredient;
// Provide a direct reference to each of the views within a data item
// Used to cache the views within the item layout for fast access
public class ViewHolder extends RecyclerView.ViewHolder {
// Your holder should contain a member variable
// for any view that will be set as you render a row
private CardView cardIngredient;
private TextView lblIngredientName;
private Ingredient ingredient;
// We also create a constructor that accepts the entire item row
// and does the view lookups to find each subview
public ViewHolder(View itemView) {
super(itemView);
this.cardIngredient = (CardView) itemView.findViewById(R.id.cardIngredient);
this.lblIngredientName = (TextView) itemView.findViewById(R.id.lblIngredientName);
}
void bindViewHolder(Ingredient ingredient) {
this.ingredient = ingredient;
this.lblIngredientName.setText(ingredient.getName());
}
}
public RecipeIngredientAdapter(ArrayList<Ingredient> ingredientInRecipe, Activity activity) {
this._ingredient = ingredientInRecipe;
this._activity = activity;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row_ingredient, parent, false));
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
viewHolder.bindViewHolder((Ingredient) this._ingredient.get(position));
}
@Override
public int getItemCount() {
return this._ingredient.size();
}
public Context getContext() {
return this._activity.getApplicationContext();
}
}
FullRecipeInformationLoader.java
public class FullRecipeInformationLoader extends AsyncTaskLoader<Recipe> {
private Context _context;
private Exception _exception;
private int _recipeId;
private DBHandler _repository;
public FullRecipeInformationLoader(@NonNull Context context, int _recipeId) {
super(context);
this._context = context;
this._recipeId = _recipeId;
}
public Recipe loadInBackground() {
try {
// Return list of Ingredients
return this._repository.recipeIngredients.getIngredientForRecipeById(this._recipeId);
} catch (Exception e) {
this._exception = e;
return null;
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return null;
}
public Exception getException() {
return this._exception;
}
}
RecipeIngredients 类
public class RecipeIngredients {
public ArrayList<Ingredient> getIngredientForRecipeById(int recipeId) {
if (recipeId < 1) {
throw new IllegalArgumentException("recipeId");
}
Cursor cursor = DBHandler.this._helper.getReadableDatabase().rawQuery("SELECT Ingredients.* FROM Recipes, Ingredients, RecipeIngredient WHERE RecipeIngredient._ingredient_id = Ingredients._ingredient_id AND Recipes._id = " + recipeId, null);
ArrayList<Ingredient> ingredients = new ArrayList();
while (cursor.moveToNext()) {
ingredients.add(createIngredientFromCursor(cursor));
}
cursor.close();
return ingredients;
}
private Ingredient createIngredientFromCursor(Cursor cursor) {
boolean z2 = true;
Ingredient ingredient = new Ingredient();
int id = cursor.getInt(cursor.getColumnIndex(DBConsts.Table_Ingredient.COLUMN_IngredientId));
ingredient.setId(Integer.valueOf(id));
ingredient.setName(cursor.getString(cursor.getColumnIndex(DBConsts.Table_Ingredient.COLUMN_IngredientName)));
return ingredient;
}
}
如果您需要我遗漏的任何信息,请告诉我。 提前谢谢...
【问题讨论】:
-
@cricket_007 skyfishjy 提供的适配器真的很差:那个更好:gist.github.com/Shywim/127f207e7248fe48400b 因为它有
FilterQueryProvider -
如果我错过了它,我很抱歉,但我看不出任何一个链接是如何建议的,并且使用修改后的光标适配器与所提出的问题有关。问题是关于在数据库中查询特定 ID 并返回结果列表并将它们显示在 RecyclerView 中。原谅我的无知...
标签: android sqlite android-recyclerview