Search code examples
androidandroid-layoutandroid-listviewandroid-arrayadapter

Inserting Separator in ListView using Array Adapter


Scenario : I have n number of tabs each tab is having its own listview. I am using a Array adapter to generate a listview. The array which is passed to arrayadaper is having array of objects. Each object has and . Now based on the menu type, if the menu type is "menugroup" i need to draw using a different layout and set the background to RED colour.

Question is simple.. Whenever I scroll down / up the property of menugroup row in listview is getting passed to other rows in listview. In otherwords scrolling disturbs the seperator.

Following is the code of Adapter. Could you please guide me to the point where it needs correction ? Thanks in Advance.

public class MyCustomAdapter  extends ArrayAdapter<Menu> {
private ArrayList<Menu> menuItemList; 
Context context;
LayoutInflater vi;

    public MyCustomAdapter(Context context ,ArrayList<Menu> menu) {    
        super(context, 0, menu );    
        this.menuItemList = new ArrayList<Menu>();    
        this.menuItemList.addAll(menu); 
        this.context =context;
        vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
    }    

    private class ViewHolder {
        TextView menuItem;   
        TextView menuGroup;  
    }
    public View getView(final int position, View convertView, ViewGroup parent) {      
        ViewHolder holder;    
        int type =0;
        String menuType = menuItemList.get(position).getMenuType();
        if (menuType.equals("menugroup"))
            type=1;
        if (menuType.equals("menuitem"))
            type=2;

        if (convertView == null) { 
            holder = new ViewHolder();  
            switch (type) {
                case 1:
                convertView = vi.inflate(R.layout.group,  null); 
                holder.menuItem = (TextView) convertView.findViewById(R.id.tvGroup);
                convertView.setBackgroundColor(Color.RED); 
                break;              

                case 2:
                convertView = vi.inflate(R.layout.item,  null); 
                holder.menuItem = (TextView) convertView.findViewById(R.id.tvItem); 
                break; 
            }  
            convertView.setTag(holder); 
    } else {
        holder = (ViewHolder) convertView.getTag();  
    }    

    switch (type) {
    case 1:         
    holder.menuItem.setText(menuItemList.get(position).getItemName()) ; 
        convertView.setBackgroundColor(Color.RED); 
    break;              
    case 2:
          holder.menuItem.setText(menuItemList.get(position).getItemName()) ;  
    break; 
        }
        return convertView; 
    }
} 

Solution

  • Now based on the menu type, if the menu type is "menugroup" i need to draw using a different layout and set the background to RED colour.

    You need to override getItemViewType() and getViewTypeCount() to display more than one type of layout, otherwise you fight the Adapter's recycler...


    It looks as though you have done most of the work, but let's alter some of your code:

    public int getItemViewType(int position) {
        if (menuItemList.get(position).getMenuType().equals("menugroup")) 
            return 0;
        return 1;
    }
    
    public int getViewTypeCount() {
        return 2;
    }
    

    Then use getView() like this:

    public View getView(final int position, View convertView, ViewGroup parent) {      
        ViewHolder holder;    
        if (convertView == null) { 
            holder = new ViewHolder();  
            switch (getItemViewType(position)) {
            case 0:
                convertView = vi.inflate(R.layout.group,  null); 
                holder.menuItem = (TextView) convertView.findViewById(R.id.tvGroup);
                convertView.setBackgroundColor(Color.RED); 
                break;              
            case 1:
                convertView = vi.inflate(R.layout.item,  null); 
                holder.menuItem = (TextView) convertView.findViewById(R.id.tvItem); 
                break; 
            }  
            convertView.setTag(holder); 
        } else {
            holder = (ViewHolder) convertView.getTag();  
        }    
    
        holder.menuItem.setText(menuItemList.get(position).getItemName()); 
    
        return convertView; 
    } 
    

    how can i ignore clicks on the menuGroups row?

    In a very similar way, you need to override two more methods areAllItemsEnabled() and isEnabled(int). Since the enabled items are simply a particular item type from above the code looks also identical.

    public boolean areAllItemsEnabled() {
        return false;
    }
    
    public boolean isEnabled(int position) {
        return menuItemList.get(position).getMenuType().equals("menugroup"); 
    }