0

I have two floating action buttons in a fragment that is being created by a ViewPager. My intention is for the FABs to do the same thing that can be done in the ViewPager, so that the user can have a choice in terms of navigation. My problem is that the FABs do not respond to clicks initially, so if I click the left FAB, and then click the right FAB, the ViewPager will flip to the left instead of flipping to the right. What am I doing wrong?

Here is my code:

activity_view_pager:

<?xml version="1.0" encoding="utf-8"?>
<androidx.viewpager.widget.ViewPager
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/view_pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

fragment_test:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:text="Title"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/a"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="100dp"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="200dp"
        android:text="Description"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/b"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="250dp"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/c"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="300dp"
        app:layout_constraintTop_toTopOf="parent" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/left_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="50dp"
        android:layout_marginTop="450dp"
        android:src="@drawable/ic_left_arrow"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/right_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="450dp"
        android:layout_marginEnd="50dp"
        android:src="@drawable/ic_right_arrow"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

ViewPagerActivity:

package com.fl4me.android.exampleapplication;

import static com.fl4me.android.exampleapplication.TestAdapter.EXTRA_ID;
import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;

public class ViewPagerActivity extends AppCompatActivity {

    public static int index;
    public static ViewPager viewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view_pager);

        index = (int) getIntent().getSerializableExtra(EXTRA_ID);

        viewPager = (ViewPager) findViewById(R.id.view_pager);

        FragmentManager fragmentManager = getSupportFragmentManager();
        viewPager.setAdapter(new FragmentStatePagerAdapter(fragmentManager) {
            @Override
            public Fragment getItem(int position) {
                return TestFragment.newInstance(position);
            }

            @Override
            public int getCount() {
                return 5;
            }
        });

        for(int i = 0; i < Test.testData.length; i++) {
            if(i == index) {
                viewPager.setCurrentItem(i);
                break;
            }
        }
    }
}

TestFragment:

package com.fl4me.android.exampleapplication;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.fragment.app.Fragment;
import androidx.viewpager.widget.ViewPager;

import com.google.android.material.floatingactionbutton.FloatingActionButton;

public class TestFragment extends Fragment {

    private static final String ARG_ID = "Id";
    private int Id;
    private String a;
    private TextView aTV;
    private String b;
    private TextView bTV;
    private int c;
    private TextView cTV;
    private FloatingActionButton leftBtn;
    private FloatingActionButton rightBtn;

    public static TestFragment newInstance(int Id) {
        Bundle args = new Bundle();
        args.putSerializable(ARG_ID, Id);

        TestFragment fragment = new TestFragment();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_test, container, false);

        Id = getArguments().getInt(ARG_ID);
        a = Test.testData[Id].getA();
        b = Test.testData[Id].getB();
        c = Test.testData[Id].getC();

        aTV = (TextView) view.findViewById(R.id.a);
        aTV.setText(a);

        bTV = (TextView) view.findViewById(R.id.b);
        bTV.setText(b);

        cTV = (TextView) view.findViewById(R.id.c);
        cTV.setText(String.valueOf(c));

        leftBtn = view.findViewById(R.id.left_btn);
        rightBtn = view.findViewById(R.id.right_btn);

        leftBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ViewPagerActivity.viewPager.setCurrentItem(ViewPagerActivity.index--);
            }
        });

        rightBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ViewPagerActivity.viewPager.setCurrentItem(ViewPagerActivity.index++);
            }
        });

        return view;
    }
}
fl4me
  • 5
  • 2

1 Answers1

0

This is probably happening because you are post-incrementing or post-decrementing the index instead of pre-incrementing or pre-decrementing it. I think that you should know how post and pre incrementation works, but here is something to read.

Basically the index that you are providing for the setCurrentItem is not evaluated on the spot as index + 1 or index - 1, but it gets its new value only after the execution of the line of code in which there is an expression index++ or index--. This is why you got that "lag" in switching pages that you have described.

So, in your listener for the rightBtn the code should probably be like this:

ViewPagerActivity.viewPager.setCurrentItem(++ViewPagerActivity.index);

The listener for the leftBtn will be analogous, but with --.

sweak
  • 1,369
  • 2
  • 6
  • 21
  • Oh, that makes perfect sense. I do know how pre- and post-incrementation work, but I've never used them that much, so I haven't really had experience with them. I was thinking that maybe my ViewPager was somehow intercepting the clicks or something, but I wouldn't have guessed that the fix was that simple. Thanks a lot for answering this question and my previous one. I really appreciate it! – fl4me Aug 12 '21 at 02:37
  • Hey, sorry for bringing this question back up again, but I'm having a bit more trouble with my buttons. I'm trying have the buttons become invisible when the user is on the first and last items of the ViewPager, but it's not working properly. I have a separate method written in TestFragment that makes the left button invisible when the index is zero, and the right button invisible when the index is the last element of the array. I then call this method after finding the views of the left and right buttons and after setting the ViewPager in both of the buttons' `onClick` methods. Any ideas? – fl4me Aug 15 '21 at 00:45
  • Again, You would need to post the code for someone to resolve the issue, so probably You need create a separate question for that. – sweak Aug 15 '21 at 10:11
  • OK, I have posted a new question. I didn't want to make a new question for what seems like a really small issue, but I guess people would need to see the code to be able to help resolve the issue. – fl4me Aug 16 '21 at 00:12