Android tab behavior - android

I am designing tab view like feature, but i need one more functionality.
Suppose i have three tabs,
And if press tab2 - Content of second tab will show
tab3 -- Content of Third will show
tab1 - content of tab1 will show
and by default tab1 will be selected. and this is working fine.
Now, i need when i am scrooling the content of tab1, i need to show cotent of second tab too ( But second tab should be selected).. Just like single page application on web..
I don't need Web view. Anybody guide me how to achieve this, or if there is any sample code available on github. Please
Thanks

#AnkitaKashyap sorry mate, I kept forgot, here is your snippet code (in kotlin) if you need help, pls send me a private msg,if i got your idea correctly, here is what you want gif demo:
using a tabbar with recyclerview and set addOnTabSelectedListener:
productTabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener{
override fun onTabReselected(tab: TabLayout.Tab?) {
}
override fun onTabUnselected(tab: TabLayout.Tab?) {
}
override fun onTabSelected(tab: TabLayout.Tab?) {
productRv.scrollToPosition(tab?.position?:0)
}
})
and set in your recyclerview :
productRv.addOnScrollListener(object : RecyclerView.OnScrollListener(){
override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
var scrollPosition = layoutManager.findFirstVisibleItemPosition()
productTabs.getTabAt(scrollPosition)?.select()
}
override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
}
})

