0

I have an app which uses a Listview to display Lectures. The Lectures are colour coded according to their type. I used a custom adapter to control the different colours of each lecture. I call the adapter using the code below -

    cursor = myDbHelper.getReadableDatabase().rawQuery(sql, null);       
    startManagingCursor(cursor);
    adapter = new Lectures_Adapter(this,R.layout.menu_item,cursor,FROM,TO);        
    menuList.setAdapter(adapter);

This all works ok until I re-order the Lectures, say by Location. The code I use is -

    Cursor newCursor = myDbHelper.getReadableDatabase().rawQuery(sqlStr, null);
    adapter.changeCursor(newCursor);

The code in my custom adapter (Lectures_Adapter) is below but is not called when the Lectures are re-ordered.

     public class Lectures_Adapter extends SimpleCursorAdapter {
         private Context appContext;
         private int layout;
         private Cursor mycursor;

         public Lectures_Adapter(Context context, int layout, Cursor c, String[] from,int[] to) {
              super(context, layout, c, from, to);
              this.appContext=context;
              this.layout=layout;
              this.mycursor=c;               
         }

         @Override
         public View getView(int position, View convertView, ViewGroup parent)     
         {   
              View view = super.getView(position, convertView, parent);   
              try {             
                 if (position > 0)
                 {               
                    RelativeLayout rowFill = (RelativeLayout) convertView.findViewById(R.id.rowFill);
                    String title = mycursor.getString(1);                
                    int myColor = 0;
                    int myPos = title.indexOf("Nursing");
                    int myPos2 = title.indexOf("Masterclass");
                    if (myPos >= 0)
                    {
                        myColor = Color.parseColor("#99FF66");
                    }
                    else if (myPos2  >= 0)
                    {
                        myColor = Color.parseColor("#FF99FF");
                    }
                    else
                    {
                        myColor = Color.parseColor("#FFFF66");
                    }
                    convertView.findViewById(R.id.rowFill).setBackgroundColor(myColor);                 
                  }         
               }catch(Exception e) {

               }

              if (convertView == null) {
                  LayoutInflater inflator = (LayoutInflater) this.appContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                  convertView = inflator.inflate(this.layout,null);
              } else {
                  convertView = (View) convertView;
              }
              return view;  
          }

       }

Can somebody please tell me how I can re-order my Listview dynamically and call me custom adapter each time.

user616076
  • 3,907
  • 8
  • 38
  • 64
  • How you are doing re-ordering? Is it by some click or ? – kosa Mar 02 '12 at 16:35
  • I have a dialog box which gives the user an option of 4 ways of ordering the data. Once they make their selection I pass a new query to the code above, (sql in cursor = myDbHelper.getReadableDatabase().rawQuery(sql, null);) – user616076 Mar 05 '12 at 08:47

3 Answers3

1

The problem is that your code in getView() gets its data from the class variable mycursor, but when you call changeCursor, the mycursor variable is not getting updated, so you still see the original list. Rather than using mycursor, you should call getCursor() instead.

superfell
  • 18,780
  • 4
  • 59
  • 81
  • I changed the code adapter.changeCursor(newCursor); to adapter.getCursor(); but the code in getView never gets used. Should I have done anything else? – user616076 Mar 05 '12 at 08:37
  • You need to change the code in the getView func to call getCursor(), not replace the call to changeCursor – superfell Mar 06 '12 at 04:42
  • Thank you that works great now. There is another small problem. On the first page only, the first row is coloured the rest are not, except when you scroll down and then scroll back, then all rows are coloured. When I step through using debug, the rows are assigned a colour but it doesn't seem to apply when the screen is first displayed. – user616076 Mar 06 '12 at 09:07
  • I've gone through it again and on the initial screen build it passes through getView ok but then it passes through a second time and this time convertView is null, which would explain why the remaining rows are blank. If you scroll down and come back it works ok, it's just on the initial build. How can I stop it doing this? – user616076 Mar 06 '12 at 09:28
  • in the getView, the lines that set rowFill and the line that sets the background color should be operating on view not convertView. – superfell Mar 06 '12 at 15:44
0

Have you tried calling adapter.notifyDataSetChanged() after you call the changeCursor? That should force your menuList to be updated.

Calvin
  • 450
  • 2
  • 10
  • Thanks for you reply. I tried adding the code you suggested like so - adapter.changeCursor(newCursor); adapter.notifyDataSetChanged(); but although it now runs through getView, I get an error 'staledataexception - access closed cursor' – user616076 Mar 05 '12 at 09:01
0

Instead of using getView, you may want to use newView and bindView methods instead...here's an example from some code I've written.

private static class ViewHolder {
    HistoryRowView rowvw;
}

class ReportHistoryAdapter extends CursorAdapter {
    ViewHolder _holder;

    private static final String INFLATER_SVC = Context.LAYOUT_INFLATER_SERVICE;
    private LayoutInflater _inflater;

    public PostureReportAdapter( Context context, Cursor cursor ) {
        super( context, cursor );
        _inflater = (LayoutInflater) context.getSystemService(INFLATER_SVC);

    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        View vw = _inflater.inflate( R.layout.reports_history_view, null );
        _holder = new ViewHolder();
        _holder.rowvw = (HistoryRowView)vw.findViewById( R.id.rhv_history_row_vw );
        vw.setTag( _holder );
        return vw;
    }

    @Override
    public void bindView(View vw, Context context, Cursor cursor) {
        _holder = (ViewHolder)vw.getTag();

        int poor = cursor.getInt( 0 );
        int fair = cursor.getInt( 1 );
        int good = cursor.getInt( 2 );
        int date = cursor.getInt( 3 );

        _holder.rowvw.setData( poor, fair, good, date );
    }
}
mmaitlen
  • 824
  • 9
  • 17