listView count numbers of selected rows - android

I am trying to find out the total number of selected rows in a customized list-view. If the number of items (rows) more than 2 then we cannot click the list-view again.Here I am using customized checklist(Multiple Choice)

What's wrong with listView.getCheckedItemCount()?

lvMain.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, final View view, int position, long id)
{
int len = lvMain.getCount();
SparseBooleanArray checked = lvMain.getCheckedItemPositions();
for (int i = 1; i < len; i++){
if (checked.get(i)) {
count++;
/* do whatever you want with the checked item */
}
}
if(count>2)
{
/* do whatever you want with the checked item count more than one x value*/
lvMain.setSelected(false);
count=1;
}
}
});

Else, you could try to store your checkboxes and the other element displayed in a row (I've used TextView in my example) in a HashMap when overridden getView method get called and then count how many elements are checked iterating over the Map :
Iterator<Entry<TextView, CheckBox>> it = listCheck.entrySet().iterator();
int i = 0;
while (it.hasNext()) {
Entry<TextView, CheckBox> entry = it.next();
if (entry.getValue().isChecked())
i++;
}
return i;

I think you are trying to count the total number of selected rows in multiple listView.
for(i=0; listCount; i++) {
if(mListView.isItemChecked(i)){
}
else {
}
}

Related

Update checkbox in CheckedTextView which is inside a ListView

I am a noob android studio and this is my first app I am developing.
Context: I have a ListView lv which is populated with CheckedTextViews using a ListAdapter.
ListAdapter adapter = new SimpleAdapter(
c, manageTrackers.trackers,
R.layout.list_item, new String[]{"id", "mobile", "status"},
new int[]{R.id.trackerID, R.id.trackerMobile, R.id.trackerStatus});
lv.setAdapter(adapter);
I have set up the OnItemClickListener for lv as shown below which checks and unchecks the check boxes as expected. I want the checks to remain persistent when I navigate between activities, so I am storing a key in the selectedTrackers array list.
lv.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l)
{
CheckedTextView ctv = (CheckedTextView) view.findViewById(R.id.trackerID);
HashMap s = (HashMap)lv.getItemAtPosition(i);
String mob = (String)s.get("mobile");
//checked and pressed
if (ctv.isChecked())
{
ctv.setChecked(false);
for (int j = 0; j < selectedTrackers.size(); j++)
{
if (selectedTrackers.get(j) == mob)
{
selectedTrackers.remove(j);
break;
}
}
}
//not checked
else
{
ctv.setChecked(true);
selectedTrackers.add(mob);
}
}
});
When I navigate back to the activity with the list view, I call a function getSelectedTrackers which I want to select the saved checkboxes based on the key in selectedTrackers
public static void getSelectedTrackers()
{
if (basicSettings.selectedTrackers.size() == 0) return;
for (int i = 0; i < trackers.size(); i++)
{
HashMap s = trackers.get(i);
String mob = (String)s.get("mobile");
for (int j = 0; j < basicSettings.selectedTrackers.size(); j++)
{
if (basicSettings.selectedTrackers.get(j).equals(mob))
{
View v = getViewByPosition(i, lv);
CheckedTextView ctv = (CheckedTextView) v.findViewById(R.id.trackerID);
ctv.setChecked(true);
//******************************
//some call to update the view HERE
//******************************
break;
}
}
}
}
Question: I have confirmed that the function finds the correct checkbox, but none of the check boxes are displayed as being selected after calling setChecked(). I have scoured SO and tried invalidating, refreshing drawable state, notifyDataSetChanged, and I can't seem to figure it out how to get it to work. What's the best way to do this? Any help is appreciated!

ListView getcount row and display in TextView

