4

Sorry for my bad english and a stupid noob question. I have a SimpleCursorAdapter and a ListView with Buttons on each item (row in database).
I realize deleting row but I don`t know how to refresh the ListView.
I hope that somebody can help me with simple and clear examples

my adapter

public class MySimpleCursorAdapter extends SimpleCursorAdapter {

Context context;

public MySimpleCursorAdapter(Context contxt, int layout, Cursor c, String[] from, int[] to, int flags) {
    super(contxt, layout, c, from, to, flags);
    context=contxt;

}

public View newView(Context _context, Cursor _cursor, ViewGroup parent){
    LayoutInflater inflater = (LayoutInflater) _context.getSystemService(_context.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(R.layout.listform_item, parent, false);
    return view;
}

@Override
public void bindView(View view,  Context Context,  Cursor cursor) {
    String name = cursor.getString(cursor.getColumnIndex(DBHelper.FORM_NAME));
    String title = cursor.getString(cursor.getColumnIndex(DBHelper.FORM_TITLE));
    TextView formname = (TextView)view.findViewById(R.id.tvFormName);
    formname.setText(name);
    TextView formtitle=(TextView)view.findViewById(R.id.tvFormTitle);
    formtitle.setText(title);
    ImageButton yourButton = (ImageButton)view.findViewById(R.id.ibtnDelete);
    yourButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if(view != null) {
                Object obj = view.getTag();
                //if(obj != null && obj instanceof Integer) {
                dbForm form=new dbForm(context);
                form.open();
                String st=obj.toString();
                form.deleteForm(Long.valueOf(st).longValue());
                    Toast.makeText(context, "Delete row with id = " + st, Toast.LENGTH_LONG).show();


            }
        }
    });
    Object obj = cursor.getString(cursor.getColumnIndex(DBHelper.FORM_ID));
    yourButton.setTag(obj);


}
}

I also use a CursorLoader in Main to acces the database

UPD: i use use cursor loader and a dont undertand how call his reset in my custom adapter, hope for help.

public class MainActivity extends FragmentActivity implements LoaderCallbacks<Cursor> {

ListView lvForms;
dbForm table_form;
SimpleCursorAdapter scAdapter;

/**
 * Called when the activity is first created.
 */
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    table_form = new dbForm(this);
    table_form.open();


    String[] from = new String[]{DBHelper.FORM_NAME, DBHelper.FORM_TITLE};
    int[] to = new int[]{R.id.tvFormName, R.id.tvFormTitle};


    scAdapter = new MySimpleCursorAdapter(this, R.layout.listform_item, null, from, to, 0);
    lvForms = (ListView) findViewById(R.id.lvForms);
    lvForms.setAdapter(scAdapter);


    registerForContextMenu(lvForms);


    getSupportLoaderManager().initLoader(0, null, this);
}


public void onButtonClick(View view) {
    Intent intent = new Intent(MainActivity.this, LoginActivity.class);
    startActivity(intent);
}


protected void onDestroy() {
    super.onDestroy();
    table_form.close();
    // закрываем подключение при выходе
}

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle bndl) {
    return new MyCursorLoader(this, table_form);
}

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    scAdapter.swapCursor(cursor);
}

@Override
public void onLoaderReset(Loader<Cursor> loader) {
    scAdapter.swapCursor(null);
}

static class MyCursorLoader extends CursorLoader {

    dbForm table_form;

    public MyCursorLoader(Context context, dbForm table_form) {
        super(context);
        this.table_form = table_form;
    }

    @Override
    public Cursor loadInBackground() {
        Cursor cursor = table_form.getAllData();
        return cursor;
    }

}

}

mechanikos
  • 771
  • 12
  • 32

2 Answers2

4

For a SimpleCursorAdapter it's best to use a CursorLoader like this :

    public Loader<Cursor> onCreateLoader(int id,Bundle arg) {
    return new SimpleCursorLoader(this) {
        public Cursor loadInBackground() {
            // This field reserved to what you want to load in your cursor adater and you return it (for example database query result)
            // return Cursor ;
        }
    };
}

public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    adapter.swapCursor(cursor);    
}

public void onLoaderReset(Loader<Cursor> loader){
    adapter.swapCursor(null);
}

And in your MainActivity or where you will instanciate the adapter, just before add this :

getLoaderManager().initLoader(0x01, null, this);
// declare your new Custom Simple Cursor Adapter here
scAdapter = new MySimpleCursorAdapter ....

And add :

    public void onResume() {
    super.onResume();
    // Restart loader so that it refreshes displayed items according to database
    getLoaderManager().restartLoader(0x01, null, this);
}

I work with loaders this way, I hope it helps you .

Sacredila
  • 121
  • 3
  • Thanks, i think about it but i cant understand how do it with my custom adapter. i update my post with main-code, i hope that you give me advice for my code. – mechanikos Feb 09 '14 at 05:18
  • I updated my answer, check it and tell me if it works . – Sacredila Feb 09 '14 at 12:15
  • yes,it works if i exit my app(now not must cilled process for refresh), but not refresh in realtime. i have just one activity and i dont know how force refresh activity after deleting. – mechanikos Feb 09 '14 at 14:49
  • can you explain more to me ? you have loginActivity too , don't you ? – Sacredila Feb 09 '14 at 14:58
  • yes but login activity not use in this situation, this call after button "login". problem in refresh listview in realtime(in main activity) after deleting item(i have button delete each every item). for this situation i wrote mycursoradapter with handler in bindView for click on deletebutton. i need some way to call refresh mainactivity or just listview after deletig. sorry for my hard speak – mechanikos Feb 09 '14 at 15:25
  • in onClickButton :`.... form.deleteForm(Long.valueOf(st).longValue()); getLoaderManager().restartLoader(0x01, null, this);` – Sacredila Feb 09 '14 at 15:47
  • "cannot resolve method getLoaderManager().restartLoader(0x01, null, this);" – mechanikos Feb 09 '14 at 15:51
  • That's what I thought too because inside statement "this" isn't known. Add a method to your mainActivity class : `public void refreshUI(){ getLoaderManager().restartLoader(0x01, null, this); } ` then `.... form.deleteForm(Long.valueOf(st).longValue()); refreshUI(); ` – Sacredila Feb 09 '14 at 15:53
  • "cannot resolve" too. i think i must create a new oject of mainactivity that use public method refreshUI. i confused, surely i have not access to method in my mainactivity – mechanikos Feb 09 '14 at 16:04
  • you can access it by calling Activity.method() since it's public but you must add static also . – Sacredila Feb 09 '14 at 16:08
  • sorry, can you tell me it with code, im really noob((( – mechanikos Feb 09 '14 at 16:10
  • 1
    put `public class MySimpleCursorAdapter extends SimpleCursorAdapter {.....}` in your mainActivity class, it means as subclass, it will work that way since you're in the mainActivity. This means `public class MainActivity extends FragmentActivity implements LoaderCallbacks {............... private class MySimpleCursorAdapter extends SimpleCursorAdapter {.....}; }` which means in the same java file MainActivity.java – Sacredila Feb 09 '14 at 16:16
  • IT IS WORK!Mother of god, i dont believe that it is simple! Thanks great, you save my brain! i didnt now that i do for you) – mechanikos Feb 09 '14 at 16:30
1

You should reload your cursor and update your cursor adapter:

// Reload your cursor here
Cursor newCursor = ….;

if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD){
    adapter.swapCursor(newCurosr);
} else {
    adapter.changeCursor(newCursor);
}

Then, notify your list view about data changes:

adapter.notifyDataSetChanged();
Aleksey
  • 239
  • 2
  • 4