Zero_LL Zero_LL - 3 months ago 28
Android Question

Android Studio populate Database to RecyclerVIew

I am trying to populate database to RecyclerVIew, before I had ListView and everything was working perfectly now when I run my app it displays nothing .

This is my first time using a recyclerview so I am new to the whole concept,
I thought listview and recyclerview were little different on the view only,
anyways I am stuck and I'd grateful for some help

here are my classes

MainActivity

public class MainActivity extends AppCompatActivity {
private ArrayList<Word> mwordlist;
private WordAdapter adapter;
private RecyclerView recyclerView;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);

adapter = new WordAdapter(getApplicationContext(),mwordlist);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());


recyclerView.setAdapter(adapter);

DatabaseAccess databaseAccess = DatabaseAccess.getInstance(this);

databaseAccess.open();

mwordlist = databaseAccess.getWords(mwordlist);


adapter.notifyDataSetChanged();

FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}

@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);
}


}

WordAdapter

public class WordAdapter extends RecyclerView.Adapter<MyViewHolder> {
Context context;
ArrayList<Word> mWordlist;

public WordAdapter(Context context, ArrayList<Word> mWordlist) {
this.context = context;
this.mWordlist = mWordlist;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.word_listview,null);
MyViewHolder holder = new MyViewHolder(view);

return holder;
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {

holder.tword.setText(mWordlist.get(position).getmWord());
holder.tkalmad.setText(mWordlist.get(position).getmKalmad());
}

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


DatabaseAcces

public class DatabaseAccess {

private SQLiteOpenHelper openHelper;
private SQLiteDatabase database;
private static DatabaseAccess instance;

/**
* Private constructor to avoid object creation from outside classes.
*
* @param context
*/
private DatabaseAccess(Context context) {
this.openHelper = new DatabaseOpenHelper(context);
}

/**
* Return a singleton instance of DatabaseAccess.
*
* @param context the Context
* @return the instance of DabaseAccess
*/
public static DatabaseAccess getInstance(Context context) {
if (instance == null) {
instance = new DatabaseAccess(context);
}
return instance;
}

/**
* Open the database connection.
*/
public void open() {
this.database = openHelper.getWritableDatabase();
}

/**
* Close the database connection.
*/
public void close() {
if (database != null) {
this.database.close();
}
}


public ArrayList<Word> getWords(ArrayList<Word> WordList) {
Word word = null;
Cursor cursor = database.rawQuery("SELECT * FROM dictionary", null);
cursor.moveToFirst();
WordList.clear();
while (!cursor.isAfterLast()) {
word = new Word(cursor.getString(1),cursor.getString(2));
WordList.add(word);
cursor.moveToNext();
}
cursor.close();

return WordList;
}
}


....
i tried many solutions but i couldn't get right

The New logcat

08-21 22:42:47.903 20536-20536/com.example.zer0_ll.somalimeddictionary D/ContextImpl: ContextImpl running for user UserHandle{0} 0
08-21 22:42:47.903 20536-20536/com.example.zer0_ll.somalimeddictionary W/ResourcesManager: getTopLevelResources: null for user 0
08-21 22:42:47.913 20536-20536/com.example.zer0_ll.somalimeddictionary W/ResourcesManager: getTopLevelResources: null for user 0
08-21 22:42:47.913 20536-20536/com.example.zer0_ll.somalimeddictionary D/DisplayManager: DisplayManager()
08-21 22:42:48.294 20536-20543/com.example.zer0_ll.somalimeddictionary W/art: Suspending all threads took: 43.579ms
08-21 22:42:48.304 20536-20536/com.example.zer0_ll.somalimeddictionary D/PhoneWindow: *FMB* installDecor mIsFloating : false
08-21 22:42:48.304 20536-20536/com.example.zer0_ll.somalimeddictionary D/PhoneWindow: *FMB* installDecor flags : -2139029248
08-21 22:42:48.434 20536-20536/com.example.zer0_ll.somalimeddictionary W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(andro id.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
08-21 22:42:48.764 20536-20543/com.example.zer0_ll.somalimeddictionary W/art: Suspending all threads took: 11.779ms
08-21 22:42:48.924 20536-20536/com.example.zer0_ll.somalimeddictionary I/SQLiteAssetHelper: successfully opened database Database.db
08-21 22:42:48.924 20536-20536/com.example.zer0_ll.somalimeddictionary D/AndroidRuntime: Shutting down VM
08-21 22:42:48.924 20536-20536/com.example.zer0_ll.somalimeddictionary E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.zer0_ll.somalimeddictionary, PID: 20536
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.zer0_ll.somalimeddictionary/com.example.zer0_ll.somalimeddictionary.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void java.util.ArrayList.clear()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2695)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2769)
at android.app.ActivityThread.access$900(ActivityThread.java:177)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1430)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5910)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void java.util.ArrayList.clear()' on a null object reference
at com.example.zer0_ll.somalimeddictionary.DatabaseAccess.getWords(DatabaseAccess.java:62)
at com.example.zer0_ll.somalimeddictionary.MainActivity.onCreate(MainActivity.java:43)
at android.app.Activity.performCreate(Activity.java:6178)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2648)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2769)
at android.app.ActivityThread.access$900(ActivityThread.java:177)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1430)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5910)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)

Answer

In getWords() function inside DatabaseAccess class you are creating new Arraylist (ArrayList<Word> WordList = new ArrayList<>();) and returning this Arraylist so this function returns ArrayList with new memory location but your adapter is depend on mWordlist which is in MainActivity that's why adapter.notifyDataSetChanged(); not working. Try sending reference of mWordlist in MainActivity to getWords() function like getWords(mWordlist) and in getWords() use this ArrayList. Don't allocate new ArrayList. You can clear this ArrayList before adding new data in the ArrayList.

Remove this in getWords() function

 ArrayList<Word> WordList = new ArrayList<>();

Edited:

getWords() function Code:

public ArrayList<Word> getWords(ArrayList<Word> WordList) {
Word word = null;
Cursor cursor = database.rawQuery("SELECT * FROM dictionary", null);
cursor.moveToFirst();
WordList.clear()
while (!cursor.isAfterLast()) {
        word = new Word(cursor.getString(1),cursor.getString(2));
        WordList.add(word);
        cursor.moveToNext();
    }
cursor.close();

return WordList;
}

MainActivity Code

public class MainActivity extends AppCompatActivity {
private ArrayList<Word> mWordlist;
private WordAdapter adapter;
private RecyclerView recyclerView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);

mWordlist = new ArrayList<>()
adapter = new WordAdapter(getApplicationContext(),mWordlist);
RecyclerView.LayoutManager mLayoutManager = new      LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());


recyclerView.setAdapter(adapter);

DatabaseAccess databaseAccess = DatabaseAccess.getInstance(this);

databaseAccess.open();

mWordlist = databaseAccess.getWords(mWordlist);


adapter.notifyDataSetChanged();

FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Snackbar.make(view, "Replace with your own action",    Snackbar.LENGTH_LONG)
                .setAction("Action", null).show();
    }
});
}

@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);
}
Comments