Java tutorial
/* * 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.zms.materialdesign.observablescrollview.activity; import android.annotation.TargetApi; import android.content.res.Configuration; import android.os.Build; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.view.ViewCompat; import android.support.v4.view.ViewPager; import android.support.v7.widget.Toolbar; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.widget.FrameLayout; import android.widget.TextView; import com.zms.materialdesign.R; import com.zms.materialdesign.observablescrollview.CacheFragmentStatePagerAdapter; import com.zms.materialdesign.observablescrollview.ObservableScrollViewCallbacks; import com.zms.materialdesign.observablescrollview.ScrollState; import com.zms.materialdesign.observablescrollview.ScrollUtils; import com.zms.materialdesign.observablescrollview.Scrollable; import com.zms.materialdesign.observablescrollview.TouchInterceptionFrameLayout; import com.zms.materialdesign.observablescrollview.ui.SlidingTabLayout; import com.nineoldandroids.view.ViewHelper; /** * This uses TouchInterceptionFrameLayout to move Fragments. * <p/> * SlidingTabLayout and SlidingTabStrip are from google/iosched: * https://github.com/google/iosched */ public class FlexibleSpaceWithImageWithViewPagerTab2Activity extends BaseActivity implements ObservableScrollViewCallbacks { private static final float MAX_TEXT_SCALE_DELTA = 0.3f; private View mImageView; private View mOverlayView; private TextView mTitleView; private TouchInterceptionFrameLayout mInterceptionLayout; private ViewPager mPager; private NavigationAdapter mPagerAdapter; private int mSlop; private int mFlexibleSpaceHeight; private int mTabHeight; private boolean mScrolled; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_flexiblespacewithimagewithviewpagertab2); setSupportActionBar((Toolbar) findViewById(R.id.toolbar)); ViewCompat.setElevation(findViewById(R.id.header), getResources().getDimension(R.dimen.toolbar_elevation)); mPagerAdapter = new NavigationAdapter(getSupportFragmentManager()); mPager = (ViewPager) findViewById(R.id.pager); mPager.setAdapter(mPagerAdapter); mImageView = findViewById(R.id.image); mOverlayView = findViewById(R.id.overlay); // Padding for ViewPager must be set outside the ViewPager itself // because with padding, EdgeEffect of ViewPager become strange. mFlexibleSpaceHeight = getResources().getDimensionPixelSize(R.dimen.flexible_space_image_height); mTabHeight = getResources().getDimensionPixelSize(R.dimen.tab_height); findViewById(R.id.pager_wrapper).setPadding(0, mFlexibleSpaceHeight, 0, 0); mTitleView = (TextView) findViewById(R.id.title); mTitleView.setText(getTitle()); setTitle(null); SlidingTabLayout slidingTabLayout = (SlidingTabLayout) findViewById(R.id.sliding_tabs); slidingTabLayout.setCustomTabView(R.layout.tab_indicator, android.R.id.text1); slidingTabLayout.setSelectedIndicatorColors(getResources().getColor(R.color.accent)); slidingTabLayout.setDistributeEvenly(true); slidingTabLayout.setViewPager(mPager); ((FrameLayout.LayoutParams) slidingTabLayout.getLayoutParams()).topMargin = mFlexibleSpaceHeight - mTabHeight; ViewConfiguration vc = ViewConfiguration.get(this); mSlop = vc.getScaledTouchSlop(); mInterceptionLayout = (TouchInterceptionFrameLayout) findViewById(R.id.container); mInterceptionLayout.setScrollInterceptionListener(mInterceptionListener); ScrollUtils.addOnGlobalLayoutListener(mInterceptionLayout, new Runnable() { @Override public void run() { updateFlexibleSpace(); } }); } @Override public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) { } @Override public void onDownMotionEvent() { } @Override public void onUpOrCancelMotionEvent(ScrollState scrollState) { } private TouchInterceptionFrameLayout.TouchInterceptionListener mInterceptionListener = new TouchInterceptionFrameLayout.TouchInterceptionListener() { @Override public boolean shouldInterceptTouchEvent(MotionEvent ev, boolean moving, float diffX, float diffY) { if (!mScrolled && mSlop < Math.abs(diffX) && Math.abs(diffY) < Math.abs(diffX)) { // Horizontal scroll is maybe handled by ViewPager return false; } Scrollable scrollable = getCurrentScrollable(); if (scrollable == null) { mScrolled = false; return false; } // If interceptionLayout can move, it should intercept. // And once it begins to move, horizontal scroll shouldn't work any longer. int flexibleSpace = mFlexibleSpaceHeight - mTabHeight; int translationY = (int) ViewHelper.getTranslationY(mInterceptionLayout); boolean scrollingUp = 0 < diffY; boolean scrollingDown = diffY < 0; if (scrollingUp) { if (translationY < 0) { mScrolled = true; return true; } } else if (scrollingDown) { if (-flexibleSpace < translationY) { mScrolled = true; return true; } } mScrolled = false; return false; } @Override public void onDownMotionEvent(MotionEvent ev) { } @Override public void onMoveMotionEvent(MotionEvent ev, float diffX, float diffY) { int flexibleSpace = mFlexibleSpaceHeight - mTabHeight; float translationY = ScrollUtils.getFloat(ViewHelper.getTranslationY(mInterceptionLayout) + diffY, -flexibleSpace, 0); updateFlexibleSpace(translationY); if (translationY < 0) { FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mInterceptionLayout.getLayoutParams(); lp.height = (int) (-translationY + getScreenHeight()); mInterceptionLayout.requestLayout(); } } @Override public void onUpOrCancelMotionEvent(MotionEvent ev) { mScrolled = false; } }; private Scrollable getCurrentScrollable() { Fragment fragment = getCurrentFragment(); if (fragment == null) { return null; } View view = fragment.getView(); if (view == null) { return null; } return (Scrollable) view.findViewById(R.id.scroll); } private void updateFlexibleSpace() { updateFlexibleSpace(ViewHelper.getTranslationY(mInterceptionLayout)); } private void updateFlexibleSpace(float translationY) { ViewHelper.setTranslationY(mInterceptionLayout, translationY); int minOverlayTransitionY = getActionBarSize() - mOverlayView.getHeight(); ViewHelper.setTranslationY(mImageView, ScrollUtils.getFloat(-translationY / 2, minOverlayTransitionY, 0)); // Change alpha of overlay float flexibleRange = mFlexibleSpaceHeight - getActionBarSize(); ViewHelper.setAlpha(mOverlayView, ScrollUtils.getFloat(-translationY / flexibleRange, 0, 1)); // Scale title text float scale = 1 + ScrollUtils.getFloat((flexibleRange + translationY - mTabHeight) / flexibleRange, 0, MAX_TEXT_SCALE_DELTA); setPivotXToTitle(); ViewHelper.setPivotY(mTitleView, 0); ViewHelper.setScaleX(mTitleView, scale); ViewHelper.setScaleY(mTitleView, scale); } private Fragment getCurrentFragment() { return mPagerAdapter.getItemAt(mPager.getCurrentItem()); } @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) private void setPivotXToTitle() { Configuration config = getResources().getConfiguration(); if (Build.VERSION_CODES.JELLY_BEAN_MR1 <= Build.VERSION.SDK_INT && config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) { ViewHelper.setPivotX(mTitleView, findViewById(android.R.id.content).getWidth()); } else { ViewHelper.setPivotX(mTitleView, 0); } } /** * This adapter provides two types of fragments as an example. * {@linkplain #createItem(int)} should be modified if you use this example for your app. */ private static class NavigationAdapter extends CacheFragmentStatePagerAdapter { private static final String[] TITLES = new String[] { "Applepie", "Butter Cookie", "Cupcake", "Donut", "Eclair", "Froyo", "Gingerbread", "Honeycomb", "Ice Cream Sandwich", "Jelly Bean", "KitKat", "Lollipop" }; public NavigationAdapter(FragmentManager fm) { super(fm); } @Override protected Fragment createItem(int position) { Fragment f; final int pattern = position % 5; switch (pattern) { case 0: f = new ViewPagerTab2ScrollViewFragment(); break; case 1: f = new ViewPagerTab2ListViewFragment(); break; case 2: f = new ViewPagerTab2RecyclerViewFragment(); break; case 3: f = new ViewPagerTab2GridViewFragment(); break; case 4: default: f = new ViewPagerTab2WebViewFragment(); break; } return f; } @Override public int getCount() { return TITLES.length; } @Override public CharSequence getPageTitle(int position) { return TITLES[position]; } } }