forked from upstream-mirrors/OpenTracks
ViewPager migrate to ViewPager2. Fixes #522.
Swiping between tabs work. Fixes #105.
This commit is contained in:
@@ -22,11 +22,14 @@ import android.util.Log;
|
|||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewParent;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
import androidx.fragment.app.FragmentPagerAdapter;
|
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||||
|
|
||||||
|
import com.google.android.material.tabs.TabLayoutMediator;
|
||||||
|
|
||||||
import de.dennisguse.opentracks.content.TrackDataHub;
|
import de.dennisguse.opentracks.content.TrackDataHub;
|
||||||
import de.dennisguse.opentracks.content.data.Marker;
|
import de.dennisguse.opentracks.content.data.Marker;
|
||||||
@@ -75,8 +78,10 @@ public class TrackRecordedActivity extends AbstractListActivity implements Confi
|
|||||||
|
|
||||||
trackDataHub = new TrackDataHub(this);
|
trackDataHub = new TrackDataHub(this);
|
||||||
|
|
||||||
viewBinding.trackDetailActivityViewPager.setAdapter(new CustomFragmentPagerAdapter(getSupportFragmentManager(), FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT));
|
CustomFragmentPagerAdapter pagerAdapter = new CustomFragmentPagerAdapter(this);
|
||||||
viewBinding.trackDetailActivityTablayout.setupWithViewPager(viewBinding.trackDetailActivityViewPager);
|
viewBinding.trackDetailActivityViewPager.setAdapter(pagerAdapter);
|
||||||
|
new TabLayoutMediator(viewBinding.trackDetailActivityTablayout, viewBinding.trackDetailActivityViewPager,
|
||||||
|
(tab, position) -> tab.setText(pagerAdapter.getPageTitle(position))).attach();
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
viewBinding.trackDetailActivityViewPager.setCurrentItem(savedInstanceState.getInt(CURRENT_TAB_TAG_KEY));
|
viewBinding.trackDetailActivityViewPager.setCurrentItem(savedInstanceState.getInt(CURRENT_TAB_TAG_KEY));
|
||||||
}
|
}
|
||||||
@@ -220,20 +225,15 @@ public class TrackRecordedActivity extends AbstractListActivity implements Confi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CustomFragmentPagerAdapter extends FragmentPagerAdapter {
|
private class CustomFragmentPagerAdapter extends FragmentStateAdapter {
|
||||||
|
|
||||||
public CustomFragmentPagerAdapter(@NonNull FragmentManager fm, int behavior) {
|
public CustomFragmentPagerAdapter(@NonNull FragmentActivity fa) {
|
||||||
super(fm, behavior);
|
super(fa);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCount() {
|
|
||||||
return 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Fragment getItem(int position) {
|
public Fragment createFragment(int position) {
|
||||||
switch (position) {
|
switch (position) {
|
||||||
case 0:
|
case 0:
|
||||||
return StatisticsRecordedFragment.newInstance(trackId);
|
return StatisticsRecordedFragment.newInstance(trackId);
|
||||||
@@ -249,6 +249,10 @@ public class TrackRecordedActivity extends AbstractListActivity implements Confi
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
public CharSequence getPageTitle(int position) {
|
public CharSequence getPageTitle(int position) {
|
||||||
switch (position) {
|
switch (position) {
|
||||||
case 0:
|
case 0:
|
||||||
|
|||||||
@@ -13,8 +13,10 @@ import android.view.WindowManager;
|
|||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
import androidx.fragment.app.FragmentPagerAdapter;
|
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||||
|
|
||||||
|
import com.google.android.material.tabs.TabLayoutMediator;
|
||||||
|
|
||||||
import de.dennisguse.opentracks.content.TrackDataHub;
|
import de.dennisguse.opentracks.content.TrackDataHub;
|
||||||
import de.dennisguse.opentracks.content.data.Track;
|
import de.dennisguse.opentracks.content.data.Track;
|
||||||
@@ -148,8 +150,10 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
|
|||||||
trackRecordingServiceConnection = new TrackRecordingServiceConnection(bindChangedCallback);
|
trackRecordingServiceConnection = new TrackRecordingServiceConnection(bindChangedCallback);
|
||||||
trackDataHub = new TrackDataHub(this);
|
trackDataHub = new TrackDataHub(this);
|
||||||
|
|
||||||
viewBinding.trackDetailActivityViewPager.setAdapter(new CustomFragmentPagerAdapter(getSupportFragmentManager(), FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT));
|
CustomFragmentPagerAdapter pagerAdapter = new CustomFragmentPagerAdapter(this);
|
||||||
viewBinding.trackDetailActivityTablayout.setupWithViewPager(viewBinding.trackDetailActivityViewPager);
|
viewBinding.trackDetailActivityViewPager.setAdapter(pagerAdapter);
|
||||||
|
new TabLayoutMediator(viewBinding.trackDetailActivityTablayout, viewBinding.trackDetailActivityViewPager,
|
||||||
|
(tab, position) -> tab.setText(pagerAdapter.getPageTitle(position))).attach();
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
viewBinding.trackDetailActivityViewPager.setCurrentItem(savedInstanceState.getInt(CURRENT_TAB_TAG_KEY));
|
viewBinding.trackDetailActivityViewPager.setCurrentItem(savedInstanceState.getInt(CURRENT_TAB_TAG_KEY));
|
||||||
}
|
}
|
||||||
@@ -358,20 +362,15 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
|
|||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CustomFragmentPagerAdapter extends FragmentPagerAdapter {
|
private class CustomFragmentPagerAdapter extends FragmentStateAdapter {
|
||||||
|
|
||||||
public CustomFragmentPagerAdapter(@NonNull FragmentManager fm, int behavior) {
|
public CustomFragmentPagerAdapter(@NonNull FragmentActivity fa) {
|
||||||
super(fm, behavior);
|
super(fa);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCount() {
|
|
||||||
return 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Fragment getItem(int position) {
|
public Fragment createFragment(int position) {
|
||||||
switch (position) {
|
switch (position) {
|
||||||
case 0:
|
case 0:
|
||||||
return StatisticsRecordingFragment.newInstance();
|
return StatisticsRecordingFragment.newInstance();
|
||||||
@@ -387,6 +386,10 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
public CharSequence getPageTitle(int position) {
|
public CharSequence getPageTitle(int position) {
|
||||||
switch (position) {
|
switch (position) {
|
||||||
case 0:
|
case 0:
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import android.view.GestureDetector;
|
|||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.ScaleGestureDetector;
|
import android.view.ScaleGestureDetector;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewParent;
|
||||||
import android.widget.Scroller;
|
import android.widget.Scroller;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
@@ -117,6 +118,14 @@ public class ChartView extends View {
|
|||||||
private boolean reportSpeed = true;
|
private boolean reportSpeed = true;
|
||||||
private boolean showPointer = false;
|
private boolean showPointer = false;
|
||||||
|
|
||||||
|
// To handle disallow intercept touch event in parent.
|
||||||
|
private static final int SCROLL_X_NONE = 0;
|
||||||
|
private static final int SCROLL_X_LEFT = 1;
|
||||||
|
private static final int SCROLL_X_RIGHT = 2;
|
||||||
|
private boolean isOnLeftEdge = true;
|
||||||
|
private boolean isOnRightEdge = true;
|
||||||
|
private int scrollXDirection = SCROLL_X_NONE;
|
||||||
|
|
||||||
private final GestureDetectorCompat detectorScrollFlingTab = new GestureDetectorCompat(getContext(), new GestureDetector.SimpleOnGestureListener() {
|
private final GestureDetectorCompat detectorScrollFlingTab = new GestureDetectorCompat(getContext(), new GestureDetector.SimpleOnGestureListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -129,6 +138,14 @@ public class ChartView extends View {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
|
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
|
||||||
|
if (distanceX < 0) {
|
||||||
|
scrollXDirection = SCROLL_X_LEFT;
|
||||||
|
} else if (distanceX > 0) {
|
||||||
|
scrollXDirection = SCROLL_X_RIGHT;
|
||||||
|
} else {
|
||||||
|
scrollXDirection = SCROLL_X_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
if (Math.abs(distanceX) > 0) {
|
if (Math.abs(distanceX) > 0) {
|
||||||
int availableToScroll = effectiveWidth * (zoomLevel - 1) - getScrollX();
|
int availableToScroll = effectiveWidth * (zoomLevel - 1) - getScrollX();
|
||||||
if (availableToScroll > 0) {
|
if (availableToScroll > 0) {
|
||||||
@@ -434,6 +451,9 @@ public class ChartView extends View {
|
|||||||
chartPoints.clear();
|
chartPoints.clear();
|
||||||
xExtremityMonitor.reset();
|
xExtremityMonitor.reset();
|
||||||
zoomLevel = 1;
|
zoomLevel = 1;
|
||||||
|
isOnLeftEdge = true;
|
||||||
|
isOnRightEdge = true;
|
||||||
|
scrollXDirection = SCROLL_X_NONE;
|
||||||
updateDimensions();
|
updateDimensions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -500,6 +520,18 @@ public class ChartView extends View {
|
|||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle parent's view disallow touch event.
|
||||||
|
*
|
||||||
|
* @param disallow Does disallow parent touch event?
|
||||||
|
*/
|
||||||
|
private void requestDisallowInterceptTouchEventInParent(boolean disallow) {
|
||||||
|
ViewParent parent = getParent();
|
||||||
|
if (parent != null) {
|
||||||
|
parent.requestDisallowInterceptTouchEvent(disallow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scrolls the view horizontally by a given amount.
|
* Scrolls the view horizontally by a given amount.
|
||||||
*
|
*
|
||||||
@@ -507,13 +539,21 @@ public class ChartView extends View {
|
|||||||
*/
|
*/
|
||||||
private void scrollBy(int deltaX) {
|
private void scrollBy(int deltaX) {
|
||||||
int scrollX = getScrollX() + deltaX;
|
int scrollX = getScrollX() + deltaX;
|
||||||
if (scrollX < 0) {
|
if (scrollX <= 0) {
|
||||||
scrollX = 0;
|
scrollX = 0;
|
||||||
|
isOnLeftEdge = true;
|
||||||
|
} else {
|
||||||
|
isOnLeftEdge = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int maxWidth = effectiveWidth * (zoomLevel - 1);
|
int maxWidth = effectiveWidth * (zoomLevel - 1);
|
||||||
if (scrollX > maxWidth) {
|
if (scrollX >= maxWidth) {
|
||||||
scrollX = maxWidth;
|
scrollX = maxWidth;
|
||||||
|
isOnRightEdge = true;
|
||||||
|
} else {
|
||||||
|
isOnRightEdge = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollTo(scrollX, 0);
|
scrollTo(scrollX, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -538,6 +578,15 @@ public class ChartView extends View {
|
|||||||
public boolean onTouchEvent(MotionEvent event) {
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
boolean isZoom = detectorZoom.onTouchEvent(event);
|
boolean isZoom = detectorZoom.onTouchEvent(event);
|
||||||
boolean isScrollTab = detectorScrollFlingTab.onTouchEvent(event);
|
boolean isScrollTab = detectorScrollFlingTab.onTouchEvent(event);
|
||||||
|
|
||||||
|
if (event.getPointerCount() == 1 && ((isOnLeftEdge && scrollXDirection == SCROLL_X_LEFT) || (isOnRightEdge && scrollXDirection == SCROLL_X_RIGHT))) {
|
||||||
|
// Focus on view's parent.
|
||||||
|
requestDisallowInterceptTouchEventInParent(false);
|
||||||
|
} else {
|
||||||
|
// Focus on ChartView.
|
||||||
|
requestDisallowInterceptTouchEventInParent(true);
|
||||||
|
}
|
||||||
|
|
||||||
return isZoom || isScrollTab;
|
return isZoom || isScrollTab;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
<androidx.viewpager.widget.ViewPager
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
android:id="@+id/track_detail_activity_view_pager"
|
android:id="@+id/track_detail_activity_view_pager"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ limitations under the License.
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
<androidx.viewpager.widget.ViewPager
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
android:id="@+id/track_detail_activity_view_pager"
|
android:id="@+id/track_detail_activity_view_pager"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
<androidx.viewpager.widget.ViewPager
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
android:id="@+id/track_detail_activity_view_pager"
|
android:id="@+id/track_detail_activity_view_pager"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
|
|||||||
Reference in New Issue
Block a user