You need to go with VerticalViewPager as shown in this StackOverflow post and use TabLayout along with it.
Code from the given SO link:
/**
* Uses a combination of a PageTransformer and swapping X & Y coordinates
* of touch events to create the illusion of a vertically scrolling ViewPager.
*
* Requires API 11+
*
*/
public class VerticalViewPager extends ViewPager {
public VerticalViewPager(Context context) {
super(context);
init();
}
public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
// The majority of the magic happens here
setPageTransformer(true, new VerticalPageTransformer());
// The easiest way to get rid of the overscroll drawing that happens on the left and right
setOverScrollMode(OVER_SCROLL_NEVER);
}
private class VerticalPageTransformer implements ViewPager.PageTransformer {
#Override
public void transformPage(View view, float position) {
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 1) { // [-1,1]
view.setAlpha(1);
// Counteract the default slide transition
view.setTranslationX(view.getWidth() * -position);
//set Y position to swipe in from top
float yPosition = position * view.getHeight();
view.setTranslationY(yPosition);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
/**
* Swaps the X and Y coordinates of your touch event.
*/
private MotionEvent swapXY(MotionEvent ev) {
float width = getWidth();
float height = getHeight();
float newX = (ev.getY() / height) * width;
float newY = (ev.getX() / width) * height;
ev.setLocation(newX, newY);
return ev;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev){
boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
swapXY(ev); // return touch coordinates to original reference frame for any child views
return intercepted;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(swapXY(ev));
}
}

Related

Making ViewPager + WebView swipe vertical in continuous way

I'm writing a html page reader, cant load all .html because its huge and performance is bad, so I decided to split it into 3(or more) html and load that inside Web View nested with View Pager (swipe vertically)
My problem is that I should swipe slowly to scroll the web view and swipe fast to change view pager
Slow swiping
fast swipe change the Page on ViewPager
1) Can i expand webview to all its content heigh inside viewpager ?
2) Can change viewpager item only when topScroll or endScroll?
what i've tried so far:
CustomWebView
#Override
public boolean onTouchEvent(MotionEvent event) {
requestDisallowInterceptTouchEvent(true);
return super.onTouchEvent(event);
}
worked but was unable to change viewpager item
so i though about enable/disable it when i get to the top or to the end
removed webview onTouchEvent and added:
#Override
protected void onScrollChanged(final int l, final int t, final int oldl, final int oldt) {
requestDisallowInterceptTouchEvent(true);
int height = (int) Math.floor(this.getContentHeight() * this.getScale());
int webViewHeight = this.getMeasuredHeight();
boolean scrollTop = this.getTop() == t;
boolean scrollEnd = this.getScrollY() + webViewHeight >= height;
if(scrollTop || scrollEnd) {
requestDisallowInterceptTouchEvent(false);
}
worked randomly, the most common thing is that when i change page, i must scroll down and scroll up to trigger the requestDisallow to false so i can change page =[
Vertical CustomViewPage is this one ->
public class VerticalViewPager extends ViewPager {
public VerticalViewPager(Context context) {
super(context);
init();
}
public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
// The majority of the magic happens here
setPageTransformer(true, new VerticalPageTransformer());
// The easiest way to get rid of the overscroll drawing that happens on the left and right
setOverScrollMode(OVER_SCROLL_NEVER);
}
private class VerticalPageTransformer implements ViewPager.PageTransformer {
#Override
public void transformPage(View view, float position) {
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 1) { // [-1,1]
view.setAlpha(1);
// Counteract the default slide transition
view.setTranslationX(view.getWidth() * -position);
//set Y position to swipe in from top
float yPosition = position * view.getHeight();
view.setTranslationY(yPosition);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
/**
* Swaps the X and Y coordinates of your touch event.
*/
private MotionEvent swapXY(MotionEvent ev) {
float width = getWidth();
float height = getHeight();
float newX = (ev.getY() / height) * width;
float newY = (ev.getX() / width) * height;
ev.setLocation(newX, newY);
return ev;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev){
boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
swapXY(ev); // return touch coordinates to original reference frame for any child views
return intercepted;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(swapXY(ev));
}
}
1st i think it's a bad idea to split your content into 3 different HTML files and putting them on 3 different WebViews.
3 fils can be a good idea but 3 WebView in 3 Views of ViewPager is a bad idea.
Instead, you should detect top and bottom of the webpage using ".js" / "jQuery" and route page/HTML within same WebView.
window.onscroll = function(ev) {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
// you're at the bottom of the page
}};
There are many ways to detect TOP and BOTTOM of your HTML content.
Still, if you want to increase the height of your review to content height use
Getting WebView Content height once its loaded Android it worked for me.

Scrolling behaviour: HorizontalScrollView inside ViewPager

I have a View Pager (VP) which contains a Horizontal Scroll View (HSV). If the HSV reaches one of its edges or is not able to scroll at all, on a new swipe in the blocked direction VP should take over scrolling to the next page. I hesitated to ask this question because I found similar ones like these:
Can I use Horizontal Scrollview Inside a Viewpager in Android?
or
horizontalscrollview inside viewpager
But the solution did not work for me. 'v instanceof HorizontalScrollView' gets true but viewPager does not scroll
Any other ideas how to achieve the desired behaviour?
public class MyViewPager extends ViewPager {
public MyViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
// Update 1
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return true;
//return super.onInterceptTouchEvent(ev);
}
/**
* https://stackoverflow.com/questions/22781496/can-i-use-horizontal-scrollview-inside-a-viewpager-in-android
*/
#Override
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
if (v instanceof HorizontalScrollView) {
return true;
}
return super.canScroll(v, checkV, dx, x, y);
}
}
child view: view_pager_page.xml:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">
<include layout="#layout/" />
</LinearLayout>
</HorizontalScrollView>
</LinearLayout>
</FrameLayout>
</RelativeLayout>
parent view: view_pager.xml
<android.support.design.widget.CoordinatorLayout>
...
<LinearLayout>
<packagepath.MyViewPager
android:layout_width="match_parent"
android:layout_height="wrap_content">
</packagepath.MyViewPager>
</LinearLayout>
...
<android.support.design.widget.CoordinatorLayout>
Update 1: When overriding 'onInterceptTouchEvent' and let it always return true VP scrolls, but HSV doesn't. I think this must return true only if HSV reaches edges right? How can I figure out in this method if it is the case?
Update 2: I reconstructed the touch event mechanism of android hoping to get some insight of how to intercept the motion event flow. E.g. in HSV I can simply return false to let VP consume this and all subsequent motion events. Unfortunately I need two motion events of type MotionEvent.MOVE to decide if HSV or VP should scroll when reaching an edge (if HSV has reached right edge, a right swipe scrolls HSV back and a left swipe scrolls to next page of VP). But if I skip the MotionEvent.DOWN action neither HSV or VP starts scrolling... so hard to solve. Any ideas?
Touchevent Mechanism in Android
(Warning: Graphic is not complete and will contain mistakes, everyone is invited to correct it :-))
Update 3: Finally I got it working. Understanding the Touchevent mechanism helped a lot and also the first comment of ZeroOne. I will post my solution when I have time for it.
I solved this with a custom HorizontalScrollView. The key is to override the onTouchEvent() method and return false if you are at the left edge and swiping right, or the right edge and swiping left. Returning false means this view didn't consume the touch event and this event can bubble back up the view hierarchy to be handled by the ViewPager.
public class HorizontalScrollViewForViewPager extends HorizontalScrollView {
float old_x, old_y;
public HorizontalScrollViewForViewPager(Context context) {
super(context);
}
public HorizontalScrollViewForViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
public HorizontalScrollViewForViewPager(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
int action = ev.getActionMasked();
if (action == MotionEvent.ACTION_DOWN) {
//Start of touch. Could be tap, could be drag.
old_x = ev.getX();
old_y = ev.getY();
} else if (action == MotionEvent.ACTION_MOVE) {
//Drag movement underway
float deltaX = ev.getX() - old_x;
float deltaY = ev.getY() - old_y;
if (Math.abs(deltaX) > Math.abs(deltaY)) {
//scrolling more left/right than up/down
if (deltaX > 0 && getScrollX() == 0) {
//dragging left, at left edge of HorizontalScrollView. Don't handle this touch event, let it bubble up to ViewPager
return false;
} else {
//dragging right. Use first child to determine width of content inside HorizontalScrollView
int childWidth = getChildAt(0).getWidth();
if (deltaX < 0 && (this.getScrollX() + this.getWidth()) >= childWidth) {
//swiping left, and at right edge of HorizontalScrollView. Don't handle this touch event, let it bubble up to ViewPager
return false;
}
}
}
}
return super.onTouchEvent(ev);
}
}
1.Extend ViewPager Class:
public class ViewPagerContainingHorizontalScrollView extends ViewPager {
private Float x_old;
private boolean bDoIntercept = false;
private boolean bHsvRightEdge = false;
private boolean bHsvLeftEdge = true;
public ViewPagerContainingHorizontalScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
private float calculateDistanceSwipe(MotionEvent ev){
float distance = 0;
if (x_old == null) {
x_old = ev.getX();
} else {
distance = ev.getX() - x_old;
x_old = null;
}
return distance;
}
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
mDoIntercept = false;
if(ev.getAction() == MotionEvent.ACTION_MOVE) {
float distance = calculateDistanceSwipe(ev);
if (distance < 0) {//scrolling left direction
if (bHsvRightEdge) { //HSV right edge
bDoIntercept = true;
//When scrolling slow VP may not switch page.
//Then HSV snaps back into old position.
//To allow HSV to scroll into non blocked direction set following to false.
bHsvRightEdge = false;
}
bHsvLeftEdge = false;//scrolling left means left edge not reached
} else if (distance > 0) {//scrolling right direction
if (bHsvLeftEdge) { //HSV left edge
bDoIntercept = true;
//When scrolling slow VP may not switch page.
//Then HSV snaps back into old position.
//To allow HSV to scroll into non blocked direction set following to false.
bHsvLeftEdge = false;
}
bHsvRightEdge = false;//scrolling right means right edge not reached
}
}
return super.dispatchTouchEvent(ev);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if(bDoIntercept){
return true;
}else{
return super.onInterceptTouchEvent(ev);
}
}
#Override
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
if (v instanceof HorizontalScrollView) {
HorizontalScrollView hsv = (HorizontalScrollView) v;
int max_scrollX = hsv.getChildAt(0).getWidth() - hsv.getWidth();
int min_scrollX = 0;
int current_scroll_x = hsv.getScrollX();
if (current_scroll_x == max_scrollX) { //HSV right edge
bHsvRightEdge = true;
}
if (current_scroll_x == min_scrollX) { //HSV left edge
bHsvLeftEdge = true;
}
return true;
}
return super.canScroll(v, checkV, dx, x, y);
}
}
Use this custom VP in XML.
Enjoy nested HSV scrolling in VP :-)
Touch Event Mechanism Overview for this specific case

