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.nomapp.nomapp_beta.RecipePreview; import android.content.Intent; import android.content.SharedPreferences; import android.database.Cursor; import android.os.Bundle; import android.provider.ContactsContract; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBarDrawerToggle; import android.support.v7.widget.Toolbar; import android.view.View; import android.view.Window; import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.AdapterView; import android.widget.FrameLayout; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks; import com.github.ksoichiro.android.observablescrollview.ScrollState; import com.github.ksoichiro.android.observablescrollview.ScrollUtils; import com.github.ksoichiro.android.observablescrollview.Scrollable; import com.melnykov.fab.FloatingActionButton; import com.nineoldandroids.animation.ValueAnimator; import com.nineoldandroids.view.ViewHelper; import com.nineoldandroids.view.ViewPropertyAnimator; import com.nomapp.nomapp_beta.CategoriesOfRecipes.CategoriesOfRecipesActivity; import com.nomapp.nomapp_beta.Database.Database; import com.nomapp.nomapp_beta.NavigationDrawer.NavDrawerListAdapter; import com.nomapp.nomapp_beta.R; import com.nomapp.nomapp_beta.Start.StartActivity; import com.nomapp.nomapp_beta.Steps.TabsActivity; /** * Warning: This example does not work on Android 2.3. * * @param <S> Scrollable */ public abstract class FillGapBaseActivity<S extends Scrollable> extends BaseActivity implements ObservableScrollViewCallbacks { protected View mHeader; protected int mFlexibleSpaceImageHeight; protected View mHeaderBar; protected View mListBackgroundView; protected int mActionBarSize; protected int mIntersectionHeight; private View mImage; private View mHeaderBackground; private int mPrevScrollY; private boolean mGapIsChanging; private boolean mGapHidden; private boolean mReady; ActionBarDrawerToggle mDrawerToggle; ListView mDrawerList; DrawerLayout mDrawerLayout; Toolbar mToolbar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getLayoutResId()); Window window = getWindow(); // window.setStatusBarColor(getResources().getColor(R.color.notification)); mFlexibleSpaceImageHeight = getResources().getDimensionPixelSize(R.dimen.flexible_space_image_height); mActionBarSize = getActionBarSize(); //TODO // Even when the top gap has began to change, header bar still can move // within mIntersectionHeight. mIntersectionHeight = getResources().getDimensionPixelSize(R.dimen.intersection_height); mImage = findViewById(R.id.image); mHeader = findViewById(R.id.header); mHeaderBar = findViewById(R.id.header_bar); mHeaderBackground = findViewById(R.id.header_background); mListBackgroundView = findViewById(R.id.list_background); final S scrollable = createScrollable(); setUpTitle(); ScrollUtils.addOnGlobalLayoutListener((View) scrollable, new Runnable() { @Override public void run() { mReady = true; updateViews(scrollable.getCurrentScrollY(), false); } }); setUpNavigationDraver(); } void setUpNavigationDraver() { mToolbar = new Toolbar(this); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerLayout.setStatusBarBackgroundColor(getResources().getColor(R.color.notification)); mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, 0, 0); mDrawerToggle.setDrawerIndicatorEnabled(true); mDrawerLayout.setDrawerListener(mDrawerToggle); mDrawerList = (ListView) findViewById(R.id.nav_drawer_list_view); // Set the adapter for the list view mDrawerList.setAdapter(new NavDrawerListAdapter(this)); // Click events for Navigation Drawer (now available only on start screen) mDrawerList.setOnItemClickListener(new DrawerItemClickListener()); } private class DrawerItemClickListener implements ListView.OnItemClickListener { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { navDrawerSelectItem(i); } } // private void navDrawerSelectItem(int position) { switch (position) { case 0: mDrawerLayout.closeDrawers(); Intent toStartActivity = new Intent(FillGapBaseActivity.this, StartActivity.class); startActivity(toStartActivity); break; case 1: mDrawerLayout.closeDrawers(); Intent toAllRecipes = new Intent(FillGapBaseActivity.this, CategoriesOfRecipesActivity.class); startActivity(toAllRecipes); break; default: break; } } private void setUpTitle() { Cursor cursor = Database.getDatabase().getGeneralDb().query(Database.getRecipesTableName(), new String[] { Database.getRecipesName() }, null, null, null, null, null); Intent data = getIntent(); cursor.moveToPosition(data.getIntExtra("numberOfRecipe", 0) - 1); ((TextView) findViewById(R.id.title)).setText(cursor.getString(0)); cursor.close(); setTitle(null); } protected abstract int getLayoutResId(); protected abstract S createScrollable(); @Override public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) { updateViews(scrollY, true); } @Override public void onDownMotionEvent() { } @Override public void onUpOrCancelMotionEvent(ScrollState scrollState) { } protected void updateViews(int scrollY, boolean animated) { // If it's ListView, onScrollChanged is called before ListView is laid out (onGlobalLayout). // This causes weird animation when onRestoreInstanceState occurred, // so we check if it's laid out already. if (!mReady) { return; } // Translate image ViewHelper.setTranslationY(mImage, -scrollY / 2); // Translate header ViewHelper.setTranslationY(mHeader, getHeaderTranslationY(scrollY)); //TODO // Show/hide gap final int headerHeight = mHeaderBar.getHeight(); boolean scrollUp = mPrevScrollY < scrollY; if (scrollUp) { if (mFlexibleSpaceImageHeight - headerHeight - mActionBarSize <= scrollY) { changeHeaderBackgroundHeightAnimated(false, animated); } } else { if (scrollY <= mFlexibleSpaceImageHeight - headerHeight - mActionBarSize) { changeHeaderBackgroundHeightAnimated(true, animated); } } mPrevScrollY = scrollY; } protected float getHeaderTranslationY(int scrollY) { final int headerHeight = mHeaderBar.getHeight(); int headerTranslationY = mActionBarSize - mIntersectionHeight; if (0 <= -scrollY + mFlexibleSpaceImageHeight - headerHeight - mActionBarSize + mIntersectionHeight) { headerTranslationY = -scrollY + mFlexibleSpaceImageHeight - headerHeight; } return headerTranslationY; } private void changeHeaderBackgroundHeightAnimated(boolean shouldShowGap, boolean animated) { if (mGapIsChanging) { return; } final int heightOnGapShown = mHeaderBar.getHeight(); final int heightOnGapHidden = mHeaderBar.getHeight() + mActionBarSize; final float from = mHeaderBackground.getLayoutParams().height; final float to; if (shouldShowGap) { if (!mGapHidden) { // Already shown return; } to = heightOnGapShown; } else { if (mGapHidden) { // Already hidden return; } to = heightOnGapHidden; } if (animated) { ViewPropertyAnimator.animate(mHeaderBackground).cancel(); ValueAnimator a = ValueAnimator.ofFloat(from, to); a.setDuration(100); a.setInterpolator(new AccelerateDecelerateInterpolator()); a.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float height = (float) animation.getAnimatedValue(); changeHeaderBackgroundHeight(height, to, heightOnGapHidden); } }); a.start(); } else { changeHeaderBackgroundHeight(to, to, heightOnGapHidden); } } private void changeHeaderBackgroundHeight(float height, float to, float heightOnGapHidden) { FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mHeaderBackground.getLayoutParams(); lp.height = (int) height; lp.topMargin = (int) (mHeaderBar.getHeight() - height); mHeaderBackground.requestLayout(); mGapIsChanging = (height != to); if (!mGapIsChanging) { mGapHidden = (height == heightOnGapHidden); } } }