Achieving a dynamic ScrollView via refreshing (or not) the fragment

203 Views Asked by At

I want to create a UI where there are n amount of LinearLayout's all contained within a vertical ScrollView (each row will contain a couple items).

I also want this ScrollView to update if another fragment updates a value (shared through a ViewModel). Example: The ScrollView initially renders with 4 items, and later on the user changes the value to 5 in another fragment. The Observer will notify our first fragment, and add the 5th layout in.

What's the best way to do this? Do I need to essentially delete the fragment, and force a refresh (with the new number of layouts to render)? Or is there a way to add/remove layouts like this without having to refresh the fragment?

Additional notes to consider:

  • The user can change the value multiple times in a row, so I'm assuming multiple refreshes in a row may slow down the app? In this case, I could always wait until the user is done and swipes back (see bellow) to update the value in fragment 1.

  • The two fragments are also in a tab view, so only one fragment is visible at a time. But the changes would need to be present by the time they swipe into the first tab again.

Fragment 1 (my ideas so far)

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    MyViewModel viewModel = ViewModelProviders.of(Objects.requireNonNull(getActivity())).get(MyViewModel.class);
    n = viewModel.getN().getValue();
    viewModel.getN().observe(this, this::updateN);
}

@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {

    ScrollView scrollView = view.findViewById(R.id.scrollView);

    for (int i = 0; i < n; i++) {
        // For now, just show the index of the layout

        LinearLayout linearLayout = new LinearLayout(this.getContext());
        TextView textView = new TextView(this.getContext());
        textView.setText(String.format("%01d", i);

        linearLayout.setOrientation(LinearLayout.HORIZONTAL);
        linearLayout.addView(textView);
    }
}

private void updateN(int n) {
    this.n = n;

    // TODO: update UI here?
}
1

There are 1 best solutions below

0
On

Thank you to @dotGitignore for the suggestion. He suggested I look into the android widget RecyclerView. This widget can do precicesly what I mean to do above: create a list that responds and updates on changes to a value in another fragment.

To do this (steps from guide linked bellow):

  1. Add RecyclerView support library to the gradle build file

  2. Define a model class to use as the data source. I use a ViewModel class for fragment-to-fragment access. More on ViewModel's here

  3. Add a RecyclerView to your activity to display the items

  4. Create a custom row layout XML file to visualize the item

  5. Create a RecyclerView.Adapter and ViewHolder to render the item

  6. Bind the adapter to the data source to populate the RecyclerView

All of these steps can also be found in the following excellent guide: https://guides.codepath.com/android/using-the-recyclerview