Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Assign LiveData<> to ListView

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" />

like image 674
bodovix Avatar asked Sep 14 '25 01:09

bodovix


1 Answers

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();
}
like image 81
Almyk Avatar answered Sep 16 '25 16:09

Almyk