3

I am trying to make An Activity with 4 Chips in a Horizontal Scrolling ChipGroup.

This Activity is using the ChipGroup as a filter for API call, and can have Extras telling which Chip was selected by user.

Currently I'm doing it like :

chipScroll.postDelayed(() -> {
                chipScroll.smoothScrollBy(800, 0);
            },100);

But this is quite a hacky solution to what I want to achieve.

Is there any other way to scroll to selected Chip in a Horizontal Scrolling ChipGroup?

Edit :

I've thought of trying to iteratively get all the Chips in the ChipGroup and match its IDs. But it seems hacky too. Something like spinnerAdapter.getItem(spinner.getSelectedItemPosition) is what I'm aiming for

Kevin Murvie
  • 2,592
  • 1
  • 25
  • 43

3 Answers3

6

I found the answer here.

I forgot that ChipGroup is basically just a ViewGroup, and HorizontalScrollView is just an extra for its scrolling purpose.

I could just do something like :

chipGroup.post(() -> {
    Chip chipByTag = chipGroup.findViewWithTag(filterModel.getComplaint_status());
    chipGroup.check(chipByTag.getId());
    chipScroll.smoothScrollTo(chipByTag.getLeft() - chipByTag.getPaddingLeft(), chipByTag.getTop());
});

Doing this in onCreate would crash as the Tag isn't assigned yet, and I'm using DataBinding for the tag in XML (CMIIW), hence, we should do it in a .post() runnable.

Kevin Murvie
  • 2,592
  • 1
  • 25
  • 43
1

For Kotlin: Using @Kevin Murvie answer

binding.layoutChipChoiceProducts.chipGroupDrinksChoice.post {
        val chip =
            binding.layoutChipChoiceProducts.chipGroupDrinksChoice.findViewWithTag<Chip>(tag)
        binding.layoutChipChoiceProducts.scrollLayoutChip.scrollTo(
            chip.left - chip.paddingLeft, chip.top
        )
    }
Jeremiah Polo
  • 641
  • 5
  • 10
1

You should wrap your ChipGroup with the HorizontalScrollView, and just call this extension function after the chip selection:

inline fun <reified T : View> HorizontalScrollView.scrollToPosition(
    tag: String?,
) {
    val view = findViewWithTag<T>(tag) ?: return
    val leftEdgePx = view.left
    val screenCenterPx = Resources.getSystem().displayMetrics.widthPixels / 2
    val scrollPx = if (leftEdgePx < screenCenterPx) 0
    else leftEdgePx - screenCenterPx + view.width / 2
    this.post {
        this.smoothScrollTo(scrollPx, view.top)
    }
}

This will always show selected chip centered on the screen (if it's possible).