I want to use a Screen slide but without swipe. I see this example: http://developer.android.com/training/animation/screen-slide.html , only i want slide pages with the top menu and not with the swipe.
How I can do it?
Thanks.
This is how I have implemented it. In this example I have a ViewPager with 3 items in the adapter and it swipes to the next item every 3 seconds. After it reaches the third item it goes back to the first position.
public class MainActivity extends AppCompatActivity {
private ViewPager viewPager;
int page = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_activity22);
viewPager = (ViewPager) findViewById(R.id.pager);
}
private void testing() {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
if (page == 3) {
page = 0;
}
viewPager.setCurrentItem(page++);
testing();
}
}, 3000); // 3 seconds
}
}
Disable Swipe
viewPager.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
You have to use "Swipe Views with Tabs". Here's how:
http://developer.android.com/training/implementing-navigation/lateral.html
Related
I have a ViewPager and I'm setting OnClickListener to it.
But the ViewPager is not detecting the on click. Whats wrong here ?
Code:
viewPager = (ViewPager) findViewById(R.id.pager);
ImagePagerAdapter adapter = new ImagePagerAdapter();
viewPager.setAdapter(adapter);
viewPager.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getBaseContext(), "view Pager Clicked", Toast.LENGTH_SHORT).show();
}
});
You can use setOnClickListener inside the adapter in instantiateItem method.
it works for me.
I understand you want to identify touch events on your ViewPager, so that you can trigger an animation that hides your ActionBar. One method requires you create your own subclass of ViewPager and override onInterceptTouchEvent:
public class ABetterViewPager extends ViewPager {
public ABetterViewPager(Context context) {
super(context);
}
public ABetterViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
//Enter the code here to communicate a touch event
return super.onInterceptTouchEvent(ev);
}
}
You will probably need to tailor the above to your specifications. For instance, you may only want to trigger the event once someone starts to move their finger on the screen, in which case you would use:
if (ev.getAction() == MotionEvent.ACTION_MOVE) {
//User is moving their finger over the screen
}
In respect to communicating the touch event from your ViewPager to wherever it needs to be to fire your ActionBar hiding animation (which I assume is the Activity hosting the ViewPager) then you can use an interface/EventBus.
Also, don't forget to replace the ViewPager in your xml layout file with the full name of your custom class (i.e. com.example.mywidgets.ABetterViewPager, or whatever)
ViewPager is not made for onClick. It has OnPageChangelistener as below:
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
// this will execute when page will be selected
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
I have a problem. I have an Activity with ViewPager which have some Fragments.
In my first Fragment I have some elements. Lets say an ImageView, TextView. How to make them visible by timer when you completely open the page of ViewPager?!
I used this code below in my MainActivity.java document to make that ImageView visible by timer but it works not as I expected. When i want to go to next page by scrolling and touch the screen ImageView dissapear. Why its happened?!
final ImageView mImageView = (ImageView) findViewById(R.id.earth);
mImageView.setVisibility(View.INVISIBLE);
mImageView.postDelayed(new Runnable() {
public void run() {
mImageView.setVisibility(View.VISIBLE);
}}, 5000);
Any help is appreciated. Thanks!
My new edits:
// Initialize the ViewPager and set an adapter
ViewPager pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));
// Bind the tabs to the ViewPager
PagerSlidingTabStrip tabs = (PagerSlidingTabStrip) findViewById(R.id.tabs);
tabs.setViewPager(pager);
//open concrete page of ViewPager. setCurrentItem(index of page)
pager.setCurrentItem(1);
tabs.setOnPageChangeListener(new OnPageChangeListener() {
//This method will be invoked when the current page is scrolled, either as part of a program initiated smooth scroll or a user initiated touch scroll.
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
//This method will be invoked when a new page becomes selected.
#Override
public void onPageSelected(int position) {
final ImageView mImageView = (ImageView) findViewById(R.id.earth);
mImageView.setVisibility(View.INVISIBLE);
if (position == 0) {
mImageView.postDelayed(new Runnable() {
public void run() {
mImageView.setVisibility(View.VISIBLE);
}
}, 5000);
}
}
//Called when the scroll state changes.
#Override
public void onPageScrollStateChanged(int state) {
}
});
My Problem is conflict with TABS and ViewPager. When I use tabs.setOnPageChangeListener(new OnPageChangeListener() i have conflict with pager.setCurrentItem(1); which shows concrete page when Activity first opened. In my case its shows 2-d page when Activity first opened but Tab shows that opened 1-st page. WHY?! How to solve this problem?!
I would not use a timer. It would either fire too early, or too late during which your UI looks bad. Use the pager's events to know when to update your UI. For example, you can probably use OnPageChangedListener:
pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
// Now displaying page at position
}
#Override
public void onPageScrollStateChanged(int state) {
}
};
Context:
I'm making a music player and I'm currently working on the miniplayer. The miniplayer lives in a ViewPager along with a floating action button (FAB) for shuffle. Initially, only the FAB is seen on screen. When you click on the FAB, music playback starts, the Fab-Miniplayer ViewPager's page count goes from 1 to 2, and its page is set to the second page, where the miniplayer is. The miniplayer itself in the second page is a vertical viewpager, so one can swipe through to different songs. The miniplayer/vertical viewpager is backed by a PagerAdapter that gets songs from a SongQueue obejct.
The Problem:
If I click on the FAB once, the miniplayer opens and everything works. Then I dismiss the miniplayer to stop playback by swiping back to the FAB page in the ViewPager. After clicking on the FAB to start playback and open the miniplayer for the second time, the first two fragments are never created. The miniplayer vertical ViewPager's PagerAdapter's getItem() methods are never called for item 0 and item 1. On a higher level, the first two songs in the miniplayer aren't showing up. Upon further investigation, the onCreate() methods are being called for the first two songs from the last time the miniplayer was opened, so I'm guessing the ViewPager is implementing some kind of caching or a reference is being held onto for too long because the miniplayer vertical viewpager thinks that it already has the first two songs the second time it is instantiated. Hopefully this problem description makes sense. If there are any questions, I'd be happy to try and go into more detail.
The Code
SongsFragment
/**
* Fragment used to display all of the songs on the device.
*/
public class SongsFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
private static final String TAG = "SongsFragment";
private SwipeListView mSwipeListView;
private ViewPager fabMiniPlayerViewPager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
setHasOptionsMenu(true);
// Initialize the loader to load the list of songs
getLoaderManager().initLoader(SongCursorLoader.ALL_SONGS_ID, null, this);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.list_view_songs, parent, false);
if (view != null) {
mSwipeListView = (SwipeListView) view.findViewById(R.id.list_view_songs);
}
LinearLayout emptyView = (LinearLayout) inflater.inflate(R.layout.list_view_songs_empty, parent, false);
mSwipeListView.setEmptyView(emptyView);
fabMiniPlayerViewPager = (ViewPager) view.findViewById(R.id.fab_miniplayer_ViewPager);
Integer viewPagerPageCount = new Integer(1);
fabMiniPlayerViewPager.setTag(viewPagerPageCount); // The fabMiniPlayerViewPager gets it's page count from the tag so it can be dynamically modified
fabMiniPlayerViewPager.setAdapter(new FragmentStatePagerAdapter(getChildFragmentManager()) {
#Override
public Fragment getItem(int i) {
if (i == 0) {
// ShuffleFabFragment just houses a single button, the code is below
ShuffleFabFragment fragment = new ShuffleFabFragment();
fragment.setViewPager(fabMiniPlayerViewPager);
return fragment;
}
MiniPlayerFragment fragment = new MiniPlayerFragment();
return fragment;
}
#Override
public int getCount() {
Integer count = (Integer) fabMiniPlayerViewPager.getTag();
return count.intValue();
}
});
fabMiniPlayerViewPager.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
// Pass touch events to the list view behind it
mSwipeListView.onTouchEvent(motionEvent);
return false;
}
});
return view;
}
#Override
public void onResume() {
super.onResume();
if (!MusicPlayerService.isStopped()) {
Integer viewPagerPageCount = 2;
fabMiniPlayerViewPager.setTag(viewPagerPageCount);
PagerAdapter adapter = fabMiniPlayerViewPager.getAdapter();
fabMiniPlayerViewPager.setAdapter(adapter);
fabMiniPlayerViewPager.setCurrentItem(1, false);
} else {
Integer viewPagerPageCount = 1;
fabMiniPlayerViewPager.setTag(viewPagerPageCount);
fabMiniPlayerViewPager.getAdapter().notifyDataSetChanged();
}
}
}
ShuffleFabFragment
/**
* Fragment representing the Shuffle Floating Action Button. On FAB click, it turns on shuffle and
* plays a random song. Depending on the user preference, the mini-player will appear or the
* Now Playing view will appear. The ShuffleFabFragment holds a reference to its containing
* ViewPager so it can do the following:
* <p/>
* 1. Add the MiniPlayer fragment to the ViewPager to enable swiping & animations
* 2. Remove the MiniPlayer fragment when it is swiped away
* <p/>
* Once the MiniPlayer is swiped away (to the right), it stops music playback.
*/
public class ShuffleFabFragment extends Fragment {
private static final String TAG = "ShuffleFabFragment";
private ViewPager fabMiniPlayerViewPager;
public void setViewPager(ViewPager viewPager) {
fabMiniPlayerViewPager = viewPager;
fabMiniPlayerViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int i, float v, int i2) {
}
#Override
public void onPageSelected(int i) {
if (i == 0) { // MiniPlayer swiped away
Integer viewPagerPageCount = new Integer(1);
fabMiniPlayerViewPager.setTag(viewPagerPageCount);
PagerAdapter adapter = fabMiniPlayerViewPager.getAdapter();
Intent stopMusicIntent = new Intent(getActivity(), MusicPlayerService.class);
stopMusicIntent.setAction(MusicPlayerService.ACTION_STOP);
getActivity().startService(stopMusicIntent);
fabMiniPlayerViewPager.setAdapter(adapter);
}
}
#Override
public void onPageScrollStateChanged(int i) {
}
});
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.shuffle_fab, viewGroup, false);
ImageView shuffleFabImageView = (ImageView) view.findViewById(R.id.shuffle_fab_ImageView);
shuffleFabImageView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
// Scale up on touch to make the button appear to come closer
view.setScaleX(8f / 7f);
view.setScaleY(8f / 7f);
break;
case MotionEvent.ACTION_UP:
view.setScaleX(1f);
view.setScaleY(1f);
break;
default:
view.setScaleX(1f);
view.setScaleY(1f);
}
return false;
}
});
shuffleFabImageView.setClickable(true);
shuffleFabImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String shuffleMode = PreferencesHelper.getShuffleMode(getActivity());
if (shuffleMode.equals(PreferencesHelper.SHUFFLE_MODE_OFF)) {
PreferencesHelper.setShuffleMode(getActivity(), PreferencesHelper.SHUFFLE_MODE_SMART);
}
SongQueue.initializeQueue(null, true, Song.COLLECTION_TYPE_ALL_SONGS, getActivity().getApplicationContext(), null);
Song firstSong = SongQueue.getSong(0);
firstSong.play(getActivity(), false);
// On Click, update the page count, then set page to miniplayer
Integer viewPagerPageCount = new Integer(2);
fabMiniPlayerViewPager.setTag(viewPagerPageCount);
fabMiniPlayerViewPager.getAdapter().notifyDataSetChanged();
fabMiniPlayerViewPager.setCurrentItem(1, true);
}
});
return view;
}
}
MiniPlayerFragment
/**
* Hosts MiniplayerCardFragments and allows for song skipping
*/
public class MiniPlayerFragment extends Fragment implements ViewPager.OnPageChangeListener {
VerticalViewPager miniplayerCardViewPager;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.view_pager_miniplayer, viewGroup, false);
miniplayerCardViewPager = (VerticalViewPager) view.findViewById(R.id.miniplayer_cards_ViewPager);
miniplayerCardViewPager.setAdapter(new FragmentStatePagerAdapter(getChildFragmentManager()) {
#Override
public Fragment getItem(int position) {
Song song = SongQueue.getSong(position);
return MiniPlayerCardFragment.newInstance(song);
}
#Override
public int getCount() {
return SongQueue.getTotalSize();
}
});
miniplayerCardViewPager.setOnPageChangeListener(this);
SongQueue.addOnQueueChangeListener(new SongQueue.OnQueueChangeListener() {
#Override
public void onNextSongChanged() {
onQueueChanged();
}
#Override
public void onQueueChanged() {
// Force re-layout to update fragments
int queuePosition = SongQueue.getQueuePositionCurrentSong();
PagerAdapter adapter = miniplayerCardViewPager.getAdapter();
miniplayerCardViewPager.setAdapter(adapter);
miniplayerCardViewPager.setCurrentItem(queuePosition, true);
}
#Override
public void onCurrentSongChanged() {
onQueueChanged();
}
});
return view;
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
int queuePosition = SongQueue.getQueuePositionCurrentSong();
if (queuePosition < position) {
Intent nextIntent = new Intent(getActivity(), MusicPlayerService.class);
nextIntent.setAction(MusicPlayerService.ACTION_NEXT);
getActivity().startService(nextIntent);
} else if (queuePosition > position) {
Intent prevIntent = new Intent(getActivity(), MusicPlayerService.class);
prevIntent.setAction(MusicPlayerService.ACTION_PREV);
getActivity().startService(prevIntent);
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
#Override
public void onResume() {
super.onResume();
// Force re-layout to update fragments
int queuePosition = SongQueue.getQueuePositionCurrentSong();
PagerAdapter adapter = miniplayerCardViewPager.getAdapter();
miniplayerCardViewPager.setAdapter(adapter);
miniplayerCardViewPager.setCurrentItem(queuePosition, true);
SongQueue.setPagerAdapter(adapter);
}
}
Screenshots to help visualization
After clicking on the FAB to start playback and open the miniplayer for the second time, the first two fragments are never created. The miniplayer vertical ViewPager's PagerAdapter's getItem() methods are never called for item 0 and item 1.
That is because the standard ViewPager already has pages 0 and 1. To clarify Sanket's answer, setOffscreenPageLimit() indicates how many pages to either side of the current page to create (via getItem()) and cache, and the minimum value is 1. Calls to setOffscreenPageLimit(0) will be ignored.
getItem() is not a means of finding out when the user switches pages. A PageChangeListener is your means of finding out when the user switches pages.
the miniplayer vertical viewpager thinks that it already has the first two songs the second time it is instantiated
It's not being instantiated a second time AFAICT.
ViewPager has bydefault offScreenPagerLimit value 3.. so it may be not loading your first 2 item second time..
try with this
mViewPager.setOffscreenPageLimit(0);
more info
I'm using a viewpager to swipe between fragments and would like the back button to navigate to the previously viewed fragment rather than ending the activity. Sorry if this is a duplicate of this question however I didn't find the answer very helpful. Obviously onBackPressed needs to be overridden, but I don't know how to get and display the correct fragment. I assume that I should use the fragmentmanager's backstack, but getSupportFragmentManager().getBackStackEntryCount() always returns 0. Do I need to manually add fragments to the backstack using FragmentTransaction.addToBackStack()? If so, where would I add this in my adapter?
Here is the code for my activity,
public class PagerActivity extends FragmentActivity {
ArrayList<Sale> sales;
MyAdapter mAdapter;
ViewPager mPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent it = getIntent();
this.sales = (ArrayList<Sale>) it.getExtras().get("sales");
int position = it.getExtras().getInt("position");
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
setContentView(R.layout.fragment_pager);
mAdapter = new MyAdapter(getSupportFragmentManager());
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
mPager.setCurrentItem(position);
}
public class MyAdapter extends FragmentPagerAdapter {
public MyAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
#Override
public int getCount() {
return sales.size();
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
}
#Override
public Fragment getItem(int position) {
SalesThumbFragment frag = new SalesThumbFragment();
return frag.newInstance(sales.get(position));
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.sales_controller, menu);
return true;
}
#Override
public void onBackPressed() {
if(getSupportFragmentManager().getBackStackEntryCount() != 0) {
getSupportFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
}
In new design support library, i use this
I have same issue and i follow this step
In the main activity where there are 3 fragment in viewpager i create stack
and push and pop data.
//private Stack<Integer> stackkk; ==> As i get edit suggestion
private Stack<Integer> stackkk = new Stack<>(); // Edited
private ViewPager mPager;
private int tabPosition = 0;
mTabLayout.setupWithViewPager(mPager);
mPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTabLayout));
mTabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
tabPosition = tab.getPosition();
mPager.setCurrentItem(tab.getPosition());
if (stackkk.empty())
stackkk.push(0);
if (stackkk.contains(tabPosition)) {
stackkk.remove(stackkk.indexOf(tabPosition));
stackkk.push(tabPosition);
} else {
stackkk.push(tabPosition);
}
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
tabPositionUnselected = tab.getPosition();
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
and in the onBackPressed in activity,
#Override
public void onBackPressed() {
if (stackkk.size() > 1) {
stackkk.pop();
mPager.setCurrentItem(stackkk.lastElement());
} else {
}
}
Use this code in Fragment Activity class. Don't forget to add return true;
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
mViewPager.setCurrentItem(viewPageSelected - 1);
return true;
}
return super.onKeyDown(keyCode, event);
}
I had a similar problem, this is how I solved it. I think you can adapt the code to your problem, if I understood what you problem is. I had a ViewPager with 6 fragments and wanted to keep track of the page history and to be able to use the back button to navigate backwards in the history. I create a java.util.Stack<Integer> object, add fragment numbers to it (except when you use the back button, see below), and override onBackPressed() to make it pop the last viewed fragment instead of using the back stack, when my history stack is not empty.
You want to avoid pushing elements on the Stack when you press the back button, otherwise you will get stuck between two fragments if you keep using the back button, instead of eventually exiting.
My code:
MyAdapter mAdapter;
ViewPager mPager;
Stack<Integer> pageHistory;
int currentPage;
boolean saveToHistory;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAdapter = new MyAdapter(getSupportFragmentManager());
mPager = (ViewPager)findViewById(R.id.container);
mPager.setAdapter(mAdapter);
mPager.setOffscreenPageLimit(5);
pageHistory = new Stack<Integer>();
mPager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int arg0) {
if(saveToHistory)
pageHistory.push(Integer.valueOf(currentPage));
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
saveToHistory = true;
}
#Override
public void onBackPressed() {
if(pageHistory.empty())
super.onBackPressed();
else {
saveToHistory = false;
mPager.setCurrentItem(pageHistory.pop().intValue());
saveToHistory = true;
}
};
If you use a field to keep track of the index of the previous page using mPager.getCurrentItem() after each time the user navigates to a new fragment, then in the onBackPressed() method, you should be able to call mPager.setCurrentItem(previousPage)
Or, if the user can only page in order, then you don't need a field at all, and you could just do mPager.setCurrentItem(mPager.getCurrentItem()-1)
I've made custom ViewPager and implement stack functionality in it.
public class CustomViewPager extends ViewPager {
private Stack<Integer> stack = new Stack<>();
#Override
public void setCurrentItem(int item, boolean smoothScroll) {
stack.push(getCurrentItem());
super.setCurrentItem(item, smoothScroll);
}
public int popFromBackStack(boolean smoothScroll) {
if (stack.size()>0) {
super.setCurrentItem(stack.pop(), smoothScroll);
return getCurrentItem();
} else return -1;
}
I have a viewpager which switches between tabs when swiping left/right.In my second tab, i have some custom views which have listeners for pinching and dragging but when i try to pinch or drag, the viewpager starts to swipe the page.
A solution comes to my mind is to disable swiping when touching those specific views and only swipe when touching outside those views.Is this possible?
Updated:
#Asok kindly provided the solution. But then updated the code which wouldnt work in my case so i post the previous piece of code which worked for me:
public class CustomViewPager extends ViewPager {
private boolean swipeable = true;
public CustomViewPager(Context context) {
super(context);
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
// Call this method in your motion events when you want to disable or enable
// It should work as desired.
public void setSwipeable(boolean swipeable) {
this.swipeable = swipeable;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent arg0) {
return (this.swipeable) ? super.onInterceptTouchEvent(arg0) : false;
}
Lets suppose i have a draggable view and i need to disable swipping when dragging start and re enable when dragging finished so in TouchEvent of my so called view:
#Override
public boolean onTouchEvent(MotionEvent event) {
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
//disable swiping when the button is touched
((ActivityOriginal) getActivity()).setSwipeable(false);
//the rest of the code...
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
//re enable swipping when the touch is stopped
//the rest of the code...
((ActivityOriginal) getActivity()).setSwipeable(true);
break;
}
return true;
}
This first thing that comes to mind for me is to have a custom ViewPager in which, when your touch listeners get notified of a specific event you could set the swipeable boolean in ViewPager to false and set it back to true whichever way best fits your application.
public class CustomViewPager extends ViewPager {
private boolean swipeable = true;
public CustomViewPager(Context context) {
super(context);
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
// Call this method in your motion events when you want to disable or enable
// It should work as desired.
public void setSwipeable(boolean swipeable) {
this.swipeable = swipeable;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent arg0) {
return (this.swipeable) ? super.onInterceptTouchEvent(arg0) : false;
}
}
Make sure to change your layout file to show:
<com.your.package.CustomViewPager .. />
Instead of:
<android.support.v4.view.ViewPager .. />
Edit 2
Here is my setup (Working with the above CustomViewPager):
CustomViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set up the action bar.
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Create the adapter that will return a fragment for each of the three
// primary sections of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the CustomViewPager with the sections adapter.
mViewPager = (CustomViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
actionBar.addTab(actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
public void swipeOn(View v) {
mViewPager.setSwipeable(true);
}
public void swipeOff(View v) {
mViewPager.setSwipeable(false);
}
The above shown onCreate is in my MainActivity class which extends FragmentActivity and implements ActionBar.TabListener
I am using requestDisallowInterceptTouchEvent(true) int the onTouchEvent listener of the view that also has drag events.
#Override
public boolean onTouchEvent(MotionEvent event) {
ViewParent parent = getParent();
// or get a reference to the ViewPager and cast it to ViewParent
parent.requestDisallowInterceptTouchEvent(true);
// let this view deal with the event or
return super.onTouchEvent(event);
}
I am using like this
public void setSwipeable(boolean swipeable)
{
this.swipeable = swipeable;
}
#Override
public void scrollTo(int x, int y){
if (swipeable){
super.scrollTo(x, y);
}
}
If you know the positions on which you don't want to intercept touch events in the view pager you can do something like I did.
#Override
public boolean onInterceptTouchEvent(MotionEvent arg0) {
if(arg0.getY()>getHeight()/2)return false;
return super.onInterceptTouchEvent(arg0);
}