Stack Exchange
Не получается корректно передать номер элемента во фрагмент через ViewPager
Есть код ViewPager:
public class CrimePagerActivity extends AppCompatActivity {

    private static final String EXTRA_CRIME_ID =
            "com.bignerdranch.android.criminalintent.crime_id";

    private static ViewPager mViewPager;
    public static List<Crime> mCrimes;
    public static int indexPager;

    private Button startButton;
    private Button finishButton;

    public static Intent newIntent(Context packageContext, UUID crimeId) {
        Intent intent = new Intent(packageContext, CrimePagerActivity.class);
        intent.putExtra(EXTRA_CRIME_ID, crimeId);
        return intent;
    }

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

        UUID crimeId = (UUID) getIntent()
                .getSerializableExtra(EXTRA_CRIME_ID);

        mViewPager = (ViewPager) findViewById(R.id.crime_view_pager);
        mViewPager.setClipToPadding(false);
        mViewPager.setPadding(20, 0, 20, 0);
        mViewPager.setPageMargin(20);
        mCrimes = CrimeLab.get(this).getCrimes();
        FragmentManager fragmentManager = getSupportFragmentManager();
        mViewPager.setAdapter(new FragmentStatePagerAdapter(fragmentManager) {

            @Override
            public Fragment getItem(int position) {  // !!!
                Crime crime = mCrimes.get(position);
                indexPager = position;
                return CrimeFragment.newInstance(crime.getId());
            }

            @Override
            public int getCount() {
                return mCrimes.size(); //!!!!!!!!
            }
        });

        for (int i = 0; i < mCrimes.size(); i++) {
            if (mCrimes.get(i).getId().equals(crimeId)) {
                mViewPager.setCurrentItem(i);
                indexPager = i;
                break;
            }
        }
    }

    public static void razmeshcheniyePager(int a){
        mViewPager.setCurrentItem(a);
    }
}

И код фрагмента:
public class CrimeFragment extends Fragment {

    private static final String ARG_CRIME_ID = "crime_id";

    private Crime mCrime;
    private EditText mTitleField;
    private Button mDateButton;
    private CheckBox mSolvedCheckBox;

    private Button startButton;
    private Button finishButton;

    private CrimePagerActivity mPagerActivity;

    public static CrimeFragment newInstance(UUID crimeId) {
        Bundle args = new Bundle();
        args.putSerializable(ARG_CRIME_ID, crimeId);
        CrimeFragment fragment = new CrimeFragment();
        fragment.setArguments(args);
        return fragment;
    }

        @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
            UUID crimeId = (UUID) getArguments().getSerializable(ARG_CRIME_ID);
            mCrime = CrimeLab.get(getActivity()).getCrime(crimeId);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_crime, container, false); // уточнить, что происходит здесь
        mTitleField = (EditText) v.findViewById(R.id.crime_title);


        startButton = (Button) v.findViewById(R.id.start_button); 
        if(CrimePagerActivity.indexPager == 2) startButton.setEnabled(false);
        startButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mPagerActivity.razmeshcheniyePager(0);
            }
        });

        finishButton = (Button) v.findViewById(R.id.fifsh_button); 
        if (CrimePagerActivity.indexPager == CrimePagerActivity.mCrimes.size()-3) finishButton.setEnabled(false);
        finishButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mPagerActivity.razmeshcheniyePager(CrimePagerActivity.mCrimes.size()-1);
            }
        });

        mTitleField.setText(mCrime.getTitle());
        mTitleField.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                mCrime.setTitle(s.toString()); // возвращает строку, которая используется для задания заголовка Crime
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

        mDateButton = (Button) v.findViewById(R.id.crime_date); // кнопка во фрагменте создаётся немного не так, как в активности
        mDateButton.setText(mCrime.getDate().toString()); // вывод даты на кнопке
        mDateButton.setEnabled(false); // блокироание возможности нажатия кнопки

        mSolvedCheckBox = (CheckBox)v.findViewById(R.id.crime_solved);
        mSolvedCheckBox.setChecked(mCrime.isSolved()); // метод setChecked меняет булеву значение булевой переменной на противоположное
        mSolvedCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                mCrime.setSolved(isChecked);
            }
        });
        return v;
    }
}

