android - ViewHolder 单个 onClick 影响多个列表项
android - ViewHolder single onClick affects multiple list items
我正在使用带有 ViewHolder 模式的自定义列表适配器将视图扩展到我的列表中,该列表显示图像 (width = match_parent
)、左侧的一些文本(图像下方)和右侧的按钮(也在图片下方)。
这是适配器的代码 class -
public class DishItemListAdapter extends ArrayAdapter<DishItem> {
//declare fonts - BOLD and LIGHT
final Typeface tf_light = Typeface.createFromAsset(getContext().getAssets(),
"fonts/Roboto-Thin.ttf");
final Typeface tf_bold = Typeface.createFromAsset(getContext().getAssets(),
"fonts/Roboto-Regular.ttf");
//get item count
CartItemCount cartItemCount;
//count for dish at particular position
ArrayList<Integer> dishCountList = new ArrayList<>();
//for matching key string in SharedPrefs
String existingKeyString;
Typeface font_light, font_bold;
/* List of DishItem Objects shown on the Dashboard */
private List<DishItem> DishItemList = new ArrayList<DishItem>();
public DishItemListAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
this.font_bold = tf_bold;
this.font_light = tf_light;
}
/* Add a New DishItem Item (object) to the list of DishItems on the Dashboard i.e. DishItemList */
@Override
public void add(DishItem object) {
DishItemList.add(object);
super.add(object);
}
@Override
public int getCount() {
return this.DishItemList.size();
}
@Override
public DishItem getItem(int index) {
return this.DishItemList.get(index);
}
@Override
public View getView(final int position, final View convertView, ViewGroup parent) {
Log.e("getView() at " + position, "");
View row = convertView;
final DishItemViewHolder viewHolder;
// A ViewHolder keeps references to children views to
// avoid unnecessary (and expensive) calls to findViewById() on each row.
if (row == null) {
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.list_item_dish, parent, false);
//instantiate DishItem View Holder
viewHolder = new DishItemViewHolder();
//get BUTTON for Adding Dish to Cart
viewHolder.addToCart = (Button) row.findViewById(R.id.add_to_cart_button);
//BUTTONS for + and - (adding and removing items from cart)
viewHolder.addItemButton = (Button) row.findViewById(R.id.increase_item_count);
viewHolder.removeItemButton = (Button) row.findViewById(R.id.decrease_item_count);
//DISH NAME, CHEF NAME, DISH PRICE and DISH IMAGE
viewHolder.dishName = (TextView) row.findViewById(R.id.dish_name_textview);
viewHolder.chefName = (TextView) row.findViewById(R.id.chef_name_textview);
viewHolder.dishPrice = (TextView) row.findViewById(R.id.dish_price_textview);
viewHolder.dishImage = (ImageView) row.findViewById(R.id.dish_imageview);
//image absolute path
viewHolder.imageStorePath = new String();
//image for depicting whether image is VEG or NON VEG
viewHolder.veg_nonveg_indicator = (ImageView) row.findViewById(R.id.veg_nonveg_indicator);
//viewSwitcher for switching between BUTTON and - + button
viewHolder.viewSwitcher = (ViewSwitcher) row.findViewById(R.id.viewswitcher);
//indicator for item added to Cart
viewHolder.addedToCartIndicator = (TextView) row.findViewById(R.id.added_to_cart_text_indicator);
viewHolder.addedToCartIndicator.setVisibility(View.INVISIBLE);
//counter for number of items selected for a particular dish
viewHolder.dishQuantity = (TextView) row.findViewById(R.id.dish_quantity);
//set tag for the ViewHolder
row.setTag(viewHolder);
} else {
/* Get the ViewHolder back to get fast access to the DishItem UI widgets (views) */
viewHolder = (DishItemViewHolder) row.getTag();
}
//create object of Item Count Class
cartItemCount = new CartItemCount();
/* fetch DishItem View at current position (="position") */
final DishItem dishItem = getItem(position);
row.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e("clicked"+position,"");
viewHolder.dishName.setText("CLICKED");
}
});
return row;
}
static class DishItemViewHolder {
TextView dishName;
TextView chefName;
TextView dishPrice;
TextView dishQuantity;
String imageStorePath;
boolean isDishItemSelected;
Button addToCart, addItemButton, removeItemButton;
ImageView veg_nonveg_indicator;
ImageView dishImage;
ViewSwitcher viewSwitcher;
TextView addedToCartIndicator;
}
}
问题
假设我将 6 个 DishItem
bean(模型)添加到列表中。然后,当我对列表中的第一个项目执行 onClick 时,第一个项目的文本应按原样更改为 CLICKED。此外,在日志中,表示 clicked:0
(因为第一个列表项的索引为 0)。
但是第 4 个列表项的文本也更改为 CLICKED,这是不应该的。
现在看了thispost讲解ListView的回收机制
但是,我不希望它以这种方式工作,因为我只想更新我单击的那些项目。
我在这里做错了什么?
这种回收机制是否有任何变通方法来仅更新我单击的特定项目?
更新
问题已解决。我遵循了 BlackBelt 的方法,因此接受了他的回答,但我要感谢你们所有人的投入!! :)
这是更新后的 getView() 方法。
/**
*
* @param position The position of the item within the adapter's data set of the item whose view we want.
* @param convertView The old view to reuse, if possible.
* Note: You should check that this view is non-null and of an appropriate type before using.
* If it is not possible to convert this view to display the correct data, this method
* can create a new view. Heterogeneous lists can specify their number of view types,
* so that this View is always of the right type (see getViewTypeCount() and getItemViewType(int)).
* @param parent The parent that this view will eventually be attached to
* @return A View corresponding to the data at the specified position.
*/
@Override
public View getView(final int position, final View convertView, ViewGroup parent) {
View row = convertView;
final DishItemViewHolder viewHolder;
// A ViewHolder keeps references to children views to
// avoid unnecessary (and expensive) calls to findViewById() on each row.
if (row == null) {
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.list_item_dish, parent, false);
//instantiate DishItem View Holder
viewHolder = new DishItemViewHolder();
//get BUTTON for Adding Dish to Cart
//viewHolder.addToCart = (Button) row.findViewById(R.id.add_to_cart_button);
viewHolder.addItemButton = (Button) row.findViewById(R.id.add_to_cart_secondary_button);
viewHolder.removeItemButton = (Button) row.findViewById(R.id.remove_from_cart_button);
//DISH NAME, CHEF NAME, DISH PRICE and DISH IMAGE
viewHolder.dishName = (TextView) row.findViewById(R.id.dish_name_textview);
viewHolder.chefName = (TextView) row.findViewById(R.id.chef_name_textview);
viewHolder.dishPrice = (TextView) row.findViewById(R.id.dish_price_textview);
viewHolder.dishImage = (ImageView) row.findViewById(R.id.dish_imageview);
//image absolute path
viewHolder.imageStorePath = new String();
//image for depicting whether image is VEG or NON VEG
viewHolder.veg_nonveg_indicator = (ImageView) row.findViewById(R.id.veg_nonveg_indicator);
//indicator for item added to Cart
viewHolder.addedToCartIndicator = (TextView) row.findViewById(R.id.added_to_cart_text_indicator);
viewHolder.addedToCartIndicator.setVisibility(View.INVISIBLE);
//set tag for the ViewHolder
row.setTag(viewHolder);
} else {
/* Get the ViewHolder back to get fast access to the DishItem UI widgets (views) */
viewHolder = (DishItemViewHolder) row.getTag();
}
//get object for CART ITEM COUNT class
final CartItemCount cartItemCount = new CartItemCount();
//get current dish item (MODEL from Bean class)
final DishItem dishItem = getItem(position);
//disable any highlighting unless dish is selected (verified from SharedPreferences)
viewHolder.dishImage.setColorFilter(null);
//hide ITEM COUNT indicator over the image unless dish is selected (again, verified from SharedPreferences)
viewHolder.addedToCartIndicator.setVisibility(View.INVISIBLE);
//show the + and - buttons on the right and left (respectively) side on the Dish ImageView
viewHolder.addItemButton.setVisibility(View.VISIBLE);
viewHolder.removeItemButton.setVisibility(View.VISIBLE);
//get data from Preferences (to see which dish is selected)
SharedPreferences pref = getContext().getSharedPreferences("DishDetails", Context.MODE_PRIVATE);
Map<String, ?> allEntries = pref.getAll();
for (Map.Entry<String, ?> entry : allEntries.entrySet()) {
Log.d("KEY = " + entry.getKey(), " VALUE = " + entry.getValue().toString());
}
//get Count for each dish in the list and set Quantity in the Model (DishItem.java)
if (pref != null) {
int currentDishCount = pref.getInt("dishCount" + position, 0);
Log.e("Current DishCount", String.valueOf(currentDishCount));
if (currentDishCount > 0) {
getItem(position).setisDishItemSelected(true);
dishItem.setDishQuantity(currentDishCount);
Log.d("dish item" + position," selected");
}
}
//update Views for selected DishItems
if (dishItem.isDishItemSelected()) {
viewHolder.dishImage.setColorFilter(Color.parseColor("#80E0E0E0"));
viewHolder.addedToCartIndicator.setVisibility(View.VISIBLE);
viewHolder.addedToCartIndicator.setText(dishItem.getDishQuantity() + " items in cart");
}
viewHolder.addItemButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dishItem.setisDishItemSelected(true);
dishItem.setDishQuantity(dishItem.getDishQuantity() + 1);
//save data to preferences
SharedPreferences pref = getContext().getSharedPreferences("DishDetails", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.putInt("dishCount" + position, dishItem.getDishQuantity());
editor.commit();
//increment Total Number of Items in Cart
int itemCount = cartItemCount.getitemCount();
cartItemCount.setitemCount(itemCount + 1);
Log.d("itemCount =", String.valueOf(itemCount));
//broadcast the value of itemCount to MainMenuActivity
Intent intent = new Intent("NEW_CART_ITEM");
intent.putExtra("value", cartItemCount.getitemCount());
getContext().sendBroadcast(intent);
Log.d("broadcast", "sent");
//notify adapter of change in underlying data (i.e. update View to show Changes in Model)
notifyDataSetChanged();
}
});
viewHolder.removeItemButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("Old Dish Qty. ", String.valueOf(dishItem.getDishQuantity()));
//if dishCount has reached ZERO, set Dish as NOT SELECTED for buying
if (dishItem.getDishQuantity() == 0) {
dishItem.setisDishItemSelected(false);
} else {
dishItem.setisDishItemSelected(true);
dishItem.setDishQuantity(dishItem.getDishQuantity() - 1);
Log.d("New Dish Qty.", String.valueOf(dishItem.getDishQuantity()));
//decrement TOTAL number of items in Cart
int itemCount = cartItemCount.getitemCount();
cartItemCount.setitemCount(itemCount - 1);
Log.d("itemCount =", String.valueOf(itemCount));
//broadcast the value of itemCount to MainMenuActivity
Intent intent = new Intent("NEW_CART_ITEM");
intent.putExtra("value", cartItemCount.getitemCount());
getContext().sendBroadcast(intent);
Log.d("broadcast", "sent");
//recheck -> if dish Count has reached ZERO, set Dish as NOT SELECTED for buying
if (dishItem.getDishQuantity() == 0) {
dishItem.setisDishItemSelected(false);
}
}
//save Current Quantity of Dish Selected to SharedPreferences
SharedPreferences pref = getContext().getSharedPreferences("DishDetails", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.putInt("dishCount" + position, dishItem.getDishQuantity());
editor.commit();
//notify adapter of change in underlying data (i.e. update View to show Changes in Model)
notifyDataSetChanged();
}
});
return row;
}
思路很简单(之前不知道)-
- 在按钮的 onClick 侦听器中,使用 bean class.
中定义的 setter 和 getter 更改模型,即数据,即 DishItem
致电
notifyDataSetChanged()
将数据的变化告知适配器,以便相应地调整视图。
- 在 getView() 方法中,根据这些数据值设置视图。
Is there any workaround this recycling mechanism to update only the
particular item that I click?
这里没有解决方法。您必须更改数据集(在位置 - 您单击的项目),并要求 Adapter
重绘 ListView
的子项。我强烈建议您也使用 OnItemClickListener
。
您应该在 getView
中将视图的状态重置为默认状态,然后应用该项目的数据。它是这样工作的:
- 获取行的视图(convertView 或扩充一个新视图)
- 创建并附加视图持有者
- 获取当前项目的数据和状态
- 应用所有状态参数和数据(所以如果当前项目被点击则写入 "Clicked" 否则清除
TextView
的文本 - 不要假设它已经包含正确的文本)
您需要将项目的状态存储在某处 - 目前您使用 TextView 的文本来执行此操作,但由于回收行为,它会中断。正确的方法是向 DishItem
添加一个字段,或者只创建一个新的 class 来包含每个项目的状态(选中、聚焦等 - 您想要支持的所有状态) .在 onClickListener
中更改状态的值,然后更改视图的内容或仅在适配器上调用 notifyDataSetChanged
。
要更改某些内容,您必须知道您的项目的位置:
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Code here
}
});
这将为您提供您触摸它的正确位置。其他方式,在您的 getView 内部(在适配器中):
DishItemList = dishCountList.get(position);
这样你就会知道你的项目的位置。只触摸你想要的那个:
row.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// here you can DishItemList.get("and get the key you need");
}
});
我正在使用带有 ViewHolder 模式的自定义列表适配器将视图扩展到我的列表中,该列表显示图像 (width = match_parent
)、左侧的一些文本(图像下方)和右侧的按钮(也在图片下方)。
这是适配器的代码 class -
public class DishItemListAdapter extends ArrayAdapter<DishItem> {
//declare fonts - BOLD and LIGHT
final Typeface tf_light = Typeface.createFromAsset(getContext().getAssets(),
"fonts/Roboto-Thin.ttf");
final Typeface tf_bold = Typeface.createFromAsset(getContext().getAssets(),
"fonts/Roboto-Regular.ttf");
//get item count
CartItemCount cartItemCount;
//count for dish at particular position
ArrayList<Integer> dishCountList = new ArrayList<>();
//for matching key string in SharedPrefs
String existingKeyString;
Typeface font_light, font_bold;
/* List of DishItem Objects shown on the Dashboard */
private List<DishItem> DishItemList = new ArrayList<DishItem>();
public DishItemListAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
this.font_bold = tf_bold;
this.font_light = tf_light;
}
/* Add a New DishItem Item (object) to the list of DishItems on the Dashboard i.e. DishItemList */
@Override
public void add(DishItem object) {
DishItemList.add(object);
super.add(object);
}
@Override
public int getCount() {
return this.DishItemList.size();
}
@Override
public DishItem getItem(int index) {
return this.DishItemList.get(index);
}
@Override
public View getView(final int position, final View convertView, ViewGroup parent) {
Log.e("getView() at " + position, "");
View row = convertView;
final DishItemViewHolder viewHolder;
// A ViewHolder keeps references to children views to
// avoid unnecessary (and expensive) calls to findViewById() on each row.
if (row == null) {
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.list_item_dish, parent, false);
//instantiate DishItem View Holder
viewHolder = new DishItemViewHolder();
//get BUTTON for Adding Dish to Cart
viewHolder.addToCart = (Button) row.findViewById(R.id.add_to_cart_button);
//BUTTONS for + and - (adding and removing items from cart)
viewHolder.addItemButton = (Button) row.findViewById(R.id.increase_item_count);
viewHolder.removeItemButton = (Button) row.findViewById(R.id.decrease_item_count);
//DISH NAME, CHEF NAME, DISH PRICE and DISH IMAGE
viewHolder.dishName = (TextView) row.findViewById(R.id.dish_name_textview);
viewHolder.chefName = (TextView) row.findViewById(R.id.chef_name_textview);
viewHolder.dishPrice = (TextView) row.findViewById(R.id.dish_price_textview);
viewHolder.dishImage = (ImageView) row.findViewById(R.id.dish_imageview);
//image absolute path
viewHolder.imageStorePath = new String();
//image for depicting whether image is VEG or NON VEG
viewHolder.veg_nonveg_indicator = (ImageView) row.findViewById(R.id.veg_nonveg_indicator);
//viewSwitcher for switching between BUTTON and - + button
viewHolder.viewSwitcher = (ViewSwitcher) row.findViewById(R.id.viewswitcher);
//indicator for item added to Cart
viewHolder.addedToCartIndicator = (TextView) row.findViewById(R.id.added_to_cart_text_indicator);
viewHolder.addedToCartIndicator.setVisibility(View.INVISIBLE);
//counter for number of items selected for a particular dish
viewHolder.dishQuantity = (TextView) row.findViewById(R.id.dish_quantity);
//set tag for the ViewHolder
row.setTag(viewHolder);
} else {
/* Get the ViewHolder back to get fast access to the DishItem UI widgets (views) */
viewHolder = (DishItemViewHolder) row.getTag();
}
//create object of Item Count Class
cartItemCount = new CartItemCount();
/* fetch DishItem View at current position (="position") */
final DishItem dishItem = getItem(position);
row.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e("clicked"+position,"");
viewHolder.dishName.setText("CLICKED");
}
});
return row;
}
static class DishItemViewHolder {
TextView dishName;
TextView chefName;
TextView dishPrice;
TextView dishQuantity;
String imageStorePath;
boolean isDishItemSelected;
Button addToCart, addItemButton, removeItemButton;
ImageView veg_nonveg_indicator;
ImageView dishImage;
ViewSwitcher viewSwitcher;
TextView addedToCartIndicator;
}
}
问题
假设我将 6 个 DishItem
bean(模型)添加到列表中。然后,当我对列表中的第一个项目执行 onClick 时,第一个项目的文本应按原样更改为 CLICKED。此外,在日志中,表示 clicked:0
(因为第一个列表项的索引为 0)。
但是第 4 个列表项的文本也更改为 CLICKED,这是不应该的。
现在看了thispost讲解ListView的回收机制
但是,我不希望它以这种方式工作,因为我只想更新我单击的那些项目。 我在这里做错了什么? 这种回收机制是否有任何变通方法来仅更新我单击的特定项目?
更新
问题已解决。我遵循了 BlackBelt 的方法,因此接受了他的回答,但我要感谢你们所有人的投入!! :)
这是更新后的 getView() 方法。
/**
*
* @param position The position of the item within the adapter's data set of the item whose view we want.
* @param convertView The old view to reuse, if possible.
* Note: You should check that this view is non-null and of an appropriate type before using.
* If it is not possible to convert this view to display the correct data, this method
* can create a new view. Heterogeneous lists can specify their number of view types,
* so that this View is always of the right type (see getViewTypeCount() and getItemViewType(int)).
* @param parent The parent that this view will eventually be attached to
* @return A View corresponding to the data at the specified position.
*/
@Override
public View getView(final int position, final View convertView, ViewGroup parent) {
View row = convertView;
final DishItemViewHolder viewHolder;
// A ViewHolder keeps references to children views to
// avoid unnecessary (and expensive) calls to findViewById() on each row.
if (row == null) {
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.list_item_dish, parent, false);
//instantiate DishItem View Holder
viewHolder = new DishItemViewHolder();
//get BUTTON for Adding Dish to Cart
//viewHolder.addToCart = (Button) row.findViewById(R.id.add_to_cart_button);
viewHolder.addItemButton = (Button) row.findViewById(R.id.add_to_cart_secondary_button);
viewHolder.removeItemButton = (Button) row.findViewById(R.id.remove_from_cart_button);
//DISH NAME, CHEF NAME, DISH PRICE and DISH IMAGE
viewHolder.dishName = (TextView) row.findViewById(R.id.dish_name_textview);
viewHolder.chefName = (TextView) row.findViewById(R.id.chef_name_textview);
viewHolder.dishPrice = (TextView) row.findViewById(R.id.dish_price_textview);
viewHolder.dishImage = (ImageView) row.findViewById(R.id.dish_imageview);
//image absolute path
viewHolder.imageStorePath = new String();
//image for depicting whether image is VEG or NON VEG
viewHolder.veg_nonveg_indicator = (ImageView) row.findViewById(R.id.veg_nonveg_indicator);
//indicator for item added to Cart
viewHolder.addedToCartIndicator = (TextView) row.findViewById(R.id.added_to_cart_text_indicator);
viewHolder.addedToCartIndicator.setVisibility(View.INVISIBLE);
//set tag for the ViewHolder
row.setTag(viewHolder);
} else {
/* Get the ViewHolder back to get fast access to the DishItem UI widgets (views) */
viewHolder = (DishItemViewHolder) row.getTag();
}
//get object for CART ITEM COUNT class
final CartItemCount cartItemCount = new CartItemCount();
//get current dish item (MODEL from Bean class)
final DishItem dishItem = getItem(position);
//disable any highlighting unless dish is selected (verified from SharedPreferences)
viewHolder.dishImage.setColorFilter(null);
//hide ITEM COUNT indicator over the image unless dish is selected (again, verified from SharedPreferences)
viewHolder.addedToCartIndicator.setVisibility(View.INVISIBLE);
//show the + and - buttons on the right and left (respectively) side on the Dish ImageView
viewHolder.addItemButton.setVisibility(View.VISIBLE);
viewHolder.removeItemButton.setVisibility(View.VISIBLE);
//get data from Preferences (to see which dish is selected)
SharedPreferences pref = getContext().getSharedPreferences("DishDetails", Context.MODE_PRIVATE);
Map<String, ?> allEntries = pref.getAll();
for (Map.Entry<String, ?> entry : allEntries.entrySet()) {
Log.d("KEY = " + entry.getKey(), " VALUE = " + entry.getValue().toString());
}
//get Count for each dish in the list and set Quantity in the Model (DishItem.java)
if (pref != null) {
int currentDishCount = pref.getInt("dishCount" + position, 0);
Log.e("Current DishCount", String.valueOf(currentDishCount));
if (currentDishCount > 0) {
getItem(position).setisDishItemSelected(true);
dishItem.setDishQuantity(currentDishCount);
Log.d("dish item" + position," selected");
}
}
//update Views for selected DishItems
if (dishItem.isDishItemSelected()) {
viewHolder.dishImage.setColorFilter(Color.parseColor("#80E0E0E0"));
viewHolder.addedToCartIndicator.setVisibility(View.VISIBLE);
viewHolder.addedToCartIndicator.setText(dishItem.getDishQuantity() + " items in cart");
}
viewHolder.addItemButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dishItem.setisDishItemSelected(true);
dishItem.setDishQuantity(dishItem.getDishQuantity() + 1);
//save data to preferences
SharedPreferences pref = getContext().getSharedPreferences("DishDetails", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.putInt("dishCount" + position, dishItem.getDishQuantity());
editor.commit();
//increment Total Number of Items in Cart
int itemCount = cartItemCount.getitemCount();
cartItemCount.setitemCount(itemCount + 1);
Log.d("itemCount =", String.valueOf(itemCount));
//broadcast the value of itemCount to MainMenuActivity
Intent intent = new Intent("NEW_CART_ITEM");
intent.putExtra("value", cartItemCount.getitemCount());
getContext().sendBroadcast(intent);
Log.d("broadcast", "sent");
//notify adapter of change in underlying data (i.e. update View to show Changes in Model)
notifyDataSetChanged();
}
});
viewHolder.removeItemButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("Old Dish Qty. ", String.valueOf(dishItem.getDishQuantity()));
//if dishCount has reached ZERO, set Dish as NOT SELECTED for buying
if (dishItem.getDishQuantity() == 0) {
dishItem.setisDishItemSelected(false);
} else {
dishItem.setisDishItemSelected(true);
dishItem.setDishQuantity(dishItem.getDishQuantity() - 1);
Log.d("New Dish Qty.", String.valueOf(dishItem.getDishQuantity()));
//decrement TOTAL number of items in Cart
int itemCount = cartItemCount.getitemCount();
cartItemCount.setitemCount(itemCount - 1);
Log.d("itemCount =", String.valueOf(itemCount));
//broadcast the value of itemCount to MainMenuActivity
Intent intent = new Intent("NEW_CART_ITEM");
intent.putExtra("value", cartItemCount.getitemCount());
getContext().sendBroadcast(intent);
Log.d("broadcast", "sent");
//recheck -> if dish Count has reached ZERO, set Dish as NOT SELECTED for buying
if (dishItem.getDishQuantity() == 0) {
dishItem.setisDishItemSelected(false);
}
}
//save Current Quantity of Dish Selected to SharedPreferences
SharedPreferences pref = getContext().getSharedPreferences("DishDetails", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.putInt("dishCount" + position, dishItem.getDishQuantity());
editor.commit();
//notify adapter of change in underlying data (i.e. update View to show Changes in Model)
notifyDataSetChanged();
}
});
return row;
}
思路很简单(之前不知道)-
- 在按钮的 onClick 侦听器中,使用 bean class. 中定义的 setter 和 getter 更改模型,即数据,即 DishItem
致电
notifyDataSetChanged()
将数据的变化告知适配器,以便相应地调整视图。
- 在 getView() 方法中,根据这些数据值设置视图。
Is there any workaround this recycling mechanism to update only the particular item that I click?
这里没有解决方法。您必须更改数据集(在位置 - 您单击的项目),并要求 Adapter
重绘 ListView
的子项。我强烈建议您也使用 OnItemClickListener
。
您应该在 getView
中将视图的状态重置为默认状态,然后应用该项目的数据。它是这样工作的:
- 获取行的视图(convertView 或扩充一个新视图)
- 创建并附加视图持有者
- 获取当前项目的数据和状态
- 应用所有状态参数和数据(所以如果当前项目被点击则写入 "Clicked" 否则清除
TextView
的文本 - 不要假设它已经包含正确的文本)
您需要将项目的状态存储在某处 - 目前您使用 TextView 的文本来执行此操作,但由于回收行为,它会中断。正确的方法是向 DishItem
添加一个字段,或者只创建一个新的 class 来包含每个项目的状态(选中、聚焦等 - 您想要支持的所有状态) .在 onClickListener
中更改状态的值,然后更改视图的内容或仅在适配器上调用 notifyDataSetChanged
。
要更改某些内容,您必须知道您的项目的位置:
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Code here
}
});
这将为您提供您触摸它的正确位置。其他方式,在您的 getView 内部(在适配器中):
DishItemList = dishCountList.get(position);
这样你就会知道你的项目的位置。只触摸你想要的那个:
row.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// here you can DishItemList.get("and get the key you need");
}
});