2

Following is my listview adapter classes using AlphabetIndexer. It does not work when I add unicode chars (for hebrew) togather with the english. I get exception in: getSectionForPosition. getting to index -1.... Tries it with 2 entries in the DB - 1 starting with hebrew char (unicode) and one with english. The first char for AlphabetIndexer was the unicode char. Really really need help in this one....

public abstract class RecipeListViewAdapter extends SimpleCursorAdapter implements SectionIndexer
{
    protected   Context                         mContext;
    protected   Cursor                          mCursor;
    private     LayoutInflater                  mInflater;

    public static final int TYPE_HEADER = 1;
    public static final int TYPE_NORMAL = 0;

    private static final int TYPE_COUNT = 2;

    private AlphabetIndexer indexer;

    private int[] usedSectionNumbers;

    private Map<Integer, Integer> sectionToOffset;
    private Map<Integer, Integer> sectionToPosition;

    protected ImageLoader   mImageLoader        = new ImageLoader( MyApp.Instance() );


    public RecipeListViewAdapter(   Context     context, 
                                    int         layout, 
                                    Cursor      c,
                                    String[]    from, 
                                    int[]       to ) 
    {
        super(context, layout, c, from, to);

        mContext            = context;
        mCursor             = c;
        mInflater           = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        indexer             = new AlphabetIndexer(c, c.getColumnIndexOrThrow("NAME"), "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
        sectionToPosition   = new TreeMap<Integer, Integer>();
        sectionToOffset     = new HashMap<Integer, Integer>();

        final int count = super.getCount();

        int i;
        for( i = count - 1 ; i >= 0; i-- )        
        {
            sectionToPosition.put(indexer.getSectionForPosition(i), i);
        }

        i = 0;
        usedSectionNumbers = new int[sectionToPosition.keySet().size()];

        for( Integer section : sectionToPosition.keySet() )
        {
            sectionToOffset.put(section, i);
            usedSectionNumbers[i] = section;
            i++;
        }

        for(Integer section: sectionToPosition.keySet())
        {
            sectionToPosition.put(section, sectionToPosition.get(section) + sectionToOffset.get(section));
        }
    }

     @Override
     public int getCount() 
     {
         if( super.getCount() != 0 )
         {
             return super.getCount() + usedSectionNumbers.length;
         }

         return 0;
     }

     @Override
     public Object getItem(int position) 
     {
         if (getItemViewType(position) == TYPE_NORMAL) //we define this function later
         {
             return super.getItem( GetItemPosition( position ) );
         }

         return null;
     }

     public int GetItemPosition( final int position )
     {
         return position - sectionToOffset.get(getSectionForPosition(position)) - 1;
     }

     public int getPositionForSection(int section) {
         if (! sectionToOffset.containsKey(section)){
             int i = 0;
             int maxLength = usedSectionNumbers.length;

             while (i < maxLength && section > usedSectionNumbers[i]){
                 i++;
             }
             if (i == maxLength) return getCount();

             return indexer.getPositionForSection(usedSectionNumbers[i]) + sectionToOffset.get(usedSectionNumbers[i]);
         }

         return indexer.getPositionForSection(section) + sectionToOffset.get(section);
     }

     public int getSectionForPosition(int position) {
         int i = 0;     
         int maxLength = usedSectionNumbers.length;

         while (i < maxLength && position >= sectionToPosition.get(usedSectionNumbers[i])){
             i++;
         }
         return usedSectionNumbers[i-1];
     }

     public Object[] getSections() {
         return indexer.getSections();
     }

     //nothing much to this: headers have positions that the sectionIndexer manages.
     @Override
     public int getItemViewType(int position) {
         if (position == getPositionForSection(getSectionForPosition(position))){
             return TYPE_HEADER;
         } return TYPE_NORMAL;
     }

     @Override
     public int getViewTypeCount() {
         return TYPE_COUNT;
     }



    @Override
    public View getView(    int         position, 
                            View        convertView, 
                            ViewGroup   parent ) 
    {
        final int type = getItemViewType(position);
        if (type == TYPE_HEADER)
        {
            if (convertView == null)
            {
                convertView = mInflater.inflate(R.layout.header, parent, false);
            }
            ((TextView)convertView.findViewById(R.id.header)).setText((String)getSections()[getSectionForPosition(position)]);
            return convertView;
        }
        else
        {
            ViewHolder holder = new ViewHolder();

            if (convertView == null) 
            {
                convertView = mInflater.inflate(R.layout.recipes_list_view_entry, null);

                holder.name             = (TextView)  convertView.findViewById( R.id.name_entry );
                holder.author           = (TextView)  convertView.findViewById( R.id.username_entry );
                holder.ratingBar        = (RatingBar) convertView.findViewById( R.id.list_RatingBarId );
                holder.userRatingBar    = (RatingBar) convertView.findViewById( R.id.list_userRatingBarId );
                holder.diffculty        = (ImageView) convertView.findViewById( R.id.list_DifficultyImageViewId );
                holder.preparationTime  = (ImageView) convertView.findViewById( R.id.list_TimeImageViewId );
                holder.recipePic        = new DisplayableImageView( (ImageView) convertView.findViewById( R.id.list_RecipeImageViewId ) );

                holder.name.setTypeface(  MyApp.Fonts.ARIAL );
                holder.name.setTextSize(  MyApp.Fonts.RUNNING_TEXT_SIZE );
                holder.name.setTextColor( Color.BLACK );
            }
            else
            {
                holder = (ViewHolder) convertView.getTag();
            }

            if( super.getItem( GetItemPosition(position) ) != null )
            {
                // Check if single
                if( getCount() == position+1 && position == 1 )
                {
                    convertView.setBackgroundResource( R.drawable.list_single );
                }
                else if( getItemViewType(position-1) == TYPE_HEADER )
                {
                    // Check if single item in the middle of the list
                    if( getItemViewType(position+1) == TYPE_HEADER )
                    {
                        convertView.setBackgroundResource( R.drawable.list_single );
                    }
                    else if( position == getCount() - 1 )
                    {
                        convertView.setBackgroundResource( R.drawable.list_single );
                    }
                    else
                    {
                        convertView.setBackgroundResource( R.drawable.list_up );
                    }
                }
                else
                {
                    // Middle or bottom
                    convertView.setBackgroundResource( R.drawable.list_middle );
                    //If not last
                    if( getCount() != position + 1 )
                    {
                        // Check if middle or down
                        if( getItemViewType(position+1) == TYPE_HEADER )
                        {
                            convertView.setBackgroundResource( R.drawable.list_down );
                        }
                        else
                        {
                            convertView.setBackgroundResource( R.drawable.list_middle );
                        }
                    }
                    else
                    {
                        // If it is last - use list_down
                        convertView.setBackgroundResource( R.drawable.list_down );
                    }

                }

                FillRecipeDataToHolder( GetItemPosition(position), holder );

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

            return convertView;
        }
    }

    //these two methods just disable the headers
    @Override
    public boolean areAllItemsEnabled() {
        return false;
    }

    @Override
    public boolean isEnabled(int position) {
        if (getItemViewType(position) == TYPE_HEADER){
            return false;
        }
        return true;
    }


    protected abstract void FillRecipeDataToHolder(int position, ViewHolder holder);

    static class ViewHolder 
    {
        TextView                separator;
        DisplayableImageView    recipePic;
        TextView                name;
        TextView                author;
        RatingBar               ratingBar;
        RatingBar               userRatingBar;
        ImageView               diffculty;
        ImageView               preparationTime;
        TextView                serveCount;
    }
}
user1136875
  • 613
  • 1
  • 9
  • 22
  • 1
    I am doing something similiar HERE http://stackoverflow.com/questions/10224233/alphabetindexer-with-custom-adapter-managed-by-loadermanager – Etienne Lawlor Apr 25 '12 at 06:15

0 Answers0