Мне нужно блокировать кнопку перемещения в начало или конец списка, в том случае, если пользователь уже находится в начале или конце списка. 
Для этого я пытаюсь передать позицию элемента через статическую переменную. Проблема в том, что позиция элемента передаётся не корректно (то есть когда должно передаваться число 0, передаётся 2, когда должно передаваться 99, передаётся 97). И даже если в коде фрагмента учесть это, блокировка кнопок всё равно происходит не корректно (могут даже заблокироваться кнопки на нескольких элементах, находящихся рядом).
Пробовал найти проблему с помощью debug, столкнулся ещё с одной непонятной особенностью. Код, перед блокировкой кнопок может поочерёдно вызываться несколько раз (может вообще не вызываться). Код некоторых методов в анонимном классе new FragmentStatePagerAdapter (который находится в активности CrimePagerActivity) может вообще вызываться огромное количество раз.
Объясните, пожалуйста, что происходит и что с этим делать
P.S. Пример кода взят из книги "Android программирование для профессионалов" глава 11

Я не очень понял что именно вы хотите сделать, но, думаю, проблема у вас в том, что вы не учитываете, что по умолчанию ViewPager инициализирует сразу несколько фрагментов, а не только тот, что виден изначально. И инициализируются они не всегда в ожидаемом порядке.

Возможно вам нужно прикрутить FragmentPagerAdapter вместо вашего адаптера

PagerAdapter использует упреждающую загрузку - то есть создаёт не только ту страницу, которая видна, но и соседние. Сделано это для того, чтобы перелистывание было плавным, без задержки. Второй момент: методы жизненного цикла вызываются не сразу вслед за конструктором фрагмента, а когда это необходимо. Таким образом в момент вызова onCreateView для первой страницы, переменной indexPager уже присвоено значение позиции следующей страницы.  
Во избежание подобных недоразумений и был придуман механизм передачи данных во фрагмент через аргументы. Используем этот механизм:
    mViewPager.setAdapter(new FragmentStatePagerAdapter(fragmentManager) {

        @Override
        public Fragment getItem(int position) {
            Crime crime = mCrimes.get(position);
            return CrimeFragment.newInstance(crime.getId(), position); // !!!!!!!!
        }


public class CrimeFragment extends Fragment {

    private static final String ARG_CRIME_ID = "crime_id";
    private static final String ARG_ADAPTER_POSITION = "position"; // !!!!!!!!!

    private Crime mCrime;
    private EditText mTitleField;
    private Button mDateButton;
    private CheckBox mSolvedCheckBox;

    private Button startButton;
    private Button finishButton;

    private CrimePagerActivity mPagerActivity;
    private int mPosition; // !!!!!!!!

    public static CrimeFragment newInstance(UUID crimeId, int position) { // !!!!!!!!
        Bundle args = new Bundle();
        args.putSerializable(ARG_CRIME_ID, crimeId);
        args.putInt(ARG_ADAPTER_POSITION, position); // !!!!!!!!
        CrimeFragment fragment = new CrimeFragment();
        fragment.setArguments(args);
        return fragment;
    }

        @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
            UUID crimeId = (UUID) getArguments().getSerializable(ARG_CRIME_ID);
            mPosition = getArguments().getInt(ARG_ADAPTER_POSITION); // !!!!!!!!
            mCrime = CrimeLab.get(getActivity()).getCrime(crimeId);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_crime, container, false); // уточнить, что происходит здесь
        mTitleField = (EditText) v.findViewById(R.id.crime_title);


        startButton = (Button) v.findViewById(R.id.start_button); 
        if (mPosition == 0) {                                    // !!!!!!!!
            startButton.setEnabled(false);
        } else {
            startButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mPagerActivity.razmeshcheniyePager(0);
                }
            });
        }

        finishButton = (Button) v.findViewById(R.id.fifsh_button); 
        if (mPosition == CrimePagerActivity.mCrimes.size() - 1) { // !!!!!!!!
            finishButton.setEnabled(false);
        } else {
            finishButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                   mPagerActivity.razmeshcheniyePager(CrimePagerActivity.mCrimes.size() - 1);
                }
            });


        mTitleField.setText(mCrime.getTitle());
        mTitleField.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                mCrime.setTitle(s.toString()); // возвращает строку, которая используется для задания заголовка Crime
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

        mDateButton = (Button) v.findViewById(R.id.crime_date); // кнопка во фрагменте создаётся немного не так, как в активности
        mDateButton.setText(mCrime.getDate().toString()); // вывод даты на кнопке
        mDateButton.setEnabled(false); // блокироание возможности нажатия кнопки

        mSolvedCheckBox = (CheckBox)v.findViewById(R.id.crime_solved);
        mSolvedCheckBox.setChecked(mCrime.isSolved()); // метод setChecked меняет булеву значение булевой переменной на противоположное
        mSolvedCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                mCrime.setSolved(isChecked);
            }
        });
        return v;
    }
}