Disable viewpager when touching/dragging certain view

Using something similar to the answer of this question, I've tried to disable the ViewPager swipe action for when the user is swiping over a particular item. The view in question is a scrollable chart from the MPAndroidChart library, so naturally I don't want the view pager interfering with the scrolling of the chart.
The issue I am having is that the ViewPager will often have "onInterceptTouch" invoked before the onTouchListener is invoked on my desired view.
In this segment of code, I'm recording when the view is pressed/unpressed:
private long lastDown;
private long lastUp;
...
public void foo(){
barChart.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
System.out.println("AAA");
if(event.getAction() == MotionEvent.ACTION_DOWN){
lastDown = System.currentTimeMillis();
}else if(event.getAction() == MotionEvent.ACTION_UP){
lastUp = System.currentTimeMillis();
}
return false;
}
});
}
In this segment of code, I determine if the view is selected:
public boolean isGraphTouched(){
return lastDown > lastUp;
}
And in this segment of code I'm overriding the onInterceptTouchEvent method:
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
System.out.println("BBB");
return isGraphSelected() ? super.onInterceptTouchEvent(ev) : false;
}
And if you take note of the printlines, the onInterceptTouchEvent method is called before...
The only way I can think of getting around this is to make a method which checks if the graph exists at the coordinates of the motion event (although I'm not sure if this is even possible) and then use that to determine if the pager will be swipable or not.
I managed to make it work using the function parent.requestDisallowInterceptTouchEvent(true); being placed inside the child view onTouchEvent(). This way the View does not allow none of his parents to interecpt his touch events in case a scroll happened and was to be handled by the ViewPager.
However in my case I had a ViewPager with a draggable custom views inside it which I wanted to move without that the ViewPager changes page.
My solution in terms of code: (Kotlin)
view.setOnTouchListener { v, event ->
parent.requestDisallowInterceptTouchEvent(true);
//Drag and drop handling is here and the rest of the event logic
}
I hope this will help you as well.
I've managed to solve my problem by incorporating this answer from another post. The code allows you to get the coordinates of a given view and compare them to your own coordinates.
Inside of my CustomViewPager class, I implemented what I mentioned above:
private boolean isPointInsideView(float x, float y, View view) {
int location[] = new int[2];
view.getLocationOnScreen(location);
int viewX = location[0];
int viewY = location[1];
return ((x > viewX && x < (viewX + view.getWidth())) && (y > viewY && y < (viewY + view.getHeight())));
}
I then had a method which returns a boolean, which checks a couple of conditions and returns true/false on if the pager should be able to be swiped:
public boolean canSwipe(float x, float y) {
boolean canSwipe = true;
if (launchActivity.isReady(MainScreenPagerAdapter.STAT_PAGE)) {
FragmentStatistics fragmentStatistics = (FragmentStatistics) launchActivity.getPageAdapter().instantiateItem(this, MainScreenPagerAdapter.STAT_PAGE);
View chart = fragmentStatistics.getView().findViewById(R.id.chart);
canSwipe = !isPointInsideView(x, y, chart) || !fragmentStatistics.isGraphPannable();
}
return canSwipe;
}
And then, of course, I overwrote the onInterceptTouchEvent like so:
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return canSwipe(ev.getX(), ev.getY()) ? super.onInterceptTouchEvent(ev) : false;
}
And now, the graph can be fully panned without the Pager interfering with it at all.
Full CustomViewPager code:
public class CustomViewPager extends ViewPager {
/** Reference to the launch activity */
private LaunchActivity launchActivity;
/**
* Constructor to call the super constructor
*
* #param context The application context
* #param attrs The attributes
*/
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* Sets object reference for the {#code launchActivity}
*
* #param launchActivity The LaunchActivity to be set
*/
public void set(LaunchActivity launchActivity) {
this.launchActivity = launchActivity;
}
/**
* Determines if the pager can be swiped based off the x and y inputs provided, as well as if the
* barchart can be panned or not.
*
* #param x The x coordinate to check
* #param y The y coordinate to check
* #return True if the ViewPager will continue with normal swiping action.
*/
public boolean canSwipe(float x, float y) {
boolean canSwipe = true;
if (launchActivity.isReady(MainScreenPagerAdapter.STAT_PAGE)) {
FragmentStatistics fragmentStatistics = (FragmentStatistics) launchActivity.getPageAdapter().instantiateItem(this, MainScreenPagerAdapter.STAT_PAGE);
View chart = fragmentStatistics.getView().findViewById(R.id.chart);
canSwipe = !isPointInsideView(x, y, chart) || !fragmentStatistics.isGraphPannable();
}
return canSwipe;
}
/**
* Takes x and y coordinates and compares them to the coordinates of the passed view. Returns true if the passed coordinates
* are within the range of the {#code view}
*
* #param x The x coordinate to compare
* #param y The y coordinate to compare
* #param view The view to check the coordinates of
* #return True if the x and y coordinates match that of the view
*/
private boolean isPointInsideView(float x, float y, View view) {
int location[] = new int[2];
view.getLocationOnScreen(location);
int viewX = location[0];
int viewY = location[1];
// point is inside view bounds
return ((x > viewX && x < (viewX + view.getWidth())) && (y > viewY && y < (viewY + view.getHeight())));
}
/**
* Override of the onInterceptTouchEvent which allows swiping to be disabled when chart is selected
*
* #param ev The MotionEvent object
* #return Call to super if true, otherwise returns false
*/
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return canSwipe(ev.getX(), ev.getY()) ? super.onInterceptTouchEvent(ev) : false;
}
}

