4

Hope everyone's good;

I know this issue was reviewed earlier couple of times but after a long search I still didn't find a solution.

My custom listview duplicates items every 6 item.

Already checked and tried:

1- layout_width and layout_height doesn't contain wrap_content

2- holder = new ListViewItem() is before any initialization of contents

3- There is a "convertView != null"

4- holder.linearLayout.getChild() can't be use in my case because the layout isn't Linear

5- clear()

If anyone can help me this is my codes

getView() of CustomListViewAdapter.java

public View getView(final int position, View convertView, ViewGroup parent) {  

    ListViewItem item = items.get(position);
    ListViewItem holder;


    View vi=convertView;

    inflater = (LayoutInflater)    getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);



    if(vi==null){

        vi = inflater.inflate(R.layout.item, null);
        holder = new ListViewItem();
        holder.cb = (CheckBox) vi.findViewById(R.id.Item1);
        holder.sp = (Spinner) vi.findViewById(R.id.Item2);
        holder.title = (TextView) vi.findViewById(R.id.Item3);
        holder.pricetitle= (TextView) vi.findViewById(R.id.item4);
        holder.Descriptiontitle= (TextView) vi.findViewById(R.id.Item5);
        vi.setTag(holder);

    }else{
        holder = (ListViewItem) vi.getTag();
    }



    holder.title.setText(item.ItemTitle);
    holder.pricetitle.setText(item.price+"");
    holder.Descriptiontitle.setText(item.Description);

    return vi;  
}

ListViewItem class

static class ListViewItem{
    public String ItemTitle;
    public int price;
    public String Description;
    public TextView title;
    public TextView pricetitle;
    public TextView Descriptiontitle;
    public CheckBox cb;
    public Spinner sp;
}

MainActivity

 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){

    View v = inflater.inflate(R.layout.starterbottom, null);

    ListView myList = (ListView)v.findViewById(R.id.MyListStarter);

    List<ListViewItem> items = new ArrayList<ListViewItem>();

    for(int i=0;i<10;i++){

        items.add(new ListViewItem(){{
            ItemTitle = "Starter Title";
            Description= "Your description goes here";
            price=0;
        }});

    }

    CustomListViewAdapter listadapter = new CustomListViewAdapter(getActivity(), android.R.layout.simple_list_item_1, items);

    myList.setAdapter(listadapter);

    return v;
}

EDIT

MainmenuActivity.java

public class MainmenuActivity extends SlidingActivity{


Button buttononside;
TextView title;
FragmentAdapter mAdapter;
ViewPager mPager;
PageIndicator mIndicator;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_mainmenu);
    setBehindContentView(R.layout.sidemenu);

    mAdapter = new FragmentAdapter(getSupportFragmentManager());
    mPager = (ViewPager)findViewById(R.id.pager);

    mPager.setAdapter(mAdapter);
    mPager.setOffscreenPageLimit(4);
    mIndicator = (PageIndicator)findViewById(R.id.indicator);
    mIndicator.setViewPager(mPager);

    getSlidingMenu().setBehindOffset(200);
    getSlidingMenu().setMode(SlidingMenu.RIGHT);
    getSlidingMenu().setFadeDegree(0.35f);

    title = (TextView) findViewById(R.id.Title);
    title.setText("Starters");




}


public boolean onCreateOptionsMenu(android.view.Menu menu) {
    getMenuInflater().inflate(R.menu.mainmenu, menu);
    return true;
}


public void onClick(View v) {
    getSlidingMenu().toggle();

}

public void changecolor(View v){
    buttononside = (Button) findViewById(v.getId());


    buttononside.setOnTouchListener(new OnTouchListener(){

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction()==MotionEvent.ACTION_DOWN)
                buttononside.setBackgroundColor(Color.BLACK); 
            else
                buttononside.setBackgroundResource(R.drawable.buttonshape);
            return true;
        }

    });
}


