将数据从片段传递到自定义适配器(用于 ListView)
Passing data from a fragment to a custom adapter (for use with ListView)
我正在尝试将从片段中的包中检索到的数据发送到 ListView 的适配器中,以便可以显示数据,具体取决于之前的用户选择。
我可以记录正确的数据被发送到我的片段,但是当我尝试将该数据传递到我的适配器的构造函数时,ListView 没有被填充。我不确定这是否是将数据传输到适配器的正确方法,特别是因为数据不是来自游标。
在我的片段中,这是相关代码:
public class AddEditRecipeActivityFragment extends Fragment {
ListView mListView;
private IngredientListAdapter mIngredientListAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d(TAG, "onCreateView: starts");
View view = inflater.inflate(R.layout.fragment_add_edit_recipe, container, false);
mNameTextView = (EditText) view.findViewById(R.id.addedit_name);
mAddItem = (ImageButton) view.findViewById(R.id.addGrocery);
mDescriptionTextView = (EditText) view.findViewById(R.id.addedit_description);
mMealType = (EditText) view.findViewById(R.id.addedit_meal);
mSaveButton = (Button) view.findViewById(R.id.addedit_save);
mListView = (ListView) view.findViewById(R.id.lstIngredient);
Bundle arguments = getArguments();
String addedGrocery = arguments.getString("GroceryName");
String addedGroceryGrams = arguments.getString("grams");
Log.d(TAG, "onCreateView: retrieved ingredient = " + addedGrocery
+ " retrieved amount = " + addedGroceryGrams );
mIngredientListAdapter = new IngredientListAdapter(getActivity(), null,
0, addedGrocery, addedGroceryGrams ) ;
mListView.setAdapter(mIngredientListAdapter);
.... }
这是我的适配器代码,修改自 CursorAdapter class:
public class IngredientListAdapter extends CursorAdapter {
private static final String TAG = "IngredientListAdapter";
private LayoutInflater mInflater;
private Context mContext;
private String mIngredient;
private String mGrams;
public IngredientListAdapter(Context context, Cursor c, int flags, String ingredient, String grams) {
super(context, c, flags);
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.mIngredient = ingredient;
this.mGrams = grams;
}
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = mInflater.inflate(R.layout.ingrediend_listview, parent, false);
ViewHolder holder = new ViewHolder();
holder.ingredient = (TextView) view.findViewById(R.id.ingredient);
holder.amount = (TextView) view.findViewById(R.id.amount);
view.setTag(holder);
return view;
}
public void bindView(View view, Context context, Cursor cursor) {
ViewHolder holder = (ViewHolder) view.getTag();
Log.d(TAG, "bindView: Starts");
Log.d(TAG, "bindView: ingredient = " + mIngredient);
holder.ingredient.setText(mIngredient);
holder.amount.setText(mGrams);
}
static class ViewHolder {
TextView ingredient;
TextView amount;
}
}
当我尝试查看 IngredientListAdapter class 的日志时,什么也没有显示。这很奇怪,因为我有另一个扩展 CursorAdapter 的适配器并且这些日志正在工作 - 可能是因为它们涉及游标参数?
我显然遗漏了一些重要的东西,任何帮助将不胜感激!
我不想在这里做出新的回答,但是评论行太短,无法扩展我的观点。
首先让我们想象一下您的适配器应该有 2 件事要管理。首先是每个列表视图项的视图。您已经通过添加视图持有者完成了它。第二件事是视图的数据。因为您使用的是 Cursor 适配器,所以您不需要在该适配器内部准备 List<E>
。游标为你做了。但是,您忘记通过将 null 传递给构造函数来准备它。
请慢慢阅读this article。这对你有好处。
你的问题:
public class AddEditRecipeActivityFragment extends Fragment {
...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
...
// The cursor's null
mIngredientListAdapter = new IngredientListAdapter(getActivity(), null, 0, addedGrocery, addedGroceryGrams ) ;
mListView.setAdapter(mIngredientListAdapter);
...
}
这里:
public class IngredientListAdapter extends CursorAdapter {
...
public IngredientListAdapter(Context context, Cursor c, int flags, String ingredient, String grams) {
super(context, c, flags); // c null now
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.mIngredient = ingredient;
this.mGrams = grams;
}
...
希望对您有所帮助。
正如另一个答案中提到的,主要问题是您的 Cursor
参数是 null
,这告诉 CursorAdapter
您不想在全部在您的 ListView
中,因此什么也没有显示。
由于您实际上并没有使用 Cursor
,扩展 CursorAdapter
并不是一个好的选择。扩展 ArrayAdapter
会更合适。
您的适配器可能如下所示:
public class IngredientAdapter extends ArrayAdapter<Ingredient> {
public IngredientAdapter(Context context, ArrayList<Ingredient> ingredients) {
super(context, 0, ingredients);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
Ingredient ingredient = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_ingredient, parent, false);
}
// Lookup view for data population
TextView ingredientName = (TextView) convertView.findViewById(R.id.ingredientName);
TextView ingredientAmt = (TextView) convertView.findViewById(R.id.ingredientAmt);
// Populate the data into the template view using the data object
ingredientName.setText(ingredient.name);
ingredientAmt.setText(ingredient.amt);
// Return the completed view to render on screen
return convertView;
}
}
Ingredient
将是您创建的 class 以保存每种成分的信息。您也可以向适配器添加 ViewHolder
,但这不是必需的。
而不是像您那样将 addedGrocery
和 addedGroceryGrams
值直接传递给构造函数,这只会让您在 ListView
中拥有一个项目,或多个具有相同值的项目,您应该传入包含以下信息的 ArrayList
个 Ingredient
个对象:
mIngredientListAdapter = new IngredientAdapter(getActivity(), ingredients);
mListView.setAdapter(mIngredientListAdapter);
我正在尝试将从片段中的包中检索到的数据发送到 ListView 的适配器中,以便可以显示数据,具体取决于之前的用户选择。
我可以记录正确的数据被发送到我的片段,但是当我尝试将该数据传递到我的适配器的构造函数时,ListView 没有被填充。我不确定这是否是将数据传输到适配器的正确方法,特别是因为数据不是来自游标。
在我的片段中,这是相关代码:
public class AddEditRecipeActivityFragment extends Fragment {
ListView mListView;
private IngredientListAdapter mIngredientListAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d(TAG, "onCreateView: starts");
View view = inflater.inflate(R.layout.fragment_add_edit_recipe, container, false);
mNameTextView = (EditText) view.findViewById(R.id.addedit_name);
mAddItem = (ImageButton) view.findViewById(R.id.addGrocery);
mDescriptionTextView = (EditText) view.findViewById(R.id.addedit_description);
mMealType = (EditText) view.findViewById(R.id.addedit_meal);
mSaveButton = (Button) view.findViewById(R.id.addedit_save);
mListView = (ListView) view.findViewById(R.id.lstIngredient);
Bundle arguments = getArguments();
String addedGrocery = arguments.getString("GroceryName");
String addedGroceryGrams = arguments.getString("grams");
Log.d(TAG, "onCreateView: retrieved ingredient = " + addedGrocery
+ " retrieved amount = " + addedGroceryGrams );
mIngredientListAdapter = new IngredientListAdapter(getActivity(), null,
0, addedGrocery, addedGroceryGrams ) ;
mListView.setAdapter(mIngredientListAdapter);
.... }
这是我的适配器代码,修改自 CursorAdapter class:
public class IngredientListAdapter extends CursorAdapter {
private static final String TAG = "IngredientListAdapter";
private LayoutInflater mInflater;
private Context mContext;
private String mIngredient;
private String mGrams;
public IngredientListAdapter(Context context, Cursor c, int flags, String ingredient, String grams) {
super(context, c, flags);
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.mIngredient = ingredient;
this.mGrams = grams;
}
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = mInflater.inflate(R.layout.ingrediend_listview, parent, false);
ViewHolder holder = new ViewHolder();
holder.ingredient = (TextView) view.findViewById(R.id.ingredient);
holder.amount = (TextView) view.findViewById(R.id.amount);
view.setTag(holder);
return view;
}
public void bindView(View view, Context context, Cursor cursor) {
ViewHolder holder = (ViewHolder) view.getTag();
Log.d(TAG, "bindView: Starts");
Log.d(TAG, "bindView: ingredient = " + mIngredient);
holder.ingredient.setText(mIngredient);
holder.amount.setText(mGrams);
}
static class ViewHolder {
TextView ingredient;
TextView amount;
}
}
当我尝试查看 IngredientListAdapter class 的日志时,什么也没有显示。这很奇怪,因为我有另一个扩展 CursorAdapter 的适配器并且这些日志正在工作 - 可能是因为它们涉及游标参数?
我显然遗漏了一些重要的东西,任何帮助将不胜感激!
我不想在这里做出新的回答,但是评论行太短,无法扩展我的观点。
首先让我们想象一下您的适配器应该有 2 件事要管理。首先是每个列表视图项的视图。您已经通过添加视图持有者完成了它。第二件事是视图的数据。因为您使用的是 Cursor 适配器,所以您不需要在该适配器内部准备 List<E>
。游标为你做了。但是,您忘记通过将 null 传递给构造函数来准备它。
请慢慢阅读this article。这对你有好处。
你的问题:
public class AddEditRecipeActivityFragment extends Fragment {
...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
...
// The cursor's null
mIngredientListAdapter = new IngredientListAdapter(getActivity(), null, 0, addedGrocery, addedGroceryGrams ) ;
mListView.setAdapter(mIngredientListAdapter);
...
}
这里:
public class IngredientListAdapter extends CursorAdapter {
...
public IngredientListAdapter(Context context, Cursor c, int flags, String ingredient, String grams) {
super(context, c, flags); // c null now
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.mIngredient = ingredient;
this.mGrams = grams;
}
...
希望对您有所帮助。
正如另一个答案中提到的,主要问题是您的 Cursor
参数是 null
,这告诉 CursorAdapter
您不想在全部在您的 ListView
中,因此什么也没有显示。
由于您实际上并没有使用 Cursor
,扩展 CursorAdapter
并不是一个好的选择。扩展 ArrayAdapter
会更合适。
您的适配器可能如下所示:
public class IngredientAdapter extends ArrayAdapter<Ingredient> {
public IngredientAdapter(Context context, ArrayList<Ingredient> ingredients) {
super(context, 0, ingredients);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
Ingredient ingredient = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_ingredient, parent, false);
}
// Lookup view for data population
TextView ingredientName = (TextView) convertView.findViewById(R.id.ingredientName);
TextView ingredientAmt = (TextView) convertView.findViewById(R.id.ingredientAmt);
// Populate the data into the template view using the data object
ingredientName.setText(ingredient.name);
ingredientAmt.setText(ingredient.amt);
// Return the completed view to render on screen
return convertView;
}
}
Ingredient
将是您创建的 class 以保存每种成分的信息。您也可以向适配器添加 ViewHolder
,但这不是必需的。
而不是像您那样将 addedGrocery
和 addedGroceryGrams
值直接传递给构造函数,这只会让您在 ListView
中拥有一个项目,或多个具有相同值的项目,您应该传入包含以下信息的 ArrayList
个 Ingredient
个对象:
mIngredientListAdapter = new IngredientAdapter(getActivity(), ingredients);
mListView.setAdapter(mIngredientListAdapter);