Two ListItems are selected when one item is clicked in ListView android?

K

Kunal Nk

Guest
I am creating a Restaurant app which displays a food menu in a ListView. The ListView has a CustomAdapter and a separate layout for a list item and has a three components,the name of the item, its price and a checkbox. The CustomAdapter has a ViewHolder class inside it which initializes all the textViews and checkbox from the layout.I want to implement a functionality such that when the user selects the items and each time the user selects an item the item is highlighted and the items which are selected are passed into another fragment and displayed to the user. But the problem is when I select the first item and scroll down the listView, the seventh item is also highlighted along with the first. Is there any way to avoid this and select only one item?

I have two classes MenuItem and MenuItemForListView, both have same variables name and price but the MenuItemForListView class has an extra boolean variable selected which indicates whether the listItem is selected or not. I have been successful in doing this and the list that has been passed to another fragment is also the one that contains the items I have selected, but I am not able to work my way around this problem of two items getting highlighted at the same time.

Here is my Adapter class

public class MenuListAdapter extends ArrayAdapter
{
Context context;
List<MenuItemForListView> menuItemForListViews;

private static final String TAG="kun";
public MenuListAdapter(Context context, List<MenuItemForListView>
menuItemForListViews) {
super(context,
R.layout.menu_list_item,R.id.menuItemName,menuItemForListViews);
this.context=context;
this.menuItemForListViews=menuItemForListViews;
}

@NonNull
@Override
public View getView(final int position, final View convertView, @NonNull
ViewGroup parent) {
View row=convertView;
MenuItemViewHolder holder=null;
if(row==null) //Initialize the LayoutInflater only when the row is
being created for the first time otherwise directly skip
// to the next step
{

LayoutInflater inflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (inflater != null) {
row = inflater.inflate(R.layout.menu_list_item, parent,
false);
}
assert row != null;
holder=new MenuItemViewHolder(row); //This does the work of
initializing the view objects like textView and imageViews and makes
// the listView further optimized.
row.setTag(holder); //This can store some object inside it.


}
else {
holder= (MenuItemViewHolder) row.getTag();

}


holder.names.setText(menuItemForListViews.get(position).getName());
holder.price.setText(menuItemForListViews.get(position).getPrice());

return row;
}



}

class MenuItemViewHolder{
TextView names,price;
ImageView icon;
CheckBox checkBox;
RelativeLayout listItem;
MenuItemViewHolder(View v){
names=v.findViewById(R.id.menuItemName);

price=v.findViewById(R.id.itemPrice);
icon=v.findViewById(R.id.icon);
checkBox=v.findViewById(R.id.checkItem);
listItem=v.findViewById(R.id.listItem);
}
}


This is my MenuFragment which contains the ListView

public class MenuFragment extends Fragment implements
View.OnClickListener, AdapterView.OnItemClickListener {
private static final String TAG="kun";
private ListView menuList;
private MenuListAdapter menuListAdapter;
private Button show;
private List<MenuItem> menuItem,addToCart;
private List<MenuItemForListView> menuItemForListViews;
private MenuFragmentMethods menuFragmentMethods;


public MenuFragment() {
// Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v=inflater.inflate(R.layout.fragment_menu, container, false);
initialize(v);
show=v.findViewById(R.id.show);
show.setOnClickListener(this);
menuList.setOnItemClickListener(this);
menuList.setAdapter(menuListAdapter);

return v;
}
private void initialize(View v){
menuList=v.findViewById(R.id.menuList);
menuItemForListViews=new ArrayList<>();
for(int i=0;i<10;i++)
{
menuItemForListViews.add(new MenuItemForListView("Item
"+i,"100"));
}

menuListAdapter=new
MenuListAdapter(getActivity(),menuItemForListViews);
}

@Override
public void onAttach(Context context) {
super.onAttach(context);
menuFragmentMethods=(MenuFragmentMethods)context;
}

@SuppressLint("ResourceAsColor")
@Override
public void onClick(View view) {

addToCart=new ArrayList<>();
int cartItems=0;
try{
for(int i=0;i<menuItemForListViews.size();i++)
{
if(menuItemForListViews.get(i).isSelected())
{
Log.d(TAG, "onClick: "+menuItemForListViews);
addToCart.add(new
MenuItem(menuItemForListViews.get(i).getName(),
menuItemForListViews.get(i).get
Price()));
cartItems++;
}
}
if(cartItems==0)
Message.message(getActivity(),"Please select at least one
item");
else {
menuFragmentMethods.sendMenuItems(addToCart);
}



}catch (NullPointerException e)
{
Message.message(getActivity(),e.toString(), 1);
Log.d(TAG, "onClick: "+e.toString());
}

}

@SuppressLint("ResourceAsColor")
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i,
long l) {
// Log.d(TAG, "onItemClick: "+view.toString());
CheckBox checkBox;
TextView name,price;
checkBox= view.findViewById(R.id.checkItem);
name=view.findViewById(R.id.menuItemName);
price=view.findViewById(R.id.itemPrice);
boolean checked=checkBox.isChecked();
checkBox.setChecked(!checked);
if(!checked)
{
view.setBackgroundColor(R.color.pink);
menuItemForListViews.get(i).setSelected(true);
}
else
{
view.setBackgroundColor(android.R.color.background_light);
menuItemForListViews.get(i).setSelected(false);
}
//This is where I am highlighting the ListItem
}
//This interface is to pass the selected items to another fragment
public interface MenuFragmentMethods{
void sendMenuItems(List<MenuItem> cart);
}


MenuItems is the class which has only two variables name and price, it is used for taking the menu data which is stored on firestore so I have kept a separate class for that purpose.

Continue reading...
 
Top