static class ListViewItem{
    public String ItemTitle;
    public int price;
    public String Description;
    public TextView title;
    public TextView pricetitle;
    public TextView Descriptiontitle;
    public CheckBox cb;
    public Spinner sp;
}

}

FragmentAdapter.java

public class FragmentAdapter extends FragmentPagerAdapter implements IconPagerAdapter{

  public FragmentAdapter(FragmentManager fm) {
        super(fm);
    }

@Override
public int getIconResId(int index) {
    return 0;
}

@Override
public Fragment getItem(int position) 
{
    android.support.v4.app.Fragment fragment = new StarterActivity();
    switch(position){
    case 0:
        fragment = new MainActivity();
        break;
    case 1:
        fragment = new SecondActivity();
        break;
    case 2:
        fragment = new ThirdActivity();
        break;
    case 3:
        fragment = new FourthActivity();
        break;
    }
    return fragment;
}

@Override
public int getCount() {
    // TODO Auto-generated method stub
    return 4;
}

@Override
public CharSequence getPageTitle(int position){
    String title = "";
    switch(position){
    case 0:
        title = "First";
        break;
    case 1:
        title = "Second";
        break;
    case 2:
        title = "Third";
        break;
    case 3:
        title = "Fourth";
        break;
    }
    return title;
 }
}

MainActivity.java

public class MainActivity extends Fragment {


int i=0;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){

    View v = inflater.inflate(R.layout.starterbottom, null);

    ListView myList = (ListView)v.findViewById(R.id.MyListStarter);

    List<ListViewItem> items = new ArrayList<ListViewItem>();

    for(i=0;i<10;i++){

        items.add(new ListViewItem(){{
            ItemTitle = "Title "+i;
            Description= i+" Your Own description";
            price= i;
        }});

    }

    CustomListViewAdapter listadapter = new CustomListViewAdapter(getActivity(), R.layout.item, items);

    myList.setAdapter(listadapter);

    return v;

    }
 }

Thanks in advance, Regards, Chris

