/*
* 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];
}
}
}