Search code examples
javaandroidandroid-layoutandroid-cursoradapter

How to use a spinner with custom layouts using a cursor adapter?


My objective is to convert a working spinner (populated via a cursor adapter) to have alternating backgrounds. Similar to :-

enter image description here

Currently I have this, where everything works fine :-

enter image description here

This is the relevant working code within the cursor adpater (i.e. with the plain dropdowns) :-

@Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {

        return LayoutInflater.from(context).inflate(R.layout.activity_aisle_shop_list_selector, parent, false);
    }
    @Override
    public void bindView(View view,Context context, Cursor cursor) {
        determineViewBeingProcessed(view,"BindV",-1);

        TextView shopname = (TextView) view.findViewById(R.id.aaslstv01);
        shopname.setText(cursor.getString(shops_shopname_offset));

    }

I have tried adding an override of the getDropDownView (code as below). I get the alternating row colors as I want but the dropdown views are blank. However, if I click outside of the selector, then they get populated with data (hence how I managed to get the screen shot, shown above, of what I want). Selection sets the correct Item.

If I remove the return after inflating the layout, then the dropdown views are populated but with data from other rows (however,selection selects the correct item)

public View getDropDownView(int position, View convertview, ViewGroup parent) {
        View v = convertview;
        determineViewBeingProcessed(v,"GetDDV",position);
        if( v == null) {
            v = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_aisle_shop_list_entry, parent, false);
            return v;
        }
        Context context = v.getContext();

        TextView shopname = (TextView) v.findViewById(R.id.aasletv01);

        shopname.setText(getCursor().getString(shops_shopname_offset));

        if(position % 2 == 0) {
            v.setBackgroundColor(ContextCompat.getColor(context,R.color.colorlistviewroweven));
        } else {
            v.setBackgroundColor(ContextCompat.getColor(context,R.color.colorlistviewrowodd));
        }
        return v;
    }

Solution

  • The clues were they I just didn't think hard enough. The issue is with the cursor being in the wrong position because the cursor needs to be obtained via getCursor().

    Additionally, the return after the inflate, is premature (this has been commented out).

    Adding getCursor().moveToPosition(position); before accessing data from the cursor resolves the problem.

    Alternately (perhaps more correctly, comments appreciated on whether or not one method is more correct than the other). Adding:-

        Cursor cursor = getCursor();
        cursor.moveToPosition(position);
    

    and then replacing subsequent getCursor() with cursor (not mandatory) also works.

    So the final code for getDropDownView method could be:-

    public View getDropDownView(int position, View convertview, ViewGroup parent) {
            View v = convertview;
            determineViewBeingProcessed(v,"GetDDV",position);
            if( v == null) {
                v = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_aisle_shop_list_entry, parent, false);
                //return v;
            }
            Context context = v.getContext();
            Cursor cursor = getCursor();
            cursor.moveToPosition(position);
    
    
            TextView shopname = (TextView) v.findViewById(R.id.aasletv01);
    
            shopname.setText(cursor.getString(shops_shopname_offset));
    
            if(position % 2 == 0) {
                v.setBackgroundColor(ContextCompat.getColor(context,R.color.colorlistviewroweven));
            } else {
                v.setBackgroundColor(ContextCompat.getColor(context,R.color.colorlistviewrowodd));
            }
            return v;
        }