Odin
  • 642
  • 1
  • 9
  • 27
  • `Listview duplicates item every 6 times` - What does this mean? In the `for-loop` inside your `onCreateView()`, change `price=0;` to `price=i;`. Do the items still duplicate? – Vikram Jul 22 '13 at 23:42
  • Seems like there is stuff missing from your code that makes it hard to diagnose the issue. From what you have included, there is nothing blatantly obvious. I would try changing `ListViewItem item = items.get(position);` to `ListViewItem item = getItem(position)` assuming that you mistakenly put `CustomListView.java` instead of `CustomListViewAdapter.java` – Chris Feist Jul 22 '13 at 23:44
  • 1
    And why is the layout `android.R.layout.simple_list_item_1` in your adapter's constructor? You are inflating, changing, and returning a custom one in your getView(). – Vikram Jul 22 '13 at 23:45
  • The only issue i see in the getView, is that you forgot to "reset" the values of some of the childs in the holder, which would cause that for example: if one element DOES HAVE price properly display it, but if another element DO NOT have price, that text will be filled with one of the reused views... – Martin Cazares Jul 23 '13 at 00:00
  • First of all thanks for your quick replies I really apperciate that.. @vikram if i set price=i; I get the correct order from 0 to 9.. but if I checked the CheckBox on position 0 it will get checked automatically on position 6 too.. I didn't catch the simple_list_item_1 , i did change it to R.layout.item correctly but it didn't fix my problem yet. – Odin Jul 23 '13 at 00:21
  • @Chris yes sorry it's CustomListViewAdapter.java .. already tried to manipulate getItem(position) but without success.. thanks anws – Odin Jul 23 '13 at 00:21
  • @Martin thanks for pointing this out for me but till now i'm just trying out the app.. later on i will link it and get the prices from a database so i wont have this problem anymore. – Odin Jul 23 '13 at 00:22
  • Chris, can you post the code when you define the behavior for `CheckBox`? Better yet, post the whole of `MainActivity`. – Vikram Jul 23 '13 at 00:31
  • Well it's kind of complicated because i'm using slidingmenu, viewpagerindicator and fragmentadapter too.. I will edit and post the mainmenuactivity which loads the slidingmenu and the fragmentadapter that sets the fragments of the ViewPagerIndicator :) – Odin Jul 23 '13 at 00:39
  • If clicking on the one `CheckBox` is affecting two of them, then it would be helpful to post code where you set them up, set their `OnClickListeners` etc. – Vikram Jul 23 '13 at 00:42
  • @vikram ummm i didn't implement any OnClickListener yet..but the problem is also present with the Spinner.. so I don't think it's a listener problem.. – Odin Jul 23 '13 at 00:46
  • @vikram I tried adding holder.cb.setChecked(false); to the getView()... the postion 6 isn't getting checked anymore but when scrolling position 0 also gets unchecked.. I guess using savedInstanceState will solve my problem? any ideas? – Odin Jul 23 '13 at 01:08
  • I'll explain the problem. But, can try the code in my post below? If it works, we can discuss on this issue. – Vikram Jul 23 '13 at 01:38
  • If you are using extends BaseAdapter then this solution will work. [http://stackoverflow.com/a/28791031/4531507](http://stackoverflow.com/a/28791031/4531507) – Rahul Sharma Aug 22 '16 at 11:46

1 Answers1

5

I see the problem now. And no, there is no duplication here. Carry out these few changes:

In your static class ListViewItem, add boolean isChecked;

static class ListViewItem{
    public String ItemTitle;
    public int price;
    public String Description;
    public TextView title;
    public TextView pricetitle;
    public TextView Descriptiontitle;
    public CheckBox cb;
    public Spinner sp;
    public boolean isChecked;    // <--- added
}

Change the initialization of items:

items.add(new ListViewItem(){{
        ItemTitle = "Starter Title";
        Description= "Your description goes here";
        price=i;
        isChecked = false;
    }});

In the getView() method, after holder.Descriptiontitle.setText(item.Description);, add:

holder.cb.setOnClickListener(new OnClickListener() {

  @Override
  public void onClick(View v) {

    if (((CheckBox) v).isChecked()) {
                item.isChecked = true;
    } else {
                item.isChecked = false;
            } 
  }
});


if (item.isChecked) {
    holder.cb.setChecked(true);
} else {
    holder.cb.setChecked(false);
}

Add the final keyword to ListViewItem item = items.get(position);:

final ListViewItem item = items.get(position);
Vikram
  • 51,313
  • 11
  • 93
  • 122
  • Wow thanks a lot @vikram for taking the time to help me out it finally worked :) I'm really grateful !! I understood that I had to initialize if the checkbox was checked or no.. but why did the listener solve my problem if there isn't anything affecting the other checkboxes? – Odin Jul 23 '13 at 07:55
  • I'm having an issue now with the Spinner.. after scrolling the values get messed up.. I'm using the setOnItemSelectedListener if anyone has an idea what might be the problem – Odin Jul 23 '13 at 18:46
  • 1
    @Chris Use a similar approach(one that you used tosolve the CheckBox problem). Create a integer variable in `ListViewItem` like `int spinnerValue`. Add a ` setOnItemSelectedListener (AdapterView.OnItemSelectedListener listener)` listener to Spinner instances in your getView(). When a values is selected from this spinner the method `onItemSelected(AdapterView> parent, View view, int position, long id)` will be called. Save the `position` to `spinnerValue` of the `ListViewItem`. – Vikram Jul 23 '13 at 18:55
  • 1
    @Chris In your getView(), add a line of code: `holder.sp.setSelection(item.spinnerValue)`. Don't forget to initialize these values in the for-loop in MainActivity: `spinnerValue = 0`. – Vikram Jul 23 '13 at 18:58
  • 1
    man i don't know how to thank you.. I was doing like you mentioned but using setOnItemClickListener instead of setOnItemSelectedListener even though I know that I need to use the first one lol.. Everything works great now.. your the best thanks a lot :) – Odin Jul 23 '13 at 22:31