I just wanna know if I’m doing something wrong since I’m kinda new to all this.
If there is anything else that you’ll like me to add just let me know.
This is the repo branch where I’m trying to implement the ViewPager if you wanna see all the code.
Context
So I have 4 Categories represented with Fragments
, each of this categories holds an ArrayList
of items that each has a onItemClickListener
that should reproduce some audio.
I’m trying to display the Fragments
with a ViewPager but the problem is that when I scroll from a Fragment
to another, then come back to the already created Fragment
, it doesnt register the touch event, nothing happens, not even an error nor exception.
If I go to a newly created Fragment
the touch works just fine.
Also, after switching back to an already created Fragment
if I scroll even just a little bit to another Fragment
and comeback or through the ArrayList
of that Fragment
for some reason it starts to recognize the touch in the ArrayList
items again.
Similar questions that didn’t really help
- Fragments in ViewPager2 does not respond to clicks if scroll position is 0
- ViewPager2 conflicting with SwipeRefreshLayout
- Android ViewPager2 with fragment containing a recyclerview not scrolling
What I’ve tried
- I tried to use a
coordinatorlayout
wrapping theViewPager2
but there is no difference - I’ve been reading some of the official viewPager2 examples that are written in Kotlin but none of them seem to have a similar situation (also it’s hard for me to read Kotlin code)
Code Snippets
word_list.xml:
<ListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/root_list_view" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/tan_background" />
activity_main.xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="MainActivity"> <androidx.viewpager2.widget.ViewPager2 android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"/> </FrameLayout>
This is one of the Fragments, the other three are basically the same, just the items in the arrayList change and some other minor things:
// ...Skipped some irrelevant code... public class NumbersFragment extends Fragment { private ArrayList<Word> mWords; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View rootView = inflater.inflate(R.layout.word_list, container, false); mWords = new ArrayList<>(); // ...Add all the items to the list... // Make the adapter for the word items WordAdapter adapter = new WordAdapter(getActivity(), mWords, R.color.category_numbers); // Find the root view of the list ListView listView = rootView.findViewById(R.id.root_list_view); // Add adapter to the root list view listView.setAdapter(adapter); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Log.d("NumbersFragment", "CLICKED"); } } }); return rootView; } @Override public void onPause() { super.onPause(); Log.d("NumbersFragment", "Fragment paused"); } }
This is the Category adapter, it manages the fragments:
public class CategoryAdapter extends FragmentStateAdapter { private static final int NUM_CATEGORIES = 4; // Required public constructor public CategoryAdapter(@NonNull FragmentActivity fragmentActivity) { super(fragmentActivity); } @NonNull @Override public Fragment createFragment(int position) { // Depending on which page the user is in, // create a fragment of the corresponding category switch (position) { case 0: return new NumbersFragment(); case 1: return new FamilyFragment(); case 2: return new ColorsFragment(); default: return new PhrasesFragment(); } } @Override public int getItemCount() { return NUM_CATEGORIES; } }
And this is my MainActivity:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Set the content of the activity to use the activity_main.xml layout file setContentView(R.layout.activity_main); // Find the view pager that will allow the user to swipe between fragments ViewPager2 viewPager = findViewById(R.id.viewpager); // Create an adapter that knows which fragment should be shown on each page CategoryAdapter adapter = new CategoryAdapter(this); //or CategoryAdapter adapter = new CategoryAdapter(getSupportFragmentManager(), getLifecycle()); // Set the adapter into the view pager viewPager.setAdapter(adapter); } }
Advertisement
Answer
add this in your MainActivity viewPager.setOffscreenPageLimit(3);
after creating viewpager
It’s because the ViewPager has a default offscreen limit of 1 ,and ViewPager2 has a default offscreen limit of 0.
In ViewPager2 when you switch tabs the previous tab will be automatically refreshed.
in ViewPager if you have 3 tabs or more when you switch to 3rd tab automatically first one will be destroyed and when you goes to 1st tab it will be recreated.
viewPager.setOffscreenPageLimit(3);
from this line when you switch to a tab,the previous 3 tabs will be preloaded and next 3 tabs will be preloaded so nothing will be refreshed.