Reputation: 2726
I'm facing with one problem, it's about disappearing checked items in listview when I'm scrolling the list and I don't know what to do.
Here is my code of custom adapter:
public class SPCKontrola extends Activity {
ArrayList<Integer> yourSelectedItems= new ArrayList<Integer>();
@Override
public void onResume() {
super.onResume();
yourSelectedItems.clear();
}
}
public class SPCMjereAdapter extends BaseAdapter
{
private Context context;
public SPCMjereAdapter(Context c)
{
context = c;
}
public int getCount() {
return MyArrList.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.activity_list_row, null);
}
TextView txtOpis = (TextView) convertView.findViewById(R.id.ColOpis);
txtOpis.setText(MyArrList.get(position).get("OpisMjere") );
TextView txtRbMjere = (TextView) convertView.findViewById(R.id.ColCode);
txtRbMjere.setText(MyArrList.get(position).get("RbMjere"));
CheckBox Chk = (CheckBox) convertView.findViewById(R.id.ColChk);
Chk.setTag(MyArrList.get(position).get("RbMjere"));
Chk.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
yourSelectedItems.add(position);
}else{
if(yourSelectedItems.contains(position)){
yourSelectedItems.remove((position));
}
}
}
});
return convertView;
}
}
What should I change or add in code? I have found some examples but I can't reuse non of them and implement in my code :/
Upvotes: 1
Views: 2964
Reputation: 2726
I think I get something... Instead of Chk.setOnCheckedChangeListener()
I've changed to Chk.setOnClickListener(new OnClickListener()
public class SPCMjereAdapter extends BaseAdapter
{
private Context context;
public SPCMjereAdapter(Context c)
{
context = c;
}
public int getCount() {
return MyArrList.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.activity_list_row, null);
}
TextView txtOpis = (TextView) convertView.findViewById(R.id.ColOpis);
txtOpis.setText(MyArrList.get(position).get("OpisMjere") );
TextView txtRbMjere = (TextView) convertView.findViewById(R.id.ColCode);
txtRbMjere.setText(MyArrList.get(position).get("RbMjere"));
final CheckBox Chk = (CheckBox) convertView.findViewById(R.id.ColChk);
if(yourSelectedItems.contains((position))){
Chk.setChecked(true);
}else{
Chk.setChecked(false);
}
Chk.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (Chk.isChecked())
{
yourSelectedItems.add(position);
} else
{
if(yourSelectedItems.contains(position)){
yourSelectedItems.remove((position));
}
}
}
});
return convertView;
}
}
Now it works fine when scrolling up/down. But there is another problem and i'm little bit confused. When scrolling and randomly check/uncheck items program crashes and these errors I get:
FATAL EXCEPTION: main
java.lang.IndexOutOfBoundsException: Invalid index 2, size is 2
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
at java.util.ArrayList.remove(ArrayList.java:399)
at com.dem.spckontrola.SPCKontrola$SPCMjereAdapter$1.onClick(SPCKontrola.java:830)
at android.view.View.performClick(View.java:4084)
at android.widget.CompoundButton.performClick(CompoundButton.java:100)
at android.view.View$PerformClick.run(View.java:16966)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method
)
Ok. I solved this by adding yourSelectedItems.remove(yourSelectedItems.indexOf(position));
So now the correct solution is:
public class SPCMjereAdapter extends BaseAdapter
{
private Context context;
public SPCMjereAdapter(Context c)
{
context = c;
}
public int getCount() {
return MyArrList.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.activity_list_row, null);
}
TextView txtOpis = (TextView) convertView.findViewById(R.id.ColOpis);
txtOpis.setText(MyArrList.get(position).get("OpisMjere") );
TextView txtRbMjere = (TextView) convertView.findViewById(R.id.ColCode);
txtRbMjere.setText(MyArrList.get(position).get("RbMjere"));
final CheckBox Chk = (CheckBox) convertView.findViewById(R.id.ColChk);
if(yourSelectedItems.contains((position))){
Chk.setChecked(true);
}else{
Chk.setChecked(false);
}
Chk.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (Chk.isChecked())
{
yourSelectedItems.add(position);
} else
{
if(yourSelectedItems.contains(position)){
yourSelectedItems.remove(yourSelectedItems.indexOf(position));
}
}
}
});
return convertView;
}
}
But now I'm facing with new problem: How to get list of all checked and unchecked items where some checkboxes (items) are not visible due to many items in listview which are visible only when scrolling down?
Upvotes: 0
Reputation: 1420
change your getview() with this one...
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.activity_list_row, null);
}
TextView txtOpis = (TextView) convertView.findViewById(R.id.ColOpis);
txtOpis.setText(MyArrList.get(position).get("OpisMjere") );
TextView txtRbMjere = (TextView) convertView.findViewById(R.id.ColCode);
txtRbMjere.setText(MyArrList.get(position).get("RbMjere"));
CheckBox Chk = (CheckBox) convertView.findViewById(R.id.ColChk);
if(yourSelectedItems.contains((position))){
Chk.setChecked(true);
}else{
Chk.setChecked(false);
}
Chk.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
yourSelectedItems.add(position);
}else{
if(yourSelectedItems.contains(position)){
yourSelectedItems.remove((position));
}
}
}
});
return convertView;
}
Upvotes: 1
Reputation: 3438
This happened to me and i solve this wtih,
1.Create a global boolean arraylist and fill it with MyArrList.size() on constructor.
2.When you changed checkbox value set arratlist with views index.
3.Change this:
CheckBox Chk = (CheckBox) convertView.findViewById(R.id.ColChk);
Chk.setTag(MyArrList.get(position).get("RbMjere"));
with this:
CheckBox Chk = (CheckBox) convertView.findViewById(R.id.ColChk);
Chk.setTag(MyArrList.get(position).get("RbMjere"));
Chk.setChecked(commentTexts.get(position));
Upvotes: 1
Reputation: 3745
To avoid the problems with CheckBoxes in a ListView you can take a Boolean array initialized false in the beginning and then making true the corresponding position in the array where checkbox is checked in the ListView. This will not cause a trouble in checked state of checkboxes when you move forward and backward in your application or scroll the ListView.You can check sample code here:
Android checkbox multiselected issue
Upvotes: 1
Reputation: 3285
You would be facing this prob if you have used getView in your listView.onItemSelectedListner The listView does not put every object in a different view thats why when you call getView(2) it will return the view of 2nd object of list on the screen not the view of second object of list... You have to implement it yourself using some boolean values or checkboxes in your class
Upvotes: 0
Reputation: 1420
for this you have to maintain an array variable yourSelectedItems[]
for storing the view positions that you have checked..and put a condition like this in your getView()
method..
if(yourSelectedItems.contains((position))){
check.setChecked(true);
}else{
check.setChecked(false);
}
you can manage you array by writing this method in your getView()
..
check.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
yourSelectedItems.add(position);
}else{
if(yourSelectedItems.contains(position)){
yourSelectedItems.remove((position));
}
}
});
Upvotes: 5
Reputation: 2182
try this example for listview with check box:http://lalit3686.blogspot.in/2012/06/today-i-am-going-to-show-how-to-deal.html
Upvotes: 1