How to make cardView slide up and down animation in android?

I am building an android application similar to inshorts. I wanna to slide my cardView up and down. What I am doing yet - I am parsing the data from server using webAPI then using BaseAdapter displaying in cardView. But now I need on swipe up it should move up and next position card should be displayed .
You can do this with ViewPager and Fragments then you need to put slide animation with view pager. For horizontal slide you can see developers reference http://developer.android.com/training/animation/screen-slide.html.
After that you need to modify view pager slightly so that it behave like vertical instead of horizontal and you can achieve this with below code:
public class VerticalViewPager extends ViewPager {
public VerticalViewPager(Context context) {
super(context);
init();
}
public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
// The majority of the magic happens here
setPageTransformer(true, new VerticalPageTransformer());
// The easiest way to get rid of the overscroll drawing that happens on the left and right
setOverScrollMode(OVER_SCROLL_NEVER);
}
private class VerticalPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.75f;
#Override
public void transformPage(View view, float position) {
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 0) { // [-1,0]
// Use the default slide transition when moving to the left page
view.setAlpha(1);
// Counteract the default slide transition
view.setTranslationX(view.getWidth() * -position);
//set Y position to swipe in from top
float yPosition = position * view.getHeight();
view.setTranslationY(yPosition);
view.setScaleX(1);
view.setScaleY(1);
} else if (position <= 1) { // [0,1]
view.setAlpha(1);
// Counteract the default slide transition
view.setTranslationX(view.getWidth() * -position);
// Scale the page down (between MIN_SCALE and 1)
float scaleFactor = MIN_SCALE
+ (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
/**
* Swaps the X and Y coordinates of your touch event.
*/
private MotionEvent swapXY(MotionEvent ev) {
float width = getWidth();
float height = getHeight();
float newX = (ev.getY() / height) * width;
float newY = (ev.getX() / width) * height;
ev.setLocation(newX, newY);
return ev;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev){
boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
swapXY(ev); // return touch coordinates to original reference frame for any child views
return intercepted;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(swapXY(ev));
}
}
One way you can do this is by using fragments and ViewPager to load the pages, and you can specify Property Animation to animate the fragments.
If you are new to fragments, try beginning from here
And then you need ViewPager to swipe between pages. here
Property Animation is often used to animate native fragments(Android.App.Fragment) . see this
and see this to swap fragments using Animation

2 ViewPager not scrolling in Android 2.3

I am using Navigation Drawer in my app, that contains some Fragments just like in the below picture.
Every Fragment Contains another ViewPager that is an ImageSlider, and below that is a Listview and at the top I am using the SwipeRefreshLayout. My problem is the image slider works well on devices that has Android version 3.0 or higher but the swipe left or right doesn't works on devices 2.3 and lower, instead it invokes the Parent ViewPager's swipe that is it navigates the fragment. I am using support Version 4 library for this purpose to support devices lower than 3.0. All functions works quite well on 2.3 devices except that one. I have googled it but I haven't found any help anywhere. So to make it scroll what should I do for this, any idea/help will be highly appreciated.
You can use this ViewPager as your parent ViewPager. This allows the child ViewPager to scroll.
public class CustomViewPager extends ViewPager {
public CustomViewPager(Context context) {
super(context);
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
try {
//Handle the issue only in lower versions of android
if (v != this && v instanceof ViewPager && CJRAppCommonUtility.getOSVersion() < android.os.Build.VERSION_CODES.HONEYCOMB) {
ViewPager viewPager = (ViewPager) v;
int currentPage = viewPager.getCurrentItem();
int size = viewPager.getAdapter().getCount();
//if ViewPager has reached its end and if user tries to swipe left allow the parent to scroll
if (currentPage == (size - 1) && dx < 0) {
return false;
}
//if ViewPager has reached its start and if user tries to swipe right allow the parent to scroll
else if (currentPage == 0 && dx > 0) {
return false;
}
//Allow the child to scroll hence blocking parent scroll
else {
return true;
}
}
return super.canScroll(v, checkV, dx, x, y);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
Android developers site has a nice explanation about handling touch events in a Viewgroup. You can refer it here: http://developer.android.com/training/gestures/viewgroup.html
Hope it helps!!
In older version of Android requestDisallowInterceptTouchEvent doesn't work that great. The solution here is to extend view pager and override the onInterceptTouchEvent and store a list of children that are scrollable. Then, when onInterceptTouchEvent is called you can iterate through the list of scrollable children, get their hit rect, and see if the touch event is inside the hit rect. If it is, you can just return false to not handle it and let the child take it.
Something like this:
#Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
for (View view : scrollableChildren)
{
// get the hit rectangle for the view
Rect rect = new Rect();
view.getHitRect(rect);
// check to see if the click was inside this child
if (rect.contains((int) ev.getX(), (int) ev.getY()))
{
return false;
}
}
return super.onInterceptTouchEvent(ev);
}

Categories

Resources