0

I am facing weird problem with my Custom Adapter for listview My adapter repeat item's ID every 10th records.

I really appreciate for any help and/or idea

My ListActivity

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
            super.onCreate(savedInstanceState);
            requestWindowFeature(Window.FEATURE_NO_TITLE);
            setContentView(R.layout.activity_backuplist); // Get main display layout
            lv = (ListView) findViewById(android.R.id.list);
            lists = new ArrayList<BackupListView>();

            int j = 50;
            for (int i = 0; i < 15; i++)
            {
        String fileName = ((i % 2) == 0) ? "sample.csv" : "sample.vcf";
        String fileExt  = ((i % 2) == 0) ? "csv" : "vcf";
        lists.add(new BackupListView(fileName + "\ndate 2014/05/20", j, fileExt, "210"));

        j++;
    }

    int x = lists.size();
    BackupListView[] toArray = new BackupListView[x];
    toArray = lists.toArray(toArray);

    adapter = new BackupListAdapter(this, R.layout.custom_backup_listview_rows, toArray);
    lv.setAdapter(adapter);
    lv.setClickable(true);
    lv.setOnItemClickListener(new OnItemClickListener()
    {
        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id)
        {
            dspDialog();
        }
    });
}

And this is my Custom adapter

public class BackupListAdapter extends ArrayAdapter<BackupListView>
    {
    private Context context;
    private int resID;
    BackupListView[] data = null;
    private ArrayList<String> checkedItem = new ArrayList<String>();

    public BackupListAdapter(Context context, int resource, BackupListView[] objects)
    {
    super(context, resource, objects);
    this.context = context;
    this.resID = resource;
    this.data = objects;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent)
{
    CustomHolder holder = null;

    if (convertView == null)
    {
        LayoutInflater inflate = ((Activity) context).getLayoutInflater();
        convertView = inflate.inflate(resID, null);

        holder = new CustomHolder();
        holder.cb = (CheckBox) convertView.findViewById(R.id.custom_checkbox);
        holder.im = (ImageView) convertView.findViewById(R.id.img_file_ext_icon);
        holder.tw = (TextView) convertView.findViewById(R.id.custom_textView);
        holder.bt = (ImageView) convertView.findViewById(R.id.custom_button);

        final BackupListView lists = data[position];
        holder.tw.setText(lists.getText() + "  " + lists.getFileSize() + "kb");
        holder.id = lists.getId();

        Log.i("TEST ", "List getId " + lists.getId());

        // Check box event
        holder.cb.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                if (((CompoundButton) v).isChecked())
                {
                    checkedItem.add("" + lists.getId());
                }
                else
                {
                    checkedItem.remove("" + lists.getId());
                }
            }
        });

        //  Set CSV file extension icon
        if(lists.getExt().equals("csv"))
            holder.im.setBackgroundResource(R.drawable.icon_csv);
        else
            holder.im.setBackgroundResource(R.drawable.icon_vcf);

        // Button event
        holder.bt.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                final View inflater;
                inflater = ((Activity) context).getLayoutInflater().inflate(
                        R.layout.dialog_filename_change, null);

                AlertDialog.Builder dialog = new AlertDialog.Builder(
                        context.getApplicationContext());
                dialog.setTitle("Enter Pass");
                dialog.setView(inflater);
                dialog.setInverseBackgroundForced(true);
                dialog.setNegativeButton("Cancel", null);
                dialog.setPositiveButton("OK", new OnClickListener()
                {
                    @Override
                    public void onClick(DialogInterface dialog, int which)
                    {
                        Intent i = new Intent(context.getApplicationContext(),
                                PhoneBookDetail.class);
                        i.putExtra("id", lists.getId());
                        context.startActivity(i);
                    }
                });
                dialog.create();

                Log.i("TEST", " Clicked " + lists.getId());

                //dialog.show();
            }
        });

        convertView.setTag(holder);
    }
    else
    {
        holder = (CustomHolder) convertView.getTag();
    }

    return convertView;
}

public class CustomHolder
{
    CheckBox    cb;
    ImageView   im;
    TextView    tw;
    ImageView   bt;
    int         id;
}

}

And result is

