How do i detect if i have clicked or press at right side of viewPager or at left side of viewPager.
I have tried with GestureDetector but couldn't make it out.
Help me
Use the GestureDetector to get SingleTapConfirmed Action
#Override
public boolean onSingleTapConfirmed(MotionEvent e) {
float x=e.getX()
if(x < ( getWidth() * 0.5 )){
//also check if item we set if valid or not i.e (getCurrentItem() - 1) > 0
setCurrentItem( getCurrentItem() - 1)
}else{
//also check if item we set if valid or not i.e (getCurrentItem() + 1) < maxChildCount
setCurrentItem( getCurrentItem() + 1)
}
return true;
}
add this code in your custom ViewPager
Related
I have a list View in my Main Activity, which contains a list of full size images. i am trying to implement onTouchListener on that image view of list view to get the points where user touched. and i am getting it correct by implementing onTouchListener in get View method of Custom Adapter for list view. but when i touch screen for scrolling list it still gives me the points while scrolling the list. but i don't want to get onTouchListener called while scrolling the list. How can i do this.
you may try this, this might work
float posX, posY;
imageView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN){
posX = event.getX();
posY = event.getY();
}
if (event.getAction() == MotionEvent.ACTION_UP){
if (((posX >= event.getX() && posX <= event.getX() + 10) || (posX <= event
.getX() && posX >= event.getX() - 10))
&& ((posY >= event.getY() && posY <= event.getY() + 10) || (posY <= event
.getY() && posY >= event.getY() - 10))){
//Do your thing
}
}
return true;
}
});
I think the proper way to do this is by implementing onClickListener instead of onTouchListener.
And yes, the very reason is because the View will be touched when the user only intent to scroll the ListView.
override this method and done with respect to your requirement.
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (isScrooling) {
return super.onInterceptTouchEvent(ev);
} else {
return false;
}
}
i'm using viewpagerIndicator in my app, i have 200 pages. is possible disable the Swipe 1 page before the last page?
Example my currentpage is the 199 here the swipe is disble and never change to the next page, only the previous pages.
EDIT: i have one calendar in the Tabindicator, the pages show info for day, i need show the next day but not swipe because not exist info for this reason i need disable this page.
Exam:
19/ago/2014 | 20/ago/2014 | 21/ago/2014
before |Current |Last Page
in before i can swipe left and right but in Current i need only swipe left and disable right is possible?
You can return 199 from getCount() from adapter that way viewpager will not know there are 200 pages.
EDIT:
Well In that case, you have to override viewpager and manually disable the motion when viewpager is showing second last page.
It would look something like this
First extend : class CustomViewPager extends ViewPager {...}
float lastX;
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if(getCurrentItem() == getAdapter().getCount()-1){
if(ev.getAction() == MotionEvent.ACTION_DOWN){
lastX = ev.getX();
// Just touch down let viewpager also handle touch event
return super.onInterceptTouchEvent(event);
}
else if(ev.getAction() == MotionEvent.ACTION_MOVE){
float xDiff = ev.getX() - lastX;
if(xDiff > 0){
// Attempt to move right on second last page
// Return false, we dont want to handle this movement
return false;
}
else{
// Left you can move
return super.onInterceptTouchEvent(event);
}
}
// Notice that we are not updating lastX on motion towards left
// This is to enable user can swipe towards left a bit and comeback, but dont dare go right
}
else{
// Not on second last page let viewpager handle page event
return super.onInterceptTouchEvent(event);
}
}
Solution-1: By specifying a very large number as the actual count, but maps them to the actual range of the dataset/pageset
ViewPager as a circular queue / wrapping
Problem: It doesn't work if there are less than 4 items.
Solution-2 Adding 2 extra items i.e. last item in the first and first item in the last and onPageSelected, depending on the position values, set the current item
Implementing Circular Scrolling In PagerAdapter
Problem: Extra pager indicators and extra fragment instances.
Solution-3: Using the onTouchListener on ViewPager
Implementing Circular Scrolling In PagerAdapter
Problem: The first MotionEvent is always null. Is it because of the ViewPager's own onTouchListener implementation?
Is there a proper solution for this?
Or even if the 3rd solution works fine, it would be great.
I use a combination of Solution 2 and Solution 3, I use the on touch listener of the pager to watch for swipes and see if I need to show the copy of the first or last page based on the current page
example:
mPager.setOnTouchListener(new OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN){
dxInitial=event.getX();
//
}else if(event.getAction() == MotionEvent.ACTION_MOVE){
//
if(event.getX() - dxInitial > 50 && currentPage==1){
}else if(dxInitial - event.getX() > 50 && currentPage==5){
mPager.setCurrentItem(0,false);
}else if(dxInitial - event.getX() > 50 && currentPage==6){
mPager.setCurrentItem(1,false);
}else if(event.getX() - dxInitial > 50 && currentPage==0){
mPager.setCurrentItem(5,false);
}else if(event.getX() - dxInitial > 100 && currentPage==6){
//
mPager.setCurrentItem(1,false);
}
}
return false;
}
});
you have extra pager indicators but the user should never see or notice them, just set smoothScroll to false when you change the page
I have a ViewPager of images, and I want to make it slide in the following way:
If I click on the right (left) side of the screen, go to previous (next) image. It's like the screen is two halves and each half moves to a direction on click.
How can I implement this?
You can get Disaplay width
Then you can override onTouchEvent in your viewpager.
When you get MotionEvent object - you can get 'tap' coordinates and you will be able to understand on wich side of screen user clicked and handle it.
Set on touch listener for your ViewPager or contentview of ViewPager item.
Take the half of the screen/view width, check if event.getX() is greater than the half value, if so, go to next, otherwise to the previous.
#Override
public boolean onTouch(View v, MotionEvent ev) {
if(ev.getAction() == MotionEvent.ACTION_DOWN){
mDownX = ev.getX();
mDownY = ev.getY();
isOnClick = true;
}else if(ev.getAction() == MotionEvent.ACTION_UP ){
if (isOnClick ) {
if(ev.getX() > mViewPager.getWidth()/2) {
//go to next
}else{
//go to previous
}
return true;
}
}else if(ev.getAction() == MotionEvent.ACTION_MOVE){
if (isOnClick && (Math.abs(mDownX - ev.getX()) > DRAG_THRESHOLD || Math.abs(mDownY - ev.getY()) > DRAG_THRESHOLD)) {
isOnClick = false;
return false;
}
}
return false
}
I have an achartengine GraphicalView chart inside a android.support.v4.view.ViewPager.
I want my chart to pan when the user drags her finger on it, but now the event is being caught by the ViewPager after a small drag movement.
Preferably, I would like to be able to let the user pan to the end of the chart and then let the ViewPager switch pages.
As an alternative, I would like to at least stop the ViewPager from catching the drag movement inside the chart.
Any ideas?
Here goes my solution.
It allows the user to drag the graph around while there is data in it. After that, the drag events are caught by the ViewPager.
Like I said, the key is this solution is the requestDisallowInterceptTouchEvent function.
public class ParameterGraphicalView extends org.achartengine.GraphicalView {
// stores the data model size
private int mDataSize = 0;
// stores the first X position in the dataset
private long mDataStartX = 0;
// stores the last X position in the dataset
private long mDataEndX = 0;
// the ViewPager
private ViewParent mViewPager;
//(...)
#Override
public boolean onTouchEvent(MotionEvent event) {
// save the position of the first touch so we can determine whether the user is dragging
// left or right
if (event.getAction() == MotionEvent.ACTION_DOWN) {
mFirstTouchX = event.getX();
}
// when mViewPager.requestDisallowInterceptTouchEvent(true), the viewpager does not
// intercept the events, and the drag events (pan, pinch) are caught by the GraphicalView
// we want to keep the ViewPager from intercepting the event if:
// 1- there are 2 or more touches, i.e. the pinch gesture
// 2- the user is dragging to the left but there is no data to show to the right
// 3- the user is dragging to the right but there is no data to show to the left
if (event.getPointerCount() > 1
|| (event.getX() < mFirstTouchX && mDataSize > 0 && mRenderer.getXAxisMax() < mDataEndX)
|| (event.getX() > mFirstTouchX && mData.size() > 0 && mRenderer.getXAxisMin() > mDataStartX)) {
mViewPager.requestDisallowInterceptTouchEvent(true);
}
else {
mViewPager.requestDisallowInterceptTouchEvent(false);
}
return super.onTouchEvent(event);
}
}
I think you should Implement your own ViewPager and handle Touch event yourself.
Maybe this Link helps you : how to disable viewpager adapter on touching specific views?