0

Have problem with repeating items reaction to click in custom adapter list view. Actually method in onClick applying for clicked element and if i scroll down my list some of elements repeats the same.
So when i'm try to solve it with Tag its not help me. I'm try to use different realization which find on Stack and Google but it can't help also. That is my lust code of realization

public class CAChanal extends BaseAdapter {
    private Context context;

    protected MainActivity MAcontext;

    public CAChanal(MainActivity _context){
        MAcontext = _context;
    }

    public CAChanal(Context context) { 
        this.context = context;
    }

    ArrayList<DMChanal> listArray;
    public CAChanal() {
        listArray = new ArrayList<DMChanal>();
    }
    @Override
    public int getCount() {
        return listArray.size(); 
    }

    @Override
    public Object getItem(int i) {
        return listArray.get(i); 
    }

    @Override
    public long getItemId(int i) {
        return i; 
    }

    @Override
    public View getView(int index,View view, ViewGroup parent) {
         final ViewHolder holder ; 
        if (view == null) { 
            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
            view = inflater.inflate(R.layout.chanal_template, null);
            holder = new ViewHolder(); 
            holder.chanalElement=(ChanalView)view.findViewById(R.id.chanalView_forList);
            view.setTag(holder);
        }else
        {
             holder = (ViewHolder)view.getTag();
        }


         holder.chanalElement.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                if(!holder.chanalElement.getChanalStatus())
                {
                     holder.chanalElement.enableChanal();
                }else
                {
                     holder.chanalElement.disableChanal();
                }
            }
        });     
        return view;
    } 
    static class ViewHolder {
         ChanalView chanalElement;
        }

    public Object getFilter() {

        return null;
    } 


}  

Can any one help me to solve my problem and explain what can be wrong in my code. P.S: ChanalView is my custom view

once2go
  • 1,452
  • 1
  • 13
  • 21
  • 1
    You are enabling/disabling Chanal on a click event. So that view (which is recycled) will ALWAYS have that enabled/disabled status until the user clicks the view again. Since the views are recycled, when you scroll away the views will have the enabled status that was previously set. So you will need to persist the enabled status in like an array or something similar and update the enabled status every getView(). – kgmaize Oct 27 '14 at 18:37
  • but, i'm think, that viewHolder must do that (persist state of view end return the state of it(enabling/disabling))When i'm check if view not null i'm get view state with tag which i set for new one. Is it wrong? – once2go Oct 27 '14 at 18:54
  • You are correct. The view will stay the same after it is recycled. So maybe I don't understand your question. – kgmaize Oct 27 '14 at 19:41
  • So, i have 15 element in my list view. All of elements have custom view "ChanalView". ChanalView view can be in 2 states "on" and "off". In custom adapter i apply onClick listnener for ChanaLView that make on/off switching. So after clicking for example on first element, it stay switch "on" end when i scroll down some of element in view switching also. When i scroll back some times this element shows like swithing on but some times switching off. I'm add checking in getView(if permanent_arrray[position]==true means ChanalView in LV is enabled else disabled)So it also not help =( – once2go Oct 28 '14 at 12:23
  • This has to do with the views recycling as I mentioned in my first comment. I will post an answer shortly. – kgmaize Oct 28 '14 at 16:07

1 Answers1

0
public class MyAdapter extends BaseAdapter {

     List<DMChanal> listArray;
     List<Boolean> chanalElementStates = new ArrayList<Boolean>();

     ...

     @Override
     public View getView(final int index,View view, ViewGroup parent) {
         final ViewHolder holder ; 
         if (view == null) { 
            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
            view = inflater.inflate(R.layout.chanal_template, null);
            holder = new ViewHolder(); 
            holder.chanalElement = (ChanalView)view.findViewById(R.id.chanalView_forList);
            view.setTag(holder);
        } else {
            holder = (ViewHolder)view.getTag();
        } 

        holder.chanalElement.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                boolean enabled = !chanalElementStates[index];
                chanalElementStates[index] = enabled;
                updateEnabledState(holder, enabled);
            }
        }); 

        // What you were missing. You always have to reset the state to 
        // what you want because the views are recycled.
        updateEnabledState(holder, chanalElementStates[index]);

        return view;
    } 

    private void updateEnabledState(ViewHolder holder, boolean enable) {
        if (enable)
            holder.chanalElement.enableChanal();
        else
            holder.chanalElement.disableChanal();    
    }
}
kgmaize
  • 186
  • 1
  • 6
  • So sory, but what about another value? For example when i set some text to my view and scrool text stay the same which i set by adapter. I also apply permanent array with values but text redraw to previous – once2go Nov 03 '14 at 19:39
  • Try using a model/class to store the info for each row/item in your list. Update the model when necessary such as when you "set some text to my view". This way each rows data will be stored in the model. – kgmaize Nov 03 '14 at 19:51