In my home activity. I have listview with id list and textview with id count.
Here's the code:
ListView lv = getListView();
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
int count = 0;
for (int i = 0; i <= list.getLastVisiblePosition(); i++) {
if (list.getChildAt(i) != null) {
count++;
counter.setText(count + "");
}
}
I want to display in textview of rows in listview
Do you want to display how many items is in ListView or visible on screen?
For first option:
If you use ListView, then you have to use some ListAdapter (for example descendant of BaseAdapter or ArrayAdapter) which has method
getCount()
This returns, how many items is in adapter and also in ListView.
edit:
TextView countTextView; // here you want to set number of items
ListView lv; // your ListView
BaseAdapter adapter; // your adapter, that is used with ListView
// call this method in some listener
private void showNumberOfItems() {
int count = adapter.getCount();
countTextView.setText(String.valueOf(count));
}
You can use getLastVisiblePosition() method to count the number of rows,
int count=0;
for(int i = 0; i <= list.getLastVisiblePosition(); i++)
{
if(list.getChildAt(i)!= null)
{
count++; // saying that view that counts is the one that is not null, because sometimes you have partially visible items....
}
}
and then set the Text,
counter.setText(count + "");
Edit-
try something like this,
ListView lv = getListView();
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
int count = 0;
for (int i = 0; i <= list.getLastVisiblePosition(); i++) {
if (list.getChildAt(i) != null) {
count++;
}
}
counter.setText(count + "");

Swapping two rows in ArrayAdapter

I've created a ListView that in each row has a button with UP and DOWN arrow. Pressing these buttons makes the row to be shifted one position up or down.
I've achieved it by implementing OnClickListener for both buttons in a the override method getView. It works as it should however I fill bad with that cuz it seems to be highly memory consuming and lots of code is doubled.
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View rowView = inflater.inflate(R.layout.row_layout, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.label);
CheckBox checkBox = (CheckBox) rowView.findViewById(R.id.checkbox);
checkBoxes.add(position, checkBox);
String address = this.getItem(position).getAddress();
String tokenizedAddress = tokenizeAddress(address);
textView.setText(tokenizedAddress);
ImageButton buttonUp = (ImageButton)rowView.findViewById(R.id.button_up);
ImageButton buttonDown = (ImageButton)rowView.findViewById(R.id.button_down);
buttonUp.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
ListAdapter adapter = ListAdapter.this;
if(position != 0 ){
GameTask current = adapter.getItem(position);
ArrayList<GameTask> list = new ArrayList<GameTask>();
for( int i = 0; i < adapter.getCount(); i++ )
list.add(adapter.getItem(i));
list.remove(position);
list.add(position-1, current);
adapter.clear();
for( int i = 0; i < list.size(); i++ ){
adapter.add(list.get(i));
}
adapter.notifyDataSetChanged();
}
}
});
buttonDown.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
ListAdapter adapter = ListAdapter.this;
if(position != adapter.getCount()-1 ){
GameTask current = adapter.getItem(position);
ArrayList<GameTask> list = new ArrayList<GameTask>();
for( int i = 0; i < adapter.getCount(); i++ )
list.add(adapter.getItem(i));
list.remove(position);
list.add(position+1, current);
adapter.clear();
for( int i = 0; i < list.size(); i++ ){
adapter.add(list.get(i));
}
adapter.notifyDataSetChanged();
}
}
});
return rowView;
}
Both listeners do almost the same, the only difference is the condition and the value of shifting +1/-1. I was wondering about creating the inner class implementing OnClickListener in the extended ArrayAdapter class however, I have no idea, how I could then pass the position of the row clicked to this inner class.
Instead of adding and removing elements from your ArrayList, you can better implement Collections.swap(List list, int firstElementIndex, int secondElementIndex) it would be much easier as you don't have to iterate through the whole Collection. A simple example for the same can be found here.
You could make a method that would be used by both buttonUp and buttonDown. This method could take as a parameter the type of action that was pressed (UP/DOWN), and the position of item in ListView, and then call this method in both of your click listener passing the appropriate action.
Example:
// 2 new constants
private static final int UP = 0;
private static final int DOWN = 1;
// Based on "type", increment or decrement the position.
private void changeRow(int type, int position){
if(type==UP){
position=position-1;
}else if(type==DOWN){
position=position+1;
}
// ........
// Then in your "for" cicle you specify:
list.add(position, current);
// ........
}
Then in the onClick() method of buttonUp you specify:
changeRow(UP, position);
and for buttonDown:
changeRow(DOWN, position);
This can be easily achieved
The way to do this is to store the data to be displayed in an List
Then when the user clicks the up or down arrow
Swap the references of data items which are shifting position using Collections.swap(List, int, int)
Then call notifyDataSetChanged on the adapter

