Problem with ViewPager: shows only one list item. The program consists of several fragments (more details below). The bottom line is that an array of crimes is created, then a RecyclerView is created, and when you click on a list item, you go to a detailed description of the crime.
package com.example.user.criminalintent; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class CrimeActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_crime); FragmentManager fm = getSupportFragmentManager(); Fragment fragment_list = fm.findFragmentById(R.id.list_of_crimes); if (fragment_list == null){ fragment_list = new CrimeList(); fm.beginTransaction() .add(R.id.fragment_container,fragment_list) .commit(); } } } The code above is the main activity on which a fragment appears with RecyclerView.
package com.example.user.criminalintent; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import java.util.List; public class CrimeList extends Fragment { RecyclerView rv; private ListOfCrimes mAdapter; @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View v = inflater.inflate(R.layout.list_of_crimes, container, false); rv = v.findViewById(R.id.rv1); rv.setLayoutManager(new LinearLayoutManager(getActivity())); rv.setHasFixedSize(true); updateUI(); return v; } public void updateUI(){ CrimeLab crimeLab = CrimeLab.get(getActivity()); List<Crime> crimes = crimeLab.getCrimes(); if (mAdapter == null){ mAdapter = new ListOfCrimes(crimes); rv.setAdapter(mAdapter); }else mAdapter.notifyDataSetChanged(); } @Override public void onResume() { super.onResume(); updateUI(); } } Recylerview
package com.example.user.criminalintent; import android.content.Context; import android.content.Intent; import android.support.annotation.NonNull; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import java.util.List; public class ListOfCrimes extends RecyclerView.Adapter<ListOfCrimes.ViewHolder> { private List<Crime> mCrimes; public ListOfCrimes(List<Crime> crimes){ mCrimes = crimes; } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { Context context = viewGroup.getContext(); int layout_id = R.layout.list; LayoutInflater inflater = LayoutInflater.from(context); View view = inflater.inflate(layout_id,viewGroup,false); ViewHolder viewHolder = new ViewHolder(view); return viewHolder; } @Override public void onBindViewHolder(@NonNull ViewHolder holder, int i) { Crime crime = mCrimes.get(i); holder.bind(crime); } @Override public int getItemCount() { return mCrimes.size(); } class ViewHolder extends RecyclerView.ViewHolder { private TextView tv1; private Crime mCrime; public ViewHolder(@NonNull final View itemView) { super(itemView); mCrime = new Crime(); tv1 = itemView.findViewById(R.id.tv1_list); itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(itemView.getContext(),MainActivity.class); intent.putExtra("key",mCrime.getmId()); itemView.getContext().startActivity(intent); } }); } public void bind(Crime crime){ mCrime = crime; tv1.setText(mCrime.getmTitle()+"\n"+mCrime.getmDate()+"\n"); } } } The two pieces of code above are all related to RecyclerView.
package com.example.user.criminalintent; import android.content.Context; import java.util.ArrayList; import java.util.List; import java.util.UUID; public class CrimeLab { private static CrimeLab sCrimeLab; private static List<Crime> mCrimes; public static CrimeLab get(Context context){ if (sCrimeLab == null){ sCrimeLab = new CrimeLab(context); } return sCrimeLab; } private CrimeLab(Context context){ mCrimes = new ArrayList<>(); for (int i =0;i<100;i++){ Crime crime = new Crime(); crime.setmTitle("Crime# "+i); crime.setmSolved(i%2 == 0); mCrimes.add(crime); } } public Crime getCrime(UUID id){ for (int i=0;i<mCrimes.size();i++) { if (mCrimes.get(i).getmId().equals(id)){ return mCrimes.get(i); } } return null; } public List<Crime> getCrimes(){ return mCrimes; } } The code above is a singlet class that acts as a repository of crimes in this application
package com.example.user.criminalintent; import java.util.Date; import java.util.UUID; public class Crime { private UUID mId; private String mTitle; private Date mDate; private boolean mSolved; public Crime(){ mId = UUID.randomUUID(); mDate = new Date(); } public UUID getmId() { return mId; } public void setmTitle(String mTitle) { this.mTitle = mTitle; } public void setmDate(Date mDate) { this.mDate = mDate; } public void setmSolved(boolean mSolved) { this.mSolved = mSolved; } public String getmTitle() { return mTitle; } public boolean ismSolved() { return mSolved; } public Date getmDate() { return mDate; } } Above directly the crime class itself
package com.example.user.criminalintent; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.text.Editable; import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.EditText; import java.util.UUID; public class CriminalFragment extends Fragment { private Crime mCrime; private EditText mTextfiled; private Button mDateButton; private CheckBox checkBox; private static final String ARG_CRIME_ID = "crime_id"; @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_crime,container,false); UUID crimeId = (UUID) getActivity().getIntent().getSerializableExtra("key"); mCrime = CrimeLab.get(getActivity()).getCrime(crimeId); mDateButton = v.findViewById(R.id.btn_crime); mDateButton.setEnabled(false); mDateButton.setText(mCrime.getmDate().toString()); checkBox = v.findViewById(R.id.solved_crime); mTextfiled = v.findViewById(R.id.edt_crime); mTextfiled.setText(mCrime.getmTitle()); mTextfiled.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.setmTitle(s.toString()); } @Override public void afterTextChanged(Editable s) { } }); checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { mCrime.setmSolved(isChecked); } }); return v; } public static CriminalFragment newInstance(UUID crime_id){ Bundle args = new Bundle(); args.putSerializable(ARG_CRIME_ID,crime_id); CriminalFragment fragment = new CriminalFragment(); fragment.setArguments(args); return fragment; } } Above is the second fragment, which is a detail of the crime
package com.example.user.criminalintent; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentStatePagerAdapter; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import java.util.List; import java.util.UUID; public class MainActivity extends AppCompatActivity { private ViewPager mViewPager; private List<Crime> mCrimes; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.crime_pager); final UUID crimeId = (UUID) getIntent().getSerializableExtra("key"); mViewPager = findViewById(R.id.crime_pager); mCrimes = CrimeLab.get(this).getCrimes(); FragmentManager fm1 = getSupportFragmentManager(); mViewPager.setAdapter(new FragmentStatePagerAdapter(fm1) { @Override public Fragment getItem(int position) { Crime crime = mCrimes.get(position); return CriminalFragment.newInstance(crime.getmId()); } @Override public int getCount() { return mCrimes.size(); } }); for (int i=0;i<mCrimes.size();i++){ if (mCrimes.get(i).getmId().equals(crimeId)){ mViewPager.setCurrentItem(i); break; } } } } Above is the second activity, which is the host for the CriminalFragment.
In principle, the program works, but there is one nuance: when you click on any element in the list and then scroll, only one element is scrolled through, that is, you clicked on element 3, you scroll left to right - all the same there will be third element. Already 3 hours I can not understand what was happening. Thank you in advance.