ListView not showing up in activity when using custom CursorAdapter

105 Views Asked by At

I was practising SQLiteDatabases . I made two activities MainActivity and EditorActivity. I used a list view with a custom adapter extending cursor adapter to display data in the MainActivity. Insertion into the database is successful but the list view is not showing up in the MainActivity. Please help me with this. Code below

MainActivity class

public class MainActivity extends AppCompatActivity {

Toolbar toolbar;
ImageButton FAB;
ListView listView;
CustomAdapter adapter;

DatabaseHelper mDbHelper;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    listView = (ListView) findViewById(R.id.list_view);

    FAB = (ImageButton) findViewById(R.id.imageButton);
    FAB.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            startActivity(new Intent(MainActivity.this , EditorActivity.class));
        }
    });
}

@Override
protected void onStart() {
    super.onStart();
    mDbHelper = new DatabaseHelper(getBaseContext());
    SQLiteDatabase db = mDbHelper.getReadableDatabase();
    Cursor c;

    c = db.query(
            DatabaseContract.TABLE_NAME,
            null,
            null,
            null,
            null,
            null,
            null
    );

    adapter = new CustomAdapter(MainActivity.this , c , false);

    listView.setAdapter(adapter);

    c.close();


}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}}

Editor Activity Class

    public class EditorActivity extends AppCompatActivity {

Toolbar toolbar;
EditText edtName, edtAge , edtMarks;
Button submit;
DatabaseHelper dbHelper;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_editor);

    toolbar = (Toolbar) findViewById(R.id.toolbar_editor);
    setSupportActionBar(toolbar);
    toolbar.setTitle("Editor");

    edtName = (EditText) findViewById(R.id.edt_name);
    edtAge = (EditText) findViewById(R.id.edt_age);
    edtMarks = (EditText) findViewById(R.id.edt_marks);

    submit = (Button) findViewById(R.id.btn_submit);

    submit.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            String name = edtName.getText().toString();
            int age = Integer.parseInt(edtAge.getText().toString());
            int marks = Integer.parseInt(edtMarks.getText().toString());

            dbHelper = new DatabaseHelper(getBaseContext());
            SQLiteDatabase db = dbHelper.getWritableDatabase();

            ContentValues values = new ContentValues();
            values.put(DatabaseContract.COLUMN_NAME , name);
            values.put(DatabaseContract.COLUMN_AGE , age);
            values.put(DatabaseContract.COLUMN_MARKS , marks);

            long rowId = db.insert(
                    DatabaseContract.TABLE_NAME,
                    null,
                    values
            );

            if (rowId == -1) {
                Toast.makeText(EditorActivity.this ,"Error inserting row"+rowId , Toast.LENGTH_SHORT).show();
            }else
            {
                Toast.makeText(EditorActivity.this ,"Succesfully inserted students data", Toast.LENGTH_SHORT).show();
                finish();

            }


        }
    });


}}

Custom adapter

public class CustomAdapter extends CursorAdapter {

public CustomAdapter(Context context, Cursor c, boolean autoRequery) {
    super(context, c, autoRequery);
}

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
    return LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
}

@Override
public void bindView(View view, Context context, Cursor c) {

    TextView nameTv = (TextView) view.findViewById(R.id.list_name);
    TextView marksTv = (TextView) view.findViewById(R.id.list_marks);

    String nameString = c.getString(c.getColumnIndex(DatabaseContract.COLUMN_NAME));
    int marks = c.getInt(c.getColumnIndex(DatabaseContract.COLUMN_MARKS));

    nameTv.setText(nameString);
    marksTv.setText(String.valueOf(marks));

}}

activity_main xml code

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<include
    android:id="@+id/toolbar"
    layout="@layout/tool_bar" />

    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/toolbar"
        ></ListView>
        <ImageButton
        android:layout_margin="15dp"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:src="@drawable/ic_add_black_36dp"
        android:background="@drawable/circle"
        android:id="@+id/imageButton"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        />
        </RelativeLayout>

The list view is not showing up. the activity is starting , but it appears as if there is no list view even though the values are being updated to the sqlite database. Please help me Thank you.

1

There are 1 best solutions below

1
On

If you see your code, you are creating a Cursor, assign it to an adapter and listview, and then closing the cursor. If you close cursor, you will release all resources and information in cursor:

https://developer.android.com/reference/android/database/Cursor.html#close()

You must create a list/array with cursor information, set adapter with this information and everytime you come from EditorActivity (onResume method of Main Activity) update info in this array and notify Adapter about changes:

@Override
protected void onResume() {
    super.onResume();
    mDbHelper = new DatabaseHelper(getBaseContext());
    SQLiteDatabase db = mDbHelper.getReadableDatabase();
    Cursor c;

    c = db.query(
            DatabaseContract.TABLE_NAME,
            null,
            null,
            null,
            null,
            null,
            null
    );
    // This is pseudo-code, maybe methods are not correct.
    List<DataFromDB> list = new ArrayList<DataFromDB>();
    while(cursor.hasNext()){
      DataFromDB obj ;
      // create your obj with data from cursor
      list.add(obj);
    }
    // end pseudo-code
    c.close();

    adapter = new CustomAdapter(MainActivity.this , list , false);

    listView.setAdapter(adapter);

}

You must change your Adapter class to adapt to this code. If need help, please tell us.