Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replaced ViewPager with ViewPager2 #894

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
android:elevation="10dp"
app:layout_constraintBottom_toBottomOf="@+id/fragmentContainer"/>

<androidx.viewpager.widget.ViewPager
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="0dp"
Expand Down
11 changes: 8 additions & 3 deletions org.envirocar.app/res/layout/fragment_tracklist_layout.xml
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,15 @@

</info.hoang8f.android.segmented.SegmentedGroup>

<androidx.viewpager.widget.ViewPager
android:id="@+id/fragment_tracklist_layout_viewpager"
<org.envirocar.app.views.utils.NestedScrollableHost
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
android:layout_weight="1">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/fragment_tracklist_layout_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</org.envirocar.app.views.utils.NestedScrollableHost>


</LinearLayout>
35 changes: 15 additions & 20 deletions org.envirocar.app/src/org/envirocar/app/views/BaseMainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,12 @@
import androidx.activity.OnBackPressedCallback;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;

import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.snackbar.Snackbar;
Expand Down Expand Up @@ -79,7 +82,7 @@ public class BaseMainActivity extends BaseInjectorActivity {

private static final String TROUBLESHOOTING_TAG = "TROUBLESHOOTING";

private FragmentStatePagerAdapter fragmentStatePagerAdapter;
private PageSlider fragmentStatePagerAdapter;
private MenuItem prevMenuItem;

// Custom Callback Stack
Expand Down Expand Up @@ -116,7 +119,7 @@ public class BaseMainActivity extends BaseInjectorActivity {
protected BottomNavigationView navigationBottomBar;

@BindView(R.id.fragmentContainer)
protected ViewPager viewPager;
protected ViewPager2 viewPager;

private CompositeDisposable subscriptions = new CompositeDisposable();
private BroadcastReceiver errorInformationReceiver;
Expand Down Expand Up @@ -158,7 +161,7 @@ protected void onCreate(Bundle savedInstanceState) {
navigationBottomBar.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
navigationBottomBar.setSelectedItemId(R.id.navigation_dashboard);

fragmentStatePagerAdapter = new PageSlider(getSupportFragmentManager(), FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
fragmentStatePagerAdapter = new PageSlider(this);
viewPager.setAdapter(fragmentStatePagerAdapter);

// Custom Back Navigation for fragments in BaseMainActivity
Expand All @@ -175,14 +178,10 @@ public void handleOnBackPressed() {
};
this.getOnBackPressedDispatcher().addCallback(this, callback);

viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

}

viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
if (prevMenuItem != null) {
prevMenuItem.setChecked(false);
} else {
Expand All @@ -195,14 +194,9 @@ public void onPageSelected(int position) {
}
navigationBottomBar.getMenu().getItem(position).setChecked(true);
prevMenuItem = navigationBottomBar.getMenu().getItem(position);
fragmentStatePagerAdapter.notifyDataSetChanged();
}

@Override
public void onPageScrollStateChanged(int state) {

}
});

// Subscribe for preference subscriptions. In this case, subscribe for changes to the
// active screen settings.
// TODO
Expand Down Expand Up @@ -355,12 +349,13 @@ private void showSnackbar(String info) {
Snackbar.make(navigationBottomBar, info, Snackbar.LENGTH_LONG).show();
}

private class PageSlider extends FragmentStatePagerAdapter {

private class PageSlider extends FragmentStateAdapter {

private Fragment[] fragments;

public PageSlider(@NonNull FragmentManager fm, int behavior) {
super(fm, behavior);
public PageSlider(@NonNull FragmentActivity fragmentActivity) {
super(fragmentActivity);
fragments = new Fragment[]{
dashboardFragment,
trackListPagerFragment,
Expand All @@ -370,12 +365,12 @@ public PageSlider(@NonNull FragmentManager fm, int behavior) {

@NonNull
@Override
public Fragment getItem(int position) {
public Fragment createFragment(int position) {
return fragments[position];
}

@Override
public int getCount() {
public int getItemCount() {
return 3;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;

import org.envirocar.app.BaseApplication;
import org.envirocar.app.BaseApplicationComponent;
Expand All @@ -49,7 +52,7 @@ public class TrackListPagerFragment extends BaseInjectorFragment {
@BindView(R.id.trackListSegmentedGroup)
protected SegmentedGroup trackListSegmentedGroup;
@BindView(R.id.fragment_tracklist_layout_viewpager)
protected ViewPager mViewPager;
protected ViewPager2 mViewPager;

private TrackListPagerAdapter trackListPageAdapter;

Expand All @@ -68,30 +71,24 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
View content = inflater.inflate(R.layout.fragment_tracklist_layout, container, false);
ButterKnife.bind(this, content);

trackListPageAdapter = new TrackListPagerAdapter(getChildFragmentManager());
trackListPageAdapter = new TrackListPagerAdapter(this);
mViewPager.setAdapter(trackListPageAdapter);
mViewPager.setSaveFromParentEnabled(false);

mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

}
mViewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {

@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
if (position == 0) {
trackListSegmentedGroup.check(R.id.localSegmentedButton);
} else {
trackListSegmentedGroup.check(R.id.uploadedSegmentedButton);
}
}

@Override
public void onPageScrollStateChanged(int state) {

}
});

trackListSegmentedGroup.check(R.id.localSegmentedButton);

trackListSegmentedGroup.setOnCheckedChangeListener((radioGroup, i) -> {
Expand Down Expand Up @@ -126,7 +123,7 @@ public void onDestroyView() {
/**
* @author dewall
*/
class TrackListPagerAdapter extends FragmentStatePagerAdapter {
class TrackListPagerAdapter extends FragmentStateAdapter {
private static final int NUM_PAGES = 2;

private TrackListLocalCardFragment localCardFragment;
Expand All @@ -137,16 +134,17 @@ class TrackListPagerAdapter extends FragmentStatePagerAdapter {
*
* @param fm the fragment manager of the application's current scope.
*/
public TrackListPagerAdapter(FragmentManager fm) {
public TrackListPagerAdapter(@NonNull Fragment fm) {
super(fm);

remoteCardFragment = new TrackListRemoteCardFragment();
localCardFragment = new TrackListLocalCardFragment();
localCardFragment.setOnTrackUploadedListener(remoteCardFragment);
}

@NonNull
@Override
public Fragment getItem(int position) {
public Fragment createFragment(int position) {
if (position == 0) {
return localCardFragment;
} else {
Expand All @@ -155,9 +153,8 @@ public Fragment getItem(int position) {
}

@Override
public int getCount() {
public int getItemCount() {
return NUM_PAGES;
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package org.envirocar.app.views.utils;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewpager2.widget.ViewPager2;

public class NestedScrollableHost extends FrameLayout {

private int touchSlop = 0;
private float initialX = 0;
private float initialY = 0;
private ViewPager2 parentPager;
private ViewPager2 childPager;

public NestedScrollableHost(@NonNull Context context) {
super(context);
touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}

public NestedScrollableHost(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}

public NestedScrollableHost(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}

public NestedScrollableHost(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);

View parentView = (View) getParent();
while (parentView!=null && !(parentView instanceof ViewPager2))
{
parentView = (View) parentView.getParent();
}
parentPager = (ViewPager2) parentView;

if(getChildCount()>0) childPager = (ViewPager2) getChildAt(0);
}

private boolean canChildScroll(int orientation, float delta) {
int direction = (int) -Math.signum(delta);
switch (orientation)
{
case 0:
return childPager.canScrollHorizontally(direction);
case 1:
return childPager.canScrollVertically(direction);
}
return false;
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if(parentPager!=null && childPager!=null)
{
int orientation = parentPager.getOrientation();
boolean isHorizontal = orientation==ViewPager2.ORIENTATION_HORIZONTAL;
if(canChildScroll(orientation,-1f) || canChildScroll(orientation,1f))
{
if(ev.getAction()==MotionEvent.ACTION_DOWN)
{
initialX = ev.getX();
initialY = ev.getY();
getParent().requestDisallowInterceptTouchEvent(true);
}
else if(ev.getAction()==MotionEvent.ACTION_MOVE)
{
float dx = ev.getX() - initialX;
float dy = ev.getY() - initialY;
float scaleDx = Math.abs(dx) * ( isHorizontal ? 0.5f : 1f);
float scaleDy = Math.abs(dy) * ( isHorizontal ? 1f : 0.5f);
if(scaleDx>touchSlop || scaleDy>touchSlop)
{
if( isHorizontal == (scaleDy>scaleDx) )
{
getParent().requestDisallowInterceptTouchEvent(false);
}
else
{
getParent().requestDisallowInterceptTouchEvent(canChildScroll(orientation,isHorizontal ? dx : dy));
}
}
}
}
}
return super.onInterceptTouchEvent(ev);
}
}