Retrieving the selected items from a multi-select ListView

I am currently implementing a multi-select ListView for my android app. My aim is to retrieve the selected items from the ArrayAdapter associated with the ListView when clicking the search button.
I am currently stumped on how to do this, I have found stuff online such as trying to set a MultiChoiceModeListener, but this does not seem to come up as an option in Eclipse. I am using Google APIs(level 10), Android 2.3.3 equivalent. Here is the code I have so far:
public class FindPlace extends Activity {
public FindPlace() {}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_places);
Button search = (Button) findViewById(R.id.search);
String[] categories = getResources().getStringArray(R.array.Categories);
ArrayAdapter ad = new ArrayAdapter(this,android.R.layout.simple_list_item_multiple_choice,categories);
final ListView list=(ListView)findViewById(R.id.List);
list.setAdapter(ad);
list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { }
});
}
}
Slightly more efficiently / correctly:
SparseBooleanArray checked = listView.getCheckedItemPositions();
for (int i = 0; i < checked.size(); ++i)
{
if (checked.valueAt(i))
{
int pos = checked.keyAt(i);
doSomethingWith(adapter.getItem(pos));
}
}
Use the method getCheckedItemPosition().
take the count of the selected item in the int and make for loop like below.
int len = listView.getCount();
SparseBooleanArray checked = listView.getCheckedItemPositions();
for (int i = 0; i < len; i++){
if (checked.get(i)) {
String item = cont_list.get(i);
/* do whatever you want with the checked item */
}
}

get all checked item of listview on check of checkbox without using POJO class [duplicate]