04-18 16:31:12.840: I/TEST(21986): List getId 50
04-18 16:31:12.856: I/TEST(21986): List getId 51
04-18 16:31:12.863: I/TEST(21986): List getId 52
04-18 16:31:12.871: I/TEST(21986): List getId 53
04-18 16:31:12.879: I/TEST(21986): List getId 54
04-18 16:31:12.887: I/TEST(21986): List getId 55
04-18 16:31:12.895: I/TEST(21986): List getId 56
04-18 16:31:12.903: I/TEST(21986): List getId 57
04-18 16:31:12.910: I/TEST(21986): List getId 58
04-18 16:31:14.535: I/TEST(21986):  Clicked 55
04-18 16:31:15.840: I/TEST(21986):  Clicked 54
04-18 16:31:16.871: I/TEST(21986):  Clicked 53
04-18 16:31:17.238: I/TEST(21986):  Clicked 52
04-18 16:31:17.910: I/TEST(21986):  Clicked 53
04-18 16:31:18.309: I/TEST(21986):  Clicked 54
04-18 16:31:20.121: I/TEST(21986):  Clicked 56
04-18 16:31:20.645: I/TEST(21986):  Clicked 56
04-18 16:31:21.442: I/TEST(21986):  Clicked 57
04-18 16:31:23.067: I/TEST(21986):  Clicked 58
04-18 16:31:24.785: I/TEST(21986):  Clicked 53
04-18 16:31:26.481: I/TEST(21986):  Clicked 50
04-18 16:31:27.903: I/TEST(21986):  Clicked 58
04-18 16:31:28.965: I/TEST(21986): List getId 59
04-18 16:31:30.090: I/TEST(21986):  Clicked 59
04-18 16:31:33.520: I/TEST(21986):  Clicked 59
04-18 16:31:35.559: I/TEST(21986):  Clicked 50
Lucifer
  • 29,392
  • 25
  • 90
  • 143
  • see http://stackoverflow.com/questions/11945563/how-listviews-recycling-mechanism-works, you need save changes in one area and for changing items read (like List) from that – Shayan Pourvatan Apr 18 '14 at 07:56
  • Yener selam , her on kayıtta bir mi göstermek istiyorsun yani on kayıt yüklüyorsun sonra refresh te veya son kayıta gelince yeni onkayıt falan mı yüklemeye çalışıyorsun – CompEng Apr 18 '14 at 07:59
  • 1
    @ErsinGülbahar english pls. this ia english QA site – Raghunandan Apr 18 '14 at 08:01
  • @Raghunandan sure, I will – CompEng Apr 18 '14 at 08:03
  • The more interesting thing is that i am using same Adapter for phonelist but it works excellent. Anyway, i always use list adapter for my every single projects but first time i am having facing such an error. @shayan thanks for the link. i have just read it but i cannot make fix width and height for my listview. –  Apr 18 '14 at 08:16
  • why you don't use `holder.getId()` instead of `list.getId()`? – Shayan Pourvatan Apr 18 '14 at 08:28
  • Because i am using listener in the code doesn't matter using holder or list. I must use "final" keyword at the end when ever i want to use value inside of listener. –  Apr 18 '14 at 08:53

2 Answers2

0

Initialize an Array:

Map<Integer,boolean> checkBoxMap = new Map<Integer,boolean>();

In getView method the below should be first implemented.

    if (convertView == null)
        {
            LayoutInflater inflate = ((Activity) context).getLayoutInflater();
            convertView = inflate.inflate(resID, null);

            holder = new CustomHolder();
            holder.cb = (CheckBox) convertView.findViewById(R.id.custom_checkbox);
            holder.im = (ImageView) convertView.findViewById(R.id.img_file_ext_icon);
            holder.tw = (TextView) convertView.findViewById(R.id.custom_textView);
            holder.bt = (ImageView) convertView.findViewById(R.id.custom_button);  convertView.setTag(holder); 
    } else {
     holder = (CustomHolder) convertView.getTag();  
    }
// Check box event
        holder.cb.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                checkBoxMap.put(position,((CompoundButton) v).isChecked())
            }
        });
holder.cb.setChecked(checkBoxMap.get(position));

remaining all listeners and setText everything should be after the above code.

I mean all the below cose should follow above code.

final BackupListView lists = data[position];
        holder.tw.setText(lists.getText() + "  " + lists.getFileSize() + "kb");
        holder.id = lists.getId();

        Log.i("TEST ", "List getId " + lists.getId());

        // Check box event
        holder.cb.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                if (((CompoundButton) v).isChecked())
                {
                    checkedItem.add("" + lists.getId());
                }
                else
                {
                    checkedItem.remove("" + lists.getId());
                }
            }
        });

        //  Set CSV file extension icon
        if(lists.getExt().equals("csv"))
            holder.im.setBackgroundResource(R.drawable.icon_csv);
        else
            holder.im.setBackgroundResource(R.drawable.icon_vcf);

        // Button event
        holder.bt.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                final View inflater;
                inflater = ((Activity) context).getLayoutInflater().inflate(
                        R.layout.dialog_filename_change, null);

                AlertDialog.Builder dialog = new AlertDialog.Builder(
                        context.getApplicationContext());
                dialog.setTitle("Enter Pass");
                dialog.setView(inflater);
                dialog.setInverseBackgroundForced(true);
                dialog.setNegativeButton("Cancel", null);
                dialog.setPositiveButton("OK", new OnClickListener()
                {
                    @Override
                    public void onClick(DialogInterface dialog, int which)
                    {
                        Intent i = new Intent(context.getApplicationContext(),
                                PhoneBookDetail.class);
                        i.putExtra("id", lists.getId());
                        context.startActivity(i);
                    }
                });
                dialog.create();

                Log.i("TEST", " Clicked " + lists.getId());

                //dialog.show();
            }
        });
Pavandroid
  • 1,586
  • 2
  • 15
  • 30
  • Thanks for reply. I already done that but somehow it is not working. Also another problem is when I click checkbox at #1 item in the list and scroll list fast top to bottom bottom to top then check mark at #1 move to random item in the list view. Very very strange situation. –  Apr 21 '14 at 05:06
  • Maintain an array like ArrayList arrayBool = new ArrayList(); In checkBox onClick method keep like arrayBool[position] = checkBox.isChecked(); In getView method keep like checkBox.setChecked(arrayBool[position]); This will fix your issue. – Pavandroid Apr 21 '14 at 05:22
  • Changed my answer with Map. please check this solution. It should work now with this implemenattion – Pavandroid Apr 21 '14 at 05:35
  • Take the checkBoxMap implemenattion completely – Pavandroid Apr 21 '14 at 05:36
  • I am sorry but i couldn't handle this situation i guess i need more actual examples with more show cases. –  Apr 21 '14 at 05:50
0

lists variable is final and used in the on click pointing to a specific position..when the view is recycled..lists remains the same so you get duplicates

dangVarmit
  • 5,641
  • 2
  • 22
  • 24