/* * Copyright (C) 2005-2015 Team XBMC * http://xbmc.org * * This Program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This Program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with XBMC Remote; see the file license. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * http://www.gnu.org/copyleft/gpl.html * */ package org.xbmc.android.view; import android.content.Context; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.view.MotionEvent; /** * A view pager that relies on the currently displayed fragment to deliver the * next or previous page, as opposed to a global list of fragments. * * A bit inspired from <a href="http://stackoverflow.com/questions/7951730"> * Stackoverflow.</a> * * @author freezy <freezy@xbmc.org> */ public class RelativeViewPager extends ViewPager { private final static String TAG = RelativeViewPager.class.getSimpleName(); private RelativePagerAdapter adapter; private boolean enabledPrev = true; private boolean enabledNext = true; private float x = -1; private int currPosition = 0; private OnRelativePageChangeListener pageChangeListener; public RelativeViewPager(Context context) { super(context); } public RelativeViewPager(Context context, AttributeSet attrs) { super(context, attrs); } private void initRelativeViewPager() { setOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { currPosition = position; } @Override public void onPageScrollStateChanged(final int state) { if (state == ViewPager.SCROLL_STATE_IDLE) { if (adapter == null) { return; } if (currPosition == RelativePagerAdapter.PAGE_POSITION_LEFT) { adapter.move(1); } else if (currPosition == RelativePagerAdapter.PAGE_POSITION_RIGHT) { adapter.move(-1); } onPageActive(); } } }); onPageActive(); } private void onPageActive() { setCurrentItem(RelativePagerAdapter.PAGE_POSITION_CENTER, false); setPagingNextEnabled(adapter.getCurrentFragment().hasNext()); setPagingPrevEnabled(adapter.getCurrentFragment().hasPrev()); adapter.getCurrentFragment().onPageActive(); if (pageChangeListener != null) { pageChangeListener.onPageSelected(adapter.getCurrentFragment()); } } @Override public final void setCurrentItem(final int item) { if (item != RelativePagerAdapter.PAGE_POSITION_CENTER) { // throw new RuntimeException("Cannot change page index unless its 1."); } super.setCurrentItem(item); } @Override public void setAdapter(final PagerAdapter adapter) { if (adapter instanceof RelativePagerAdapter) { super.setAdapter(adapter); this.adapter = (RelativePagerAdapter)adapter; this.adapter.setPager(this); initRelativeViewPager(); } else { throw new IllegalArgumentException("Adapter must be an instance of RelativePagerAdapter."); } } @Override public boolean onTouchEvent(MotionEvent event) { if (!enabledPrev && !enabledNext) { return true; } if (enabledPrev && enabledNext) { return super.onTouchEvent(event); } if (event.getAction() == MotionEvent.ACTION_DOWN) { x = event.getX(); } if (x < 0) { return super.onTouchEvent(event); } if (event.getAction() == MotionEvent.ACTION_MOVE) { if (!enabledPrev && x < event.getX()) { return true; } if (!enabledNext && x > event.getX()) { return true; } } //Log.d("pager", "Event: " + event.getAction() + " (" + event.getX() + ")"); return super.onTouchEvent(event); } /** * Enables or disables paging back to the previous page. * @param enabled If true, enable, otherwise disable. */ public void setPagingPrevEnabled(boolean enabled) { this.enabledPrev = enabled; } /** * Enables or disables paging forth to the next page. * @param enabled If true, enable, otherwise disable. */ public void setPagingNextEnabled(boolean enabled) { this.enabledNext = enabled; } public void setOnRelativePageChangeListener(OnRelativePageChangeListener listener) { pageChangeListener = listener; } public void onStatusUpdate() { if (pageChangeListener != null) { pageChangeListener.onPageUpdated(adapter.getCurrentFragment()); } } public interface OnRelativePageChangeListener { public void onPageSelected(RelativePagerFragment fragment); public void onPageUpdated(RelativePagerFragment fragment); } }