I've a couple of question I haven't been able to figure out.
I'm trying to get all the checked elements from a ListView but:
If I check and then uncheck an element, it's returned as "checked" by the getCheckedItemPositions() function
I don't know how can I iterate through this:
SparseBooleanArray checked = list.getCheckedItemPositions();
The other answers using SparseBooleanArray are nearly correct, but they are missing one important thing: SparseBooleanArray.size() will sometimes only return the count of true values. A correct implementation that iterates over all the items of the list is:
SparseBooleanArray checked = list.getCheckedItemPositions();
for (int i = 0; i < list.getAdapter().getCount(); i++) {
if (checked.get(i)) {
// Do something
}
}
I solved my case with this:
public class MyAdapter extends BaseAdapter{
public HashMap<String,String> checked = new HashMap<String,String>();
....
public void setCheckedItem(int item) {
if (checked.containsKey(String.valueOf(item))){
checked.remove(String.valueOf(item));
}
else {
checked.put(String.valueOf(item), String.valueOf(item));
}
}
public HashMap<String, String> getCheckedItems(){
return checked;
}
}
To set an element is checked:
public class FileBrowser extends Activity implements OnClickListener{
private ListView list;
...
list.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int item,
long id) {
BrowserAdapter bla = (BrowserAdapter) parent.getAdapter();
bla.setCheckedItem(item);
}
});
Then to get the checked items from outside the class..
MyAdapter bAdapter;
Iterator<String> it = bAdapter.getCheckedItems().values().iterator();
for (int i=0;i<bAdapter.getCheckedItems().size();i++){
//Do whatever
bAdapter.getItem(Integer.parseInt(it.next());
}
Hope it can help someone.
Jarett's answer is great, but this should be a bit faster, since it's only checking the elements in the sparse array that are present in the underlying array (only those can be true):
SparseBooleanArray checkedItemPositions = listView.getCheckedItemPositions();
final int checkedItemCount = checkedItemPositions.size();
for (int i = 0; i < checkedItemCount; i++) {
int key = checkedItemPositions.keyAt(i);
if (checkedItemPositions.get(key)) {
doSomething(key);
} else {
// item was in the sparse array, but not checked.
}
}
Pro tip: look at the source of SparseBooleanArray, it's a pretty simple class:
http://grepcode.com/file_/repository.grepcode.com/java/ext/com.google.android/android/4.0.3_r1/android/util/SparseBooleanArray.java/?v=source
My brain didn't like looping through the SparseBooleanArray and I didn't need a custom adapter, so the following was a little more intuitive for me:
Don't forget to use CHOICE_MODE_MULTIPLE in onCreate():
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
Use the following method to get an ArrayList of them:
// This example is to get an ArrayList of names (Strings)
protected ArrayList<String> getNames() {
ArrayList<String> names = new ArrayList<String>();
for (int i = 0; i < getListView().getCount(); i++) {
if (getListView().isItemChecked(i)) {
// Do whatever you need to in here to get data from
// the item at index i in the ListView
names.add(mUsers.get(i).getName());
}
}
return names;
}
You can iterate through the SparseBooleanArray using a for loop and the SparseBooleanArray's size() and get(index) methods.
EDIT 3/2/2014: People have pointed out that SparseBooleanArray's size() method returns the number of checked values, rather than the true length of the array, so I have mended my answer to account for that. Essentially it is the same, except that rather than iterating for the length of the array, we iterate until we have found all checked items. Since we only care about the number of checked items, it's irrelevant that with this method, we may not actually get to the end of the array (we won't see anything past the last checked item).
SparseBooleanArray checked = list.getCheckedItemPositions();
int numChecked = checked.size();
for (int i = 0; numChecked > 0; i++){
if (checked.get(i)){
//the item at index i is checked, do something
numChecked--; //We found a checked item, so decrement the number of checked items remaining
}
else
//the item is not checked, do something else
}
final long[] checkedIds = lv.getCheckItemIds();
for (int i = 0; i < checkedIds.length; i++) {
Log.d("checkedIds", "id checked: " + checkedIds[i]);
}
Just saw the question and I was facing the same problem.
There is a simpler solution using SparseBooleanArray to exactly count how many items are checked.
This is my onClick procedure:
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.button:
SparseBooleanArray a = listView.getCheckedItemPositions();
if(checked(vArray)>0) {
String vCheckedList = "";
for (int i = 0; i < nLength; i++) {
if (a.valueAt(i) && i < nLength-1 && a.size()>1)
vCheckedList += listView.getAdapter().getItem(vArray.keyAt(i))+"\n";
else if (a.valueAt(i))
vCheckedList += listView.getAdapter().getItem(vArray.keyAt(i));
}
Toast.makeText(getApplicationContext(), vCheckedList+ " is checked", Toast.LENGTH_SHORT).show();
a.clear();
} else
Toast.makeText(getApplicationContext(), "No Item is Selected", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
The checked method:
private int checked(SparseBooleanArray vArray) {
int vCounter = 0;
for(int i=0;i<vArray.size(); i++)
if(vArray.valueAt(i))
vCounter++;
return vCounter;
}
It will solve both problem of the checked items.
I had the same problem and here is my solution with SparseBooleanArray :
SparseBooleanArray checkedPositions = lv.getCheckedItemPositions ();
int size = checkedPositions.size ();
for (int i=0 ; i<size ; i++) {
// We get the key stored at the index 'i'
int key = checkedPositions.keyAt (i);
// We get the boolean value with the key
Log.i (Tag, "checkedPositions(" + key + ")=" + checkedPositions.get (key));
}
In it's entirety this is the solution I used.
Where pos is the Recyclerview item position
SparseBooleanArray selected = new SparseBooleanArray();
//OnClick listener here or whatever you use to check or uncheck an item
if (selected.get(pos, false)) {
selected.delete(pos);
} else {
selected.put(pos, true);
}
selected.size() will reveal how many items are selected
selected.get(pos) will return true if it's selected
The following as has been stated, iterates over all those items which were selected:
for (int i = 0; i < list.getAdapter().getCount(); i++) {
if (selected.get(pos)) {
// Do stuff
}
}
Here is how I get checked items from recyclerview adapter
fun getAllCheckedItems(outList){
for (position in spareBooleanArray.keyIterator()) {
outList.add(mList.get(position)
}
}

Categories

Resources