/* * Copyright 2014 Soichiro Kashima * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.marshalchen.common.demoofui.observablescrollview; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentStatePagerAdapter; import android.support.v4.view.ViewCompat; import android.support.v4.view.ViewPager; import android.support.v7.app.ActionBarActivity; import android.support.v7.widget.Toolbar; import android.util.SparseArray; import android.view.View; import android.view.ViewGroup; import com.github.ksoichiro.android.observablescrollview.ObservableListView; import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks; import com.github.ksoichiro.android.observablescrollview.ScrollState; import com.marshalchen.common.demoofui.R; import com.marshalchen.common.demoofui.observablescrollview.ui.widget.SlidingTabLayout; import com.nineoldandroids.view.ViewHelper; import com.nineoldandroids.view.ViewPropertyAnimator; /** * SlidingTabLayout and SlidingTabStrip are from google/iosched: * https://github.com/google/iosched */ public class ViewPagerTabListViewActivity extends ActionBarActivity implements ObservableScrollViewCallbacks { private View mHeaderView; private View mToolbarView; private int mBaseTranslationY; private ViewPager mPager; private NavigationAdapter mPagerAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.observable_scroll_view_activity_viewpagertabscrollview); setSupportActionBar((Toolbar) findViewById(R.id.toolbar)); mHeaderView = findViewById(R.id.header); ViewCompat.setElevation(mHeaderView, getResources().getDimension(R.dimen.toolbar_elevation)); mToolbarView = findViewById(R.id.toolbar); mPagerAdapter = new NavigationAdapter(getSupportFragmentManager()); mPager = (ViewPager) findViewById(R.id.pager); mPager.setAdapter(mPagerAdapter); SlidingTabLayout slidingTabLayout = (SlidingTabLayout) findViewById(R.id.sliding_tabs); slidingTabLayout.setCustomTabView(R.layout.observable_scroll_view_tab_indicator, android.R.id.text1); slidingTabLayout.setSelectedIndicatorColors(getResources().getColor(R.color.accent)); slidingTabLayout.setDistributeEvenly(true); slidingTabLayout.setViewPager(mPager); // When the page is selected, other fragments' scrollY should be adjusted // according to the toolbar status(shown/hidden) slidingTabLayout.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int i, float v, int i2) { } @Override public void onPageSelected(int i) { propagateToolbarState(toolbarIsShown()); } @Override public void onPageScrollStateChanged(int i) { } }); propagateToolbarState(toolbarIsShown()); } @Override public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) { if (dragging) { int toolbarHeight = mToolbarView.getHeight(); float currentHeaderTranslationY = ViewHelper.getTranslationY(mHeaderView); if (firstScroll) { if (-toolbarHeight < currentHeaderTranslationY) { mBaseTranslationY = scrollY; } } int headerTranslationY = Math.min(0, Math.max(-toolbarHeight, -(scrollY - mBaseTranslationY))); ViewPropertyAnimator.animate(mHeaderView).cancel(); ViewHelper.setTranslationY(mHeaderView, headerTranslationY); } } @Override public void onDownMotionEvent() { } @Override public void onUpOrCancelMotionEvent(ScrollState scrollState) { mBaseTranslationY = 0; Fragment fragment = getCurrentFragment(); if (fragment == null) { return; } View view = fragment.getView(); if (view == null) { return; } int toolbarHeight = mToolbarView.getHeight(); final ObservableListView listView = (ObservableListView) view.findViewById(R.id.list); if (scrollState == ScrollState.UP) { if (toolbarHeight < listView.getCurrentScrollY()) { hideToolbar(); } else if (listView.getCurrentScrollY() < toolbarHeight) { showToolbar(); } } else if (scrollState == ScrollState.DOWN) { if (toolbarHeight < listView.getCurrentScrollY()) { showToolbar(); } } } private Fragment getCurrentFragment() { return mPagerAdapter.getItemAt(mPager.getCurrentItem()); } private void propagateToolbarState(boolean isShown) { int toolbarHeight = mToolbarView.getHeight(); // Set scrollY for the fragments that are not created yet mPagerAdapter.setScrollY(isShown ? 0 : toolbarHeight); // Set scrollY for the active fragments for (int i = 0; i < mPagerAdapter.getCount(); i++) { // Skip current item if (i == mPager.getCurrentItem()) { continue; } // Skip destroyed or not created item Fragment f = mPagerAdapter.getItemAt(i); if (f == null) { continue; } ObservableListView listView = (ObservableListView) f.getView().findViewById(R.id.list); if (isShown) { // Scroll up if (0 < listView.getCurrentScrollY()) { listView.setSelection(0); } } else { // Scroll down (to hide padding) if (listView.getCurrentScrollY() < toolbarHeight) { listView.setSelection(1); } } } } private boolean toolbarIsShown() { return ViewHelper.getTranslationY(mHeaderView) == 0; } private void showToolbar() { float headerTranslationY = ViewHelper.getTranslationY(mHeaderView); if (headerTranslationY != 0) { ViewPropertyAnimator.animate(mHeaderView).cancel(); ViewPropertyAnimator.animate(mHeaderView).translationY(0).setDuration(200).start(); } propagateToolbarState(true); } private void hideToolbar() { float headerTranslationY = ViewHelper.getTranslationY(mHeaderView); int toolbarHeight = mToolbarView.getHeight(); if (headerTranslationY != -toolbarHeight) { ViewPropertyAnimator.animate(mHeaderView).cancel(); ViewPropertyAnimator.animate(mHeaderView).translationY(-toolbarHeight).setDuration(200).start(); } propagateToolbarState(false); } private static class NavigationAdapter extends FragmentStatePagerAdapter { private static final String[] TITLES = new String[]{"Applepie", "Butter Cookie", "Cupcake", "Donut", "Eclair", "Froyo", "Gingerbread", "Honeycomb", "Ice Cream Sandwich", "Jelly Bean", "KitKat", "Lollipop"}; private SparseArray<Fragment> mPages; private int mScrollY; public NavigationAdapter(FragmentManager fm) { super(fm); mPages = new SparseArray<Fragment>(); } public void setScrollY(int scrollY) { mScrollY = scrollY; } @Override public Fragment getItem(int position) { Fragment f = new ViewPagerTabListViewFragment(); if (0 < mScrollY) { Bundle args = new Bundle(); args.putInt(ViewPagerTabListViewFragment.ARG_INITIAL_POSITION, 1); f.setArguments(args); } mPages.put(position, f); return f; } public Fragment getItemAt(int position) { return mPages.get(position); } @Override public int getCount() { return TITLES.length; } @Override public void destroyItem(ViewGroup container, int position, Object object) { if (0 <= mPages.indexOfKey(position)) { mPages.remove(position); } super.destroyItem(container, position, object); } @Override public CharSequence getPageTitle(int position) { return TITLES[position]; } } }