8

I have populated recyclerview from sqlite .when clicking each row ,row will delete from sqlite but recyclerview not showing updated list after delete. Recycler view show updated list only after launching activity once again. My question is how to update the recycler view soon after deleting an item from the recylcerview without refresh.

following are my code

SecondActivity.java

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;

import java.util.ArrayList;
import java.util.List;

public class SecondActivity extends AppCompatActivity {
    DatabaseHelpher helpher;
    List<DatabaseModel> dbList;
RecyclerView mRecyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);


        helpher = new DatabaseHelpher(this);
        dbList= new ArrayList<DatabaseModel>();
        dbList = helpher.getDataFromDB();


        mRecyclerView = (RecyclerView)findViewById(R.id.recycleview);

        mRecyclerView.setHasFixedSize(true);

        // use a linear layout manager
        mLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mLayoutManager);

        // specify an adapter (see also next example)
        mAdapter = new RecyclerAdapter(this,dbList);
        mRecyclerView.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged ();
    }

    @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_second, menu);
        return true;
    }



    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                finish();
                return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

DatabaseHelpher.java

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class DatabaseHelpher extends SQLiteOpenHelper {
    private static final String DATABASE_NAME="student";
    private static final int DATABASE_VERSION = 1;
    private static final String STUDENT_TABLE = "stureg";
    private static final String STU_TABLE = "create table "+STUDENT_TABLE +"(name TEXT,email TEXT primary key,roll TEXT,address TEXT,branch TEXT)";

Context context;

    public DatabaseHelpher(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        this.context = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        db.execSQL(STU_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        db.execSQL("DROP TABLE IF EXISTS " + STUDENT_TABLE);

        // Create tables again
        onCreate(db);
    }
/* Insert into database*/
    public void insertIntoDB(String name,String email,String roll,String address,String branch){
        Log.d("insert", "before insert");

        // 1. get reference to writable DB
        SQLiteDatabase db = this.getWritableDatabase();

        // 2. create ContentValues to add key "column"/value
        ContentValues values = new ContentValues();
        values.put("name", name);
        values.put("email", email);
        values.put("roll", roll);
         values.put("address", address);
        values.put("branch", branch);

        // 3. insert
        db.insert(STUDENT_TABLE, null, values);
        // 4. close
        db.close();
        Toast.makeText(context, "insert value", Toast.LENGTH_LONG);
        Log.i("insert into DB", "After insert");
    }
/* Retrive  data from database */
    public List<DatabaseModel> getDataFromDB(){
        List<DatabaseModel> modelList = new ArrayList<DatabaseModel>();
        String query = "select * from "+STUDENT_TABLE;

        SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query,null);

        if (cursor.moveToFirst()){
            do {
                DatabaseModel model = new DatabaseModel();
                model.setName(cursor.getString(0));
                model.setEmail(cursor.getString(1));
                model.setRoll(cursor.getString(2));
                model.setAddress(cursor.getString(3));
                model.setBranch(cursor.getString(4));

                modelList.add(model);
            }while (cursor.moveToNext());
        }


        Log.d("student data", modelList.toString());


        return modelList;
    }


    /*delete a row from database*/

    public void deleteARow(String email){
        SQLiteDatabase db= this.getWritableDatabase();
        db.delete(STUDENT_TABLE, "email" + " = ?", new String[] { email });
        db.close();
    }

}

DatabaseModel.java

public class DatabaseModel {
    private String name;
    private String roll;
    private String address;
    private String branch;
    private String email;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getRoll() {
        return roll;
    }

