by.gdgminsk.animationguide.ContactDetailsActivity.java Source code

Java tutorial

Introduction

Here is the source code for by.gdgminsk.animationguide.ContactDetailsActivity.java

Source

/*
 * Copyright 2015 GDG Minsk
 *
 * 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 by.gdgminsk.animationguide;

import android.content.Intent;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.AppBarLayout;
import android.support.v4.view.ViewCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.transition.CircularPropagation;
import android.transition.Explode;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

import com.squareup.picasso.Callback;
import com.squareup.picasso.Picasso;

import by.gdgminsk.animationguide.adapter.ContactDetailsAdapter;
import by.gdgminsk.animationguide.data.Contact;
import by.gdgminsk.animationguide.util.AnimUtils;
import by.gdgminsk.animationguide.widget.ObservableCollapsingToolbarLayout;

public class ContactDetailsActivity extends BaseActivity {

    private static final String LOG_TAG = "ContactDetailsActivity";

    public static final String EXTRA_CONTACT = "contact";

    private static final String KEY_INITIAL_ORIENTATION = "initial_orientation";

    private View mOverlay;
    private AppBarLayout mAppBarLayout;
    private ImageView mPhotoView;

    private int mCurrentOrientation;
    private int mInitialOrientation;
    private float mCurrentCollapsingRate;

    private final View.OnClickListener mPhotoClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mAppBarLayout.setExpanded(mCurrentCollapsingRate != 0);
        }
    };

    private final ObservableCollapsingToolbarLayout.OnScrollListener mOnScrollListener = new ObservableCollapsingToolbarLayout.OnScrollListener() {
        @Override
        public void onScroll(float collapsingRate, ObservableCollapsingToolbarLayout.ScrollDirection direction) {
            mCurrentCollapsingRate = collapsingRate;
            if (collapsingRate < 0.5) {
                mOverlay.setVisibility(View.GONE);
            } else {
                mOverlay.setVisibility(View.VISIBLE);
                mOverlay.setAlpha(2 * collapsingRate - 1);
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
                && getResources().getBoolean(R.bool.translucent_status)) {
            int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
            getWindow().getDecorView().setSystemUiVisibility(flags);
        }

        setContentView(R.layout.activity_contact_details);
        mCurrentOrientation = getResources().getConfiguration().orientation;
        boolean land = mCurrentOrientation == Configuration.ORIENTATION_LANDSCAPE;
        if (savedInstanceState == null) {
            mInitialOrientation = mCurrentOrientation;
        } else {
            mInitialOrientation = savedInstanceState.getInt(KEY_INITIAL_ORIENTATION);
        }

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        ActionBar ab = getSupportActionBar();
        // getSupportActionBar() can't return null here because we set it one row above
        //noinspection ConstantConditions
        ab.setDisplayHomeAsUpEnabled(true);

        Intent intent = getIntent();
        Contact contact = intent.getParcelableExtra(EXTRA_CONTACT);
        if (contact == null) {
            Log.e(LOG_TAG, "contact is not provided");
            finish();
            return;
        }

        mAppBarLayout = (AppBarLayout) findViewById(R.id.app_bar);
        mOverlay = findViewById(R.id.overlay);
        mPhotoView = (ImageView) findViewById(R.id.contact_photo);
        RecyclerView detailsList = (RecyclerView) findViewById(R.id.details_list);
        detailsList.setAdapter(new ContactDetailsAdapter(contact, this));
        if (!land) {
            ObservableCollapsingToolbarLayout collapsingToolbar = (ObservableCollapsingToolbarLayout) findViewById(
                    R.id.toolbar_layout);
            collapsingToolbar.setOnScrollListener(mOnScrollListener);
            mPhotoView.setOnClickListener(mPhotoClickListener);
        }

        ab.setTitle(contact.getName());
        loadPhoto(contact);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt(KEY_INITIAL_ORIENTATION, mInitialOrientation);
    }

    @Override
    public boolean onSupportNavigateUp() {
        exit();
        return true;
    }

    @Override
    public void onBackPressed() {
        exit();
    }

    private void loadPhoto(final Contact contact) {
        Picasso.with(this).load(contact.getPhotoPreview()).noFade().into(mPhotoView, new Callback() {
            @Override
            public void onSuccess() {
                Picasso.with(ContactDetailsActivity.this).load(contact.getPhoto()).noFade().noPlaceholder()
                        .into(mPhotoView);
            }

            @Override
            public void onError() {
                Log.e(LOG_TAG, "Unable to load image for contact = " + contact);
            }
        });
    }

    private void exit() {
        if (mInitialOrientation != mCurrentOrientation || mCurrentCollapsingRate > 0.9f) {
            // remove tranistion name on exit to let activity explode insted of playing
            // reverse shared element animation. Better override return transition and
            // not to play shared element back because if returning activity recreated
            // there is a glitch because the end coordinate of shared element may not exist
            ViewCompat.setTransitionName(mPhotoView, null);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                Explode transition = new Explode();
                transition.setPropagation(new CircularPropagation());
                transition.setDuration(getResources().getInteger(R.integer.duration_explode));
                transition.setInterpolator(AnimUtils.EASE_OUT_INTERPOLATOR);
                getWindow().setReturnTransition(transition);
            }
        }
        supportFinishAfterTransition();
    }
}