Challenge #2 (first and last)


#1

It’s not the prettiest solution but it works like it’s supposed to. I guess there must be a more concise way to do this. Would love your thoughts:

public class CrimePagerActivity extends AppCompatActivity implements View.OnClickListener {

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

private ViewPager mViewPager;
private List<Crime> mCrimes;
private Button mFirst, mLast;

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 = findViewById(R.id.crime_view_pager);
    mFirst = findViewById(R.id.btn_first);
    mLast = findViewById(R.id.btn_last);

    mCrimes = CrimeLab.get(this).getCrimes();

    FragmentManager fragmentManager = getSupportFragmentManager();
    mViewPager.setAdapter(new FragmentStatePagerAdapter(fragmentManager) {

        @Override
        public Fragment getItem(int position) {
            Crime crime = mCrimes.get(position);

            if(mViewPager.getCurrentItem() == 0){
                mFirst.setEnabled(false);
            } else {
                mFirst.setEnabled(true);
            }
            if(mViewPager.getCurrentItem() == mCrimes.size() - 1){
                mLast.setEnabled(false);
            } else {
                mLast.setEnabled(true);
            }

            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);
            break;
        }

    }

    mFirst.setOnClickListener(this);
    mLast.setOnClickListener(this);

}

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.btn_first:
            mViewPager.setCurrentItem(0);
            break;
        case R.id.btn_last:
            mViewPager.setCurrentItem(mCrimes.size() - 1);
            break;
        default:
            break;
    }
}

}


#2

I thought of the same solution at first but i am facing an issue with getItem() as i does get called each time and i still don’t know why so i used ViewPager method addOnPageChangeListener()

  • first i changesd XML :

` <?xml version="1.0" encoding="utf-8"?>

<android.support.v4.view.ViewPager
    android:id="@+id/crime_view_pager"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"/>

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="2dp">

    <Button
        android:id="@+id/jump_to_first_button"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:layout_margin="2dp"
        android:text="@string/jump_to_first"/>

    <Button
        android:id="@+id/jump_to_last_button"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:layout_margin="2dp"
        android:text="@string/jump_to_last"/>
    </LinearLayout>
    </LinearLayout>`
  • then i wired buttons, setOnclickListners, and addOnPageChangeListener():

    public class CrimePagerActivity extends AppCompatActivity {
    
    private ViewPager mViewPager;
    private Button mJumpToFirst;
    private Button mJumpToLast;
    private List<Crime> mCrimes;
    
     @Override
     protected void onCreate(@Nullable 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.setPageMargin(getResources().getDimensionPixelSize(R.dimen.view_pager_margin));
    
      mCrimes = CrimeLab.get(this).getCrimes();
      FragmentManager fragmentManager = getSupportFragmentManager();
      mViewPager.setAdapter(new FragmentStatePagerAdapter(fragmentManager) {
          @Override
          public Fragment getItem(int position) {
              Crime crime = mCrimes.get(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);
              break;
          }
      }
    
      mJumpToFirst = (Button) findViewById(R.id.jump_to_first_button);
      mJumpToFirst.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View view) {
              mViewPager.setCurrentItem(0);
          }
      });
    
      mJumpToLast = (Button) findViewById(R.id.jump_to_last_button);
      mJumpToLast.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View view) {
              mViewPager.setCurrentItem(mCrimes.size() - 1);
          }
      });
    
      mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
          @Override
          public void onPageScrolled(int i, float v, int i1) {
              mJumpToFirst.setEnabled(mViewPager.getCurrentItem() != 0);
              mJumpToLast.setEnabled(mViewPager.getCurrentItem() != mCrimes.size() - 1);
          }
    
          @Override
          public void onPageSelected(int i) {
              // Nothing
          }
    
          @Override
          public void onPageScrollStateChanged(int i) {
              // Nothing
          }
      });
    
    }
    }

#3

Hello @pat, your solution seems absolutely correct. what I did not understand is I tried to get position from CrimeListFragment intent and passed it to CrimePagerActivity and checked that position for 0 or list size -1 and then disabled the buttons because buttons are outside the viewPager and in the Activity.
and it worked when I put the logic inside the viewPager, setAdapter method like yours.

public class CrimePagerActivity extends AppCompatActivity {

private static final String EXTRA_CRIME_ID = "crime_id";
private static final String POSITION ="clicked_position";
private ViewPager mViewPager;
private List<Crime> mCrimeList;
private Button mFirstBtn, mLastBtn;

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

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

    mFirstBtn = findViewById(R.id.jumpToFirst_btn);
    mLastBtn = findViewById(R.id.jumpToLast_btn);

    mViewPager = findViewById(R.id.crime_view_pager);
    mCrimeList = CrimeLab.get(this).getCrimes();

   UUID crimeId = (UUID) getIntent().getSerializableExtra(EXTRA_CRIME_ID);
   int position = getIntent().getIntExtra(POSITION,0);

    if(position==0){
        mFirstBtn.setEnabled(false);
    }else{
        mFirstBtn.setEnabled(true);
    }

    if(position==mCrimeList.size()-1){
        mLastBtn.setEnabled(false);
    }else{
        mLastBtn.setEnabled(true);
    }

    mFirstBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mViewPager.setCurrentItem(0);
         }
    });

    mLastBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mViewPager.setCurrentItem(mCrimeList.size()-1);
        }
    });


    FragmentManager fragmentManager = getSupportFragmentManager();

    mViewPager.setAdapter(new FragmentStatePagerAdapter(fragmentManager) {
        @Override
        public Fragment getItem(int position) {
            Crime crime = mCrimeList.get(position);

//                if(mViewPager.getCurrentItem()==0){
//                    mFirstBtn.setEnabled(false);
//                }else{
//                    mFirstBtn.setEnabled(true);
//                }
//
//                if(mViewPager.getCurrentItem()==mCrimeList.size()-1){
//                    mLastBtn.setEnabled(false);
//                }else{
//                    mLastBtn.setEnabled(true);
//                }
            return CrimeFragment.newInstance(crime.getId());
        }

        @Override
        public int getCount() {
            return mCrimeList.size();
        }
    });

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

}

Many Thanks,


#4

glad I could help :slight_smile:


#5

Hello @pat, would you know why the other method dint work, the code I have pasted above.

Thanks.