    public void setRoll(String roll) {
        this.roll = roll;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getBranch() {
        return branch;
    }

    public void setBranch(String branch) {
        this.branch = branch;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

RecyclerAdapter.java

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;


public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {

  static   List<DatabaseModel> dbList;
    static  Context context;

    static DatabaseHelper dh;
    RecyclerAdapter(Context context, List<DatabaseModel> dbList ){
        this.dbList = new ArrayList<DatabaseModel>();
        this.context = context;
        this.dbList = dbList;
dh=new DatabaseHelper(context);
    }

    @Override
    public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(
                R.layout.item_row, null);

        // create ViewHolder

        ViewHolder viewHolder = new ViewHolder(itemLayoutView);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(RecyclerAdapter.ViewHolder holder, int position) {

        holder.name.setText(dbList.get(position).getName());
        holder.email.setText(dbList.get(position).getEmail());

    }

    @Override
    public int getItemCount() {
        return dbList.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        public TextView name,email;

        public ViewHolder(View itemLayoutView) {
            super(itemLayoutView);
            name = (TextView) itemLayoutView
                    .findViewById(R.id.rvname);
            email = (TextView)itemLayoutView.findViewById(R.id.rvemail);
            itemLayoutView.setOnClickListener(this);

        }

        @Override
        public void onClick(View v) {
           dh.delete(dbList.get(getAdapterPosition()).getEmail);


            Toast.makeText(RecyclerAdapter.context, "you have clicked Row " + getAdapterPosition(), Toast.LENGTH_LONG).show();
        }
    }
}

i have tried to update recyclerview using mAdapter.notifyDataSetChanged (); but it doesn't working for me.please sugget me.Thank you

iCoders
  • 6,929
  • 5
  • 34
  • 54

10 Answers10

11

Remove data from both from your arraylist and from database and than notify your list will update.

or

Delete data from database and after delete get data from database and reload your arraylist with new data will do your work

dbList.remove(getAdapterPosition());
notifyDataSetChanged();
//or use this for better perfomance.
notifyItemRemoved(getAdapterPosition());

Pass position in remove method

Njeru Cyrus
  • 1,359
  • 18
  • 22
J.D.
  • 1,364
  • 1
  • 11
  • 20
5

You just need to notify adapter that one item is removed, inside onClick method

@Override
public void onClick(View v) {
    notifyItemRemoved(this.getLayoutPosition());
}
M.Usman
  • 1,691
  • 17
  • 22
4

You are deleting data from DB but not from list in which you have fetch all data so untill you delete data from list, it will show you even if it is deleted. So you need to change your delete method and also need to remove data from list also.

Check below updated method of deletion.

      @Override
      public void onClick(View v) {
            dh.delete(dbList.get(getAdapterPosition()).getEmail);

            // These two lines added for remove data from adapter also.
            dbList.remove(getAdapterPosition());
            notifyDataSetChanged();


            Toast.makeText(RecyclerAdapter.context, "you have clicked Row " + getAdapterPosition(), Toast.LENGTH_LONG).show();
    }
Vickyexpert
  • 3,066
  • 4
  • 17
  • 34
  • @Vickyexpert.Thanks for the answer. i will try. suppose if am doing update to sqlite instead of delete then which method i have to use ? – iCoders May 20 '16 at 06:41
  • You can do two things for that first one if either take your adapter in same activtiy class so you can edit list and then set it in adapter, or second thing for editing on click call another activity and pass position in argument and then on next activity get particular data using that position allow user to edit and on click of update button edit data and call back this main activity so it will directly show you updated list. – Vickyexpert May 20 '16 at 06:46
  • 1
    @vision the point is your RecyclerView doesn't display what's in the database directly, it shows what's in the List. If you change something in the database but not in the List, then the display will not change. Whatever changes you make in the database, you either need to also make appropriate changes to the List, or you need to query the database again for a new List. – Karakuri May 20 '16 at 06:49
3

Try reloading the info.

Change this

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            finish();
            return true;
    }
    return super.onOptionsItemSelected(item);
}

To this:

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    dbList = helpher.getDataFromDB();
    mAdapter = new RecyclerAdapter(this,dbList);
    mRecyclerView.setAdapter(mAdapter);
    mAdapter.notifyDataSetChanged ();

    switch (item.getItemId()) {
        case android.R.id.home:
            finish();
            return true;
    }
    return super.onOptionsItemSelected(item);
}

That will reload the information at your Recycler Vuew with every click.

  • lol bro u sure what you have told.... on which item's click this code will get fired? it will not at all... – mfaisalhyder Jun 02 '16 at 05:30
  • Thanks Ruben. U just given an idea. Now in my code i just display the recyclerview data twice. One is from outside button click and another one is inside button click. so the values will dynamically changed after inserting new values and it is reacts in my view – sudharsan chandrasekaran Oct 06 '16 at 06:00
2

//Define an interface in the Adapter class

private static ItemClickListener itemClickListener;

public interface ItemClickListener {
    void onItemClick(int position, View v);
}

and a method

public void setOnItemClickListener(ItemClickListener myClickListener) {
    RecyclerAdapter.itemClickListener = myClickListener;
}

in onClick method of viewHolder

 @Override
    public void onClick(View v) {
       dh.delete(dbList.remove(getAdapterPosition()).getEmail);
       itemClickListener.onItemClick(getLayoutPosition(), v);

        Toast.makeText(RecyclerAdapter.context, "you have clicked Row " + getAdapterPosition(), Toast.LENGTH_LONG).show();
    }

In your Activity's onCreate() or onResume() method

 mAdapter.setOnItemClickListener(new RecyclerAdapter.ItemClickListener() {
        @Override
        public void onItemClick(int position, View v) {
            mAdapter.notifyDataSetChanged();
        }
    });
Amit
  • 2,562
  • 1
  • 23
  • 35
2

You can call recreate() after performing the delete operation in your activity so you can refresh the activity. it works for me. Hope this will work you as well.

2

There is a completely different approach to update recyclerview when data is changed in sqlite. This is through the use of cursor.

You may like to see this video : https://www.youtube.com/playlist?list=PLrnPJCHvNZuBMJmll0xy2L2McYInT3aiu

The code is available at : https://codinginflow.com/tutorials/android/sqlite-recyclerview/part-1-layouts-contract-sqliteopenhelper

DragonFire
  • 2,033
  • 1
  • 18
  • 33
1

Remove the list data from arrayList using

 arrayList.remove(position);

And update your Adapter using,

 mAdapter.notifyDataSetChanged ();
Naveen T P
  • 6,105
  • 2
  • 17
  • 26
0

use notifyItemRemoved() instead of notifyDataSetChanged()

Stephen Rauch
  • 40,722
  • 30
  • 82
  • 105
0

Do It like this

  builder.setNeutralButton("Delete", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    PersonDBHelper dbHelper = new PersonDBHelper(mContext);
                    dbHelper.deletePersonRecord(person.getId(), mContext);

                    mPeopleList.remove(position);
                    mRecyclerV.removeViewAt(position);
                    notifyItemRemoved(position);
                    notifyItemRangeChanged(position, mPeopleList.size());
                    notifyDataSetChanged();
                }
            });

and Use On restart method in the recycle list

Usman Ali
  • 682
  • 1
  • 6
  • 25