-1

I am trying to achieve a view switch that enables user to switch between "List view" and "Grid view" in Android. However, I have achieved this but I am not satisfied with results since there is a high probability that user will find it annoying.

Please find the code below as well as expected and actual results :

fragment_dashboard.xml :

<com.google.android.material.button.MaterialButtonToggleGroup
            android:id="@+id/toggleButtonViewGroup"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:singleSelection="true"
            android:padding="5dp"
            app:checkedButton="@id/buttonGridView"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.0">

            <com.google.android.material.button.MaterialButton
                android:id="@+id/buttonListView"
                style="?attr/materialButtonOutlinedStyle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/list_view" />

            <com.google.android.material.button.MaterialButton
                android:id="@+id/buttonGridView"
                style="?attr/materialButtonOutlinedStyle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/grid_view" />
        </com.google.android.material.button.MaterialButtonToggleGroup>

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerViewNotes"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_margin="5dp"
            android:adapter="@{adapter}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/toggleButtonViewGroup"
            tools:itemCount="5"
            tools:listitem="@layout/item_note" />

NotesListViewModel.kt

fun addOnButtonCheckedListener(toggleGroup: MaterialButtonToggleGroup,recyclerView: RecyclerView,mContext: Context){
        recyclerView.layoutManager = StaggeredGridLayoutManager(2,LinearLayoutManager.VERTICAL)
        toggleGroup.addOnButtonCheckedListener { group, checkedId, isChecked ->
            if (isChecked){
                when(checkedId){
                    R.id.buttonListView ->{
                        recyclerView.layoutManager = LinearLayoutManager(mContext,LinearLayoutManager.VERTICAL,false)
                    }
                    R.id.buttonGridView ->{
                        recyclerView.layoutManager = StaggeredGridLayoutManager(2,LinearLayoutManager.VERTICAL)
                    }
                }
            }
        }
    }

DashboardFragment.kt

@AndroidEntryPoint
class DashboardFragment: Fragment() {
    private lateinit var binding: FragmentDashboardBinding
    private val viewModel: NotesListViewModel by viewModels()
    private lateinit var adapter: NotesListAdapter

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?): View {
        binding = FragmentDashboardBinding.inflate(inflater,container,false)
        binding.navController = findNavController()
        binding.viewModel = viewModel
        adapter = NotesListAdapter(viewModel.getNotes(),findNavController())
        binding.adapter = adapter
        viewModel.addOnButtonCheckedListener(binding.toggleButtonViewGroup,binding.recyclerViewNotes,requireActivity())
        return binding.root
    }

    override fun onResume() {
        super.onResume()
        adapter.notifyItemRangeChanged(0,viewModel.getNotes().size)
    }
}

1. Actual result :

enter image description here

2. Expected result :

enter image description here

4
  • 1
    for this you need to add animations between the transitions.
    – Bob
    Commented May 4 at 10:54
  • Thanks for your suggestion bob, but I am not talking about animation here. I am talking about a glitch that you will be able to see in actual result gif. The glitch is, while transiting between either of the two views, the previous view is snapping for a very fraction of a second, which is creating a bad UX. I would suggest you to check my code once again so that you can suggest me something else. Thanks for your comment Commented May 4 at 11:20
  • Can you post complete NotesListAdapter class
    – Bob
    Commented May 4 at 13:32
  • @BobSmith You were absolutely right about the fix you mentioned in your first comment. It's just that I spontaneously replied without even trying!! Thank you so much for your assistance. I will also do try your answer. Commented May 5 at 6:32

1 Answer 1

0

Try this in your adapter class

@Override
public void onBindViewHolder(YourViewHolder holder, int position) {
    // ... your binding logic here

    // Create an AnimatorSet for the animation
    AnimatorSet animatorSet = new AnimatorSet();

    // Scale up animation
    ScaleAnimation scaleUp = new ScaleAnimation(0f, 1f, 0f, 1f,
            Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
    scaleUp.setDuration(300);

    // Translate animation (modify these values for the cascading effect)
    TranslateAnimation translate = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.5f,
            Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f,
            Animation.RELATIVE_TO_SELF, -0.3f);
    translate.setDuration(200);
    translate.setStartDelay(100); // Adjust for cascading effect

    // Add animations to the set
    animatorSet.playSequentially(scaleUp, translate);

    // Start the animation on the item view
    animatorSet.start();
}

The onBindViewHolder() method was used in an adapter which subsequently has been implemented in RecyclerView. Unlike a list, the vector does not save the data of a list. Then, the methods for an animation of the views and the applying of this one to the update view list is going to be developed.

For fall scale the items will be having the components with a different way altogether from the one covered when dealing with RecyclerView which is in the above section. What it means is that the images which are seen as Scrollviewer, provide a stretching out (or flipping) effect to the left and takes time to be adjusted to the following ones.

The contrariwise, pictured image which formerly were admired or framed starts to obscured as the time goes on. Horizontally, the movement becomes so called 'waterfall effect'.

For more animations you can refer

https://github.com/wasabeef/recyclerview-animators