Selecting Multiple Items in Listview

Multiple Items selected of ListView when Click on Single Item of Listview in android

The issue with CheckBox inside ListView is that the view gets recycled due to recycling of ListView and the value of Checkbox(check or uncheck) is not maintained. To, maintain the state to CheckBox there has to be something that can store the state of Checkbox.

@Lalit Poptani have written a blog for ListView with CheckBox Scrolling Issue

Why is my Android ListView selecting multiple items?

You need to give unselected image for all except position which you want as a selected in your case its position 2. Call notifyDataSetChange of BaseAdapter to refresh listview after clicking on ListItem or Selected item.

@Override
public View getView(int position, View convertView, ViewGroup parent) {
ColorItem colorItem = getItem(position);
ViewHolder viewHolder;

if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(layoutResource, parent, false);
viewHolder.icon = (ImageView) convertView.findViewById(R.id.imageview_icon);
viewHolder.color = (TextView) convertView.findViewById(R.id.textview_item_name);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}

viewHolder.icon.setImageResource(colorItem.getColorIconId());
viewHolder.color.setText(colorItem.getColorName());
// need to give image for unselected state too.inplace of below line you can give below line in else part of positioin== 2 condition
convertView.setBackgroundResource(R.drawable.list_item_unSelectedImage);
if(position == 2) {
convertView.setBackgroundResource(R.drawable.list_item_selected);
}


return convertView;
}

Selecting multiple items in list using setOnItemLongClickListener

You don`t need to implement OnItemLongClickListener because ListView itself has such functionality what you want.Try this on your activity:

listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {

@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// TODO Auto-generated method stub
return false;
}

@Override
public void onDestroyActionMode(ActionMode mode) {
editListAdapter.removeSelection();

}

@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.delete_action_mode, menu);
return true;
}

@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.delete_mode:
SparseBooleanArray selected = editListAdapter.getSelectedIds();
for (int i = (selected.size() - 1); i >= 0; i--) {
if (selected.valueAt(i)) {
User selectedItem = editListAdapter.getItem(selected.keyAt(i));
editListAdapter.remove(selectedItem);
}
}
mode.finish();
return true;
default:
return false;
}
}

@Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
boolean checked) {
int checkedCount = listView.getCheckedItemCount();
mode.setTitle(checkedCount + " selected");
editListAdapter.toggleSelection(position);
}
});

Your ArrayAdapter Class would be like this:

public class UserListAdapter extends ArrayAdapter<User> {

LayoutInflater inflater;
private int resId;
private TextView userPosition, userName, userLogin, userPassw, userStatus, userRole;
private SparseBooleanArray mSelectedItemsIds;
private List<User> userList;

public UserListAdapter(Context context, int resource, List<User> users) {
super(context, resource, users);
this.resId = resource;
this.inflater = LayoutInflater.from(context);
this.userList = users;
mSelectedItemsIds = new SparseBooleanArray();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
User user = getItem(position);
UserItemHelper helper;
if (convertView == null) {
convertView = inflater.inflate(resId, parent, false);
userPosition = (TextView) convertView.findViewById(R.id.user_item_position);
userName = (TextView) convertView.findViewById(R.id.user_item_name);
userLogin = (TextView) convertView.findViewById(R.id.user_item_login);
userPassw = (TextView) convertView.findViewById(R.id.user_item_passw);
userStatus = (TextView) convertView.findViewById(R.id.user_item_status);
userRole = (TextView) convertView.findViewById(R.id.user_item_role);
helper = new UserItemHelper(userPosition, userName, userLogin, userPassw, userStatus, userRole);
convertView.setTag(helper);
} else {
helper = (UserItemHelper)convertView.getTag();
}
helper.getPosition().setText(position + 1 + "");
helper.getName().setText(user.getName());
helper.getLogin().setText(user.getLogin());
helper.getPassw().setText(user.getPassw());
helper.getStatus().setText(user.getStatus() +"");
helper.getRole().setText(user.getRole()+"");
return convertView;
}

public ArrayList<String> getItemsName() {
ArrayList<String> names = new ArrayList<String>();
for (int i = 0; i < getCount(); i++) {
names.add(getItem(i).getName().toLowerCase());
}
return names;
}

@Override
public void remove(User object) {
// TODO Auto-generated method stub
super.remove(object);
}

public void toggleSelection(int position) {
selectView(position, !mSelectedItemsIds.get(position));
}

public void removeSelection() {
mSelectedItemsIds = new SparseBooleanArray();
notifyDataSetChanged();
}

private void selectView(int position, boolean value) {
if (value)
mSelectedItemsIds.put(position, value);
else
mSelectedItemsIds.delete(position);
notifyDataSetChanged();

}

public SparseBooleanArray getSelectedIds() {
return mSelectedItemsIds;

}

}

Also create menu xml.

  <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

<item
android:id="@+id/delete_mode"
android:icon="@drawable/delete"
android:title="@string/delete_text"/>

</menu>

UWP C# Select Multiple items and display name as single items on Listview

The reason for this behavior is that you are using a StringBuilder object for all the loops without resetting the StringBuilder object. The StringBuilder object will contain the last item's name when you add a new item name to it.

You could move that line of code into the foreach loop.

Like this:

           foreach (StorageFile file in files)
{
StringBuilder output = new StringBuilder();
output.Append(file.Name + "\n");
ListViewtouse.Items.Add(output.ToString());
}

Does flutter have a contextual action bar for selecting multiple item from a list view

You should keep the "selected" state in your list data not in your widget.

Something like that:

import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:playground/feature_discovery.dart';

void main() {
timeDilation = 1.0;
runApp(MaterialApp(home: MyHomePage()));
}

class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
bool longPressFlag = false;
List<Element> indexList = new List();
int selectedCount = 0;
void longPress() {
setState(() {
if (indexList.isEmpty) {
longPressFlag = false;
} else {
longPressFlag = true;
}
});
}

@override
Widget build(BuildContext context) {
for (var i = 0; i < 50; i++) {
indexList.add(Element(isSelected: false));
}

return new Scaffold(
appBar: AppBar(
title: Text("Title"),
actions: <Widget>[
Padding(
padding: const EdgeInsets.only( right: 15.0),
child: Center(child: Text("$selectedCount")),
),
],
),
body: new ListView.builder(
itemCount: 50,
itemBuilder: (context, index) {
return new CustomWidget(
isSelected: indexList[index].isSelected,
index: index,
longPressEnabled: longPressFlag,
callback: () {
onElementSelected(index);
if (indexList.contains(index)) {
indexList.remove(index);
} else {
indexList.add(Element());
}
longPress();
},
);
},
),
);

}

onElementSelected(int index) {
setState(() {
if(indexList[index].isSelected)
selectedCount--;
else
selectedCount++;
indexList[index].isSelected = !indexList[index].isSelected;
});
}
}

class CustomWidget extends StatefulWidget {
final int index;
final bool longPressEnabled;
final VoidCallback callback;
final bool isSelected;
const CustomWidget(
{Key key,
this.index,
this.longPressEnabled,
this.callback,
this.isSelected})
: super(key: key);
@override
_CustomWidgetState createState() => new _CustomWidgetState();
}

class _CustomWidgetState extends State<CustomWidget> {
@override
Widget build(BuildContext context) {
return new GestureDetector(
onLongPress: () {
widget.callback();
},
onTap: () {
if (widget.longPressEnabled) {
widget.callback();
}
},
child: new Container(
margin: new EdgeInsets.all(5.0),
child: new ListTile(
title: new Text("Title ${widget.index}"),
subtitle: new Text("Description ${widget.index}"),
),
decoration: widget.isSelected
? new BoxDecoration(
color: Colors.black38,
border: new Border.all(color: Colors.black))
: new BoxDecoration(),
),
);
}
}

class Element {
Element({this.isSelected});
bool isSelected;
}

ListView select multiple items programmatically in MVVM

I finally found the solution, the problem was not in the homemade component as I was first thinking (I was not searching in the right area) but simply when I was selecting the objects with :

ilSelectedPackages.Add(objDTO_PackageToSelect);

objDTO_PackageToSelect was a copy of an object and so was not comming from ocPackages the ObservableCollection that was filling the ListView.

Conclusion : We must select the exact objects of the Binded observable collection.

DTO_Package objPackInOC = ocPackages.Where(Pack => Pack.sGuid == objDTO_PackageToSelect.sGuid).FirstOrDefault();

if(objPackInOC != null)
ilSelectedPackages.Add(objPackInOC);


Related Topics



Leave a reply



Submit