Last active
May 5, 2016 17:00
-
-
Save rharter/5488586 to your computer and use it in GitHub Desktop.
This contains many parts of the main fragment for an app I did that has an autoscrolling horizontal view pager on top of a list, very similar to Marvel. The reason I wanted to share this is because I think it is directly transferrable to solve some of the issues with the promo pager on the main screen. Notice the GestureDetector that is used. Th…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private static GestureDetector GESTURE_DETECTOR; | |
private static final long HEADLINE_SCROLL_DELAY = 5000; | |
private Timer mAutoScroller; | |
private ViewPager mHeadlinePager; | |
private HeadlineAdapter mHeadlineAdapter; | |
private static final long refreshInterval = 300 * 1000; | |
@Override | |
public void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
if (GESTURE_DETECTOR == null) { | |
GESTURE_DETECTOR = new GestureDetector(getActivity(), new PagerScrollDetector()); | |
} | |
} | |
/** | |
* Activity Lifecycle Methods | |
*/ | |
@Override | |
public void onActivityCreated(Bundle savedInstanceState) { | |
super.onActivityCreated(savedInstanceState); | |
// Take part in populating the action bar menu | |
setHasOptionsMenu(true); | |
// Setup the headline view | |
if (mHeadlinePager == null) { | |
mHeadlinePager = new ViewPager(getActivity()); | |
} | |
mHeadlineAdapter = new HeadlineAdapter(getActivity(), null); | |
mHeadlinePager.setAdapter(mHeadlineAdapter); | |
// This is a really stupid hack and seems inefficient. onActivityCreated(Bundle) is called whenever | |
// the fragment is reattached to the Activity (tab reselected), so we get an IllegalStateException if | |
// we don't set the list adapter to null first. | |
setListAdapter(null); | |
getListView().addHeaderView(mHeadlinePager); | |
final float scale = getActivity().getResources().getDisplayMetrics().density; | |
final float height = getActivity().getResources().getDimension(R.dimen.headline_height); | |
AbsListView.LayoutParams params = new AbsListView.LayoutParams( | |
AbsListView.LayoutParams.MATCH_PARENT, | |
(int) (height * scale + 0.5f)); | |
mHeadlinePager.setLayoutParams(params); | |
mHeadlinePager.setOnTouchListener(new View.OnTouchListener() { | |
@Override | |
public boolean onTouch(View v, MotionEvent event) { | |
boolean result = v.onTouchEvent(event); | |
// Stop the auto scrolling if the user manually scrolls | |
if (mAutoScroller != null) { | |
mAutoScroller.cancel(); | |
mAutoScroller = null; | |
} | |
if (GESTURE_DETECTOR.onTouchEvent(event)) { | |
v.getParent().requestDisallowInterceptTouchEvent(true); | |
} else { | |
v.getParent().requestDisallowInterceptTouchEvent(false); | |
} | |
return result; | |
} | |
}); | |
mAdapter = new StoryAdapter(getActivity(), null); | |
setListAdapter(mAdapter); | |
getActivity().getSupportLoaderManager().initLoader(HEADLINE_LIST, null, this); | |
} | |
public void onDetach() { | |
super.onDetach(); | |
setListAdapter(null); | |
} | |
@Override | |
public void onResume() { | |
super.onResume(); | |
// Restart the timer | |
if (mAutoScroller == null) { | |
mAutoScroller = new Timer(); | |
mAutoScroller.scheduleAtFixedRate(new AutoScrollTimerTask(), | |
HEADLINE_SCROLL_DELAY, HEADLINE_SCROLL_DELAY); | |
} | |
// Refresh the stories | |
updateStories(false); | |
} | |
@Override | |
public void onPause() { | |
super.onPause(); | |
setRefreshButtonState(false); | |
// Cancel the load stories task | |
if (mLoadStoriesTask != null) { | |
mLoadStoriesTask.cancel(true); | |
mLoadStoriesTask = null; | |
} | |
// Cancel the timer | |
if (mAutoScroller != null) { | |
mAutoScroller.cancel(); | |
mAutoScroller = null; | |
} | |
} | |
/** | |
* Menu handling | |
*/ | |
@Override | |
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { | |
inflater.inflate(R.menu.main_list, menu); | |
} | |
@Override | |
public boolean onOptionsItemSelected(MenuItem item) { | |
switch (item.getItemId()) { | |
case R.id.refresh: | |
updateStories(true); | |
return true; | |
default: | |
return super.onOptionsItemSelected(item); | |
} | |
} | |
/** | |
* Data Updating Methods | |
*/ | |
private void updateStories(boolean force) { | |
// If we have no stories, update the cursors | |
if (mLoadStoriesTask == null && force || | |
System.currentTimeMillis() - lastUpdateTime > refreshInterval) { | |
// Look for new stories | |
mLoadStoriesTask = new LoadStoriesTask(); | |
mLoadStoriesTask.execute(); | |
} | |
} | |
/** | |
* Creates a story cursor and adapter and sets it | |
* as the list adapter. | |
*/ | |
final static String[] STORY_PROJECTION = { | |
BaseColumns._ID, | |
StoryColumns.GUID, | |
StoryColumns.TYPE, | |
StoryColumns.TITLE, | |
StoryColumns.THUMB, | |
StoryColumns.DATE, | |
StoryColumns.CATEGORY_BADGE_COLOR, | |
StoryColumns.CATEGORY_NAME, | |
StoryColumns.AUTHOR | |
}; | |
final static String[] HEADLINE_PROJECTION = { | |
BaseColumns._ID, | |
StoryColumns.GUID, | |
StoryColumns.TYPE, | |
StoryColumns.TITLE, | |
StoryColumns.CATEGORY_BADGE_COLOR, | |
StoryColumns.CATEGORY_NAME, | |
StoryColumns.IMAGE | |
}; | |
final static String STORY_SELECT = Story.TYPE + " = " + StoryType.GENERAL; | |
final static String HEADLINE_SELECT = Story.TYPE + " = " + StoryType.HEADLINE; | |
@Override | |
public Loader<Cursor> onCreateLoader(int id, Bundle args) { | |
String select = null; | |
String[] projection = null; | |
switch (id) { | |
case STORY_LIST: | |
projection = STORY_PROJECTION; | |
select = STORY_SELECT; | |
break; | |
case HEADLINE_LIST: | |
projection = HEADLINE_PROJECTION; | |
select = HEADLINE_SELECT; | |
break; | |
} | |
return new CursorLoader(getActivity(), Story.CONTENT_URI, projection, select, | |
null, Story.DEFAULT_SORT); | |
} | |
@Override | |
public void onLoadFinished(Loader loader, Cursor data) { | |
switch(loader.getId()) { | |
case STORY_LIST: | |
mAdapter.swapCursor(data); | |
break; | |
case HEADLINE_LIST: | |
mHeadlineAdapter.swapCursor(data); | |
break; | |
} | |
} | |
@Override | |
public void onLoaderReset(Loader loader) { | |
switch (loader.getId()) { | |
case STORY_LIST: | |
mAdapter.swapCursor(null); | |
break; | |
case HEADLINE_LIST: | |
mHeadlineAdapter.swapCursor(null); | |
break; | |
} | |
} | |
// Return false if we're scrolling in the x direction | |
class PagerScrollDetector extends SimpleOnGestureListener { | |
@Override | |
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { | |
return true; | |
} | |
} | |
class AutoScrollTimerTask extends TimerTask { | |
@Override | |
public void run() { | |
getActivity().runOnUiThread(new Runnable() { | |
@Override | |
public void run() { | |
if (mHeadlinePager != null) { | |
int count = mHeadlineAdapter.getCount(); | |
if (count > 0) { | |
int current = mHeadlinePager.getCurrentItem(); | |
mHeadlinePager.setCurrentItem((current + 1) % count, true); | |
} | |
} | |
} | |
}); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
b |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment