I'm trying to build an Android application using the new ViewPager2. I've added two ViewPagers, separated by a view, and when you swipe, both viewpagers should move. Both view pagers are moving correctly but upon completion of the gesture, the swiped view flashes and the non swiped view reloads, as demonstrated by the attached gif. Here is my code for the Activity, ViewPagerAdapter, and Fragment. Any help is appreciated
public class MainActivity extends FragmentActivity {
ActivityMainBinding viewBinding;
MyPager adapter1, adapter2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
List<String> data = populateData();
adapter1 = new MyPager(this, data);
adapter2 = new MyPager(this, data);
viewBinding.viewPager.setAdapter(adapter1);
viewBinding.viewPager2.setAdapter(adapter2);
viewBinding.viewPager2.setOffscreenPageLimit(data.size());
viewBinding.viewPager.setOffscreenPageLimit(data.size());
viewBinding.viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {
viewBinding.viewPager2.scrollTo(positionOffsetPixels, 0);
}
@Override
public void onPageScrollStateChanged(final int state) {
viewBinding.viewPager2.setCurrentItem(viewBinding.viewPager.getCurrentItem(), true);
}
});
viewBinding.viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {
viewBinding.viewPager.scrollTo(positionOffsetPixels, 0);
}
@Override
public void onPageScrollStateChanged(final int state) {
viewBinding.viewPager.setCurrentItem(viewBinding.viewPager2.getCurrentItem(), true);
}
});
}
private List<String> populateData() {
List<String> data = new ArrayList<>();
for (int x = 0; x < 10; x++) {
String derril = "derril " + x;
data.add(derril);
}
return data;
}
}
public class MyPager extends FragmentStateAdapter {
List<String> data;
public MyPager(@NonNull FragmentActivity fragmentActivity, List<String> data) {
super(fragmentActivity);
this.data = data;
}
@NonNull
@Override
public Fragment createFragment(int position) {
return DerrilFragment.newInstance(data.get(position));
}
@Override
public int getItemCount() {
return data.size();
}
}
public class DerrilFragment extends Fragment {
PizzaBinding viewBinding;
String data;
private DerrilFragment(String data) {
this.data = data;
}
public static DerrilFragment newInstance(String data) {
return new DerrilFragment(data);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
viewBinding = DataBindingUtil.inflate(inflater, R.layout.pizza, container, false);
viewBinding.text.setText(data);
return viewBinding.getRoot();
}
}
You can implement by RecyclerView
.
class MainActivity : AppCompatActivity() {
private var isFirstFocused = false
private val helper: SnapHelper = LinearSnapHelper()
private val helper2: SnapHelper = LinearSnapHelper()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
recycler1.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
if (isFirstFocused) recycler2.scrollBy(dx, dy)
}
})
recycler2.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
if (!isFirstFocused) recycler1.scrollBy(dx, dy)
}
})
recycler2.setOnTouchListener { v, event ->
if (event.action != null && event.action == MotionEvent.ACTION_DOWN ) {
isFirstFocused = false
return@setOnTouchListener true
}
return@setOnTouchListener false
}
recycler1.setOnTouchListener { v, event ->
if (event.action != null && event.action == MotionEvent.ACTION_DOWN ) {
isFirstFocused = true
return@setOnTouchListener true
}
return@setOnTouchListener false
}
helper.attachToRecyclerView(recycler1)
helper2.attachToRecyclerView(recycler2)
val manager = LinearLayoutManager(this, RecyclerView.HORIZONTAL, false)
val manager2 = LinearLayoutManager(this, RecyclerView.HORIZONTAL, false)
recycler1.layoutManager = manager
recycler2.layoutManager = manager2
recycler2.adapter = Adapter(items)
recycler1.adapter = Adapter(items)
}
private val items = listOf("One", "Two", "Three")
}
class Adapter(val list: List<String>) : RecyclerView.Adapter<Adapter.Holder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
val view = LayoutInflater.from(parent.context).inflate(
R.layout.activity_listview,
parent,
false
)
return Holder(view)
}
override fun onBindViewHolder(holder: Holder, position: Int) {
holder.itemView.text_view.text = list[position]
}
override fun getItemCount() = list.size
class Holder(view: View) : RecyclerView.ViewHolder(view)
}