I have a list view to display Users and an Adapter that works well together on normal ArrayLists of Users However i'm trying to implement ViewModels and cannot get my ListView adapter to work with LiveData. I cant get any of the similar questions/answers to work for me. But this feels fairly fundamental and like it should be easy.
public class MainActivity extends AppCompatActivity {
MainActivityViewModel mainActivityViewModel;
ListView usersLV;
UsersAdapter userAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainActivityViewModel = ViewModelProviders.of(this).get(MainActivityViewModel.class);
usersLV = findViewById(R.id.usersLV);
ArrayList<User> users = (ArrayList<User>)mainActivityViewModel.getUsers().getValue();
if (users != null){
userAdapter = new UsersAdapter(this,users);
usersLV.setAdapter(userAdapter);
}else{
Log.d("gwyd","user list was null");
userAdapter = new UsersAdapter(this,new ArrayList<User>());
usersLV.setAdapter(userAdapter);
}
mainActivityViewModel.getUsers().observe(this, new Observer<List<User>>() {
@Override
public void onChanged(@Nullable List<User> users) {
if(users != null) {
userAdapter.setUsers(users);
}else {
Log.d("gwyd","no users found in db");
userAdapter.setUsers(new ArrayList<User>());
}
}
});
}}
ViewModel:
public class MainActivityViewModel extends AndroidViewModel {
private DaoRepository daoRepository;
private LiveData<List<User>> users;
public LiveData<List<User>> getUsers() {
if (users == null){
updateUsersList();
}
return users;
}
public MainActivityViewModel(@NonNull Application application) {
super(application);
daoRepository = new DaoRepository(application);
users = updateUsersList();
}
public LiveData<List<User>> updateUsersList(){
return daoRepository.getAllUsers();
}}
and UserAdapter:
public class UsersAdapter extends ArrayAdapter<User> {
private List<User> users;
public void setUsers(List<User> users) {
this.users = users;
notifyDataSetChanged();
}
public UsersAdapter(Context context, List<User> users) {
super(context, 0, users);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
User user = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.user_list_item, parent, false);
}
// Lookup view for data population
TextView tvName = (TextView) convertView.findViewById(R.id.userLvItemTV);
// Populate the data into the template view using the data object
tvName.setText(user.getUserName());
// Return the completed view to render on screen
return convertView;
}}
And the List_item Layout file
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/userLvItemTV"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Change:
mainActivityViewModel.getUsers().observe(this, new Observer<List<User>>() {
@Override
public void onChanged(@Nullable List<User> users) {
playerAdapter.notifyDataSetChanged();
}
});
To:
mainActivityViewModel.getUsers().observe(this, new Observer<List<User>>() {
@Override
public void onChanged(@Nullable List<User> users) {
playerAdapter.setUsers(users);
}
});
And in your adapter create a setter such as:
public void setUsers(List<User> users) {
this.users = users;
notifyDataSetChanged();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With