com.smoothsync.smoothsetup.MicroFragmentHostActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.smoothsync.smoothsetup.MicroFragmentHostActivity.java

Source

/*
 * Copyright (c) 2017 dmfs GmbH
 *
 * 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.smoothsync.smoothsetup;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.CollapsingToolbarLayout;
import android.support.v4.widget.NestedScrollView;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;
import android.view.View;
import android.widget.FrameLayout;

import org.dmfs.android.microfragments.MicroFragment;
import org.dmfs.android.microfragments.MicroFragmentHost;
import org.dmfs.android.microfragments.MicroFragmentState;
import org.dmfs.android.microfragments.SimpleMicroFragmentFlow;
import org.dmfs.android.microfragments.transitions.BackTransition;
import org.dmfs.android.microfragments.utils.BooleanDovecote;
import org.dmfs.pigeonpost.Dovecote;
import org.dmfs.pigeonpost.localbroadcast.ParcelableDovecote;

/**
 * An {@link Activity} that hosts a {@link MicroFragment}.
 *
 * @author Marten Gajda
 */
public final class MicroFragmentHostActivity extends AppCompatActivity
        implements Dovecote.OnPigeonReturnCallback<MicroFragmentState> {
    private CollapsingToolbarLayout mCollapsingToolbar;
    private ActionBar mActionBar;
    private Dovecote<MicroFragmentState> mMicroFragmentStateDovecote;
    private Dovecote<Boolean> mBackDovecote;
    private MicroFragmentHost mMicroFragmentHost;
    private NestedScrollView mFragmentHostView;
    private AppBarLayout mAppBarLayout;

    public static void launch(@NonNull Context context, @NonNull MicroFragment<?> microFragment) {
        Intent intent = new Intent(context, MicroFragmentHostActivity.class);
        Bundle nestedBundle = new Bundle();
        nestedBundle.putParcelable("MicroFragment", microFragment);
        intent.putExtra("org.dmfs.nestedExtras", nestedBundle);
        intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.smoothsetup_activity_microfragment_host);

        mCollapsingToolbar = findViewById(R.id.collapsing_toolbar);
        setSupportActionBar(mCollapsingToolbar.findViewById(R.id.toolbar));
        mActionBar = getSupportActionBar();
        mMicroFragmentStateDovecote = new ParcelableDovecote<>(this, "hostactivity", this);
        mBackDovecote = new BooleanDovecote(this, "backresult", aBoolean -> {
            if (!aBoolean) {
                finish();
            }
        });

        if (savedInstanceState == null) {
            // load the initial MicroFragment
            Bundle nestedExtras = getIntent().getBundleExtra("org.dmfs.nestedExtras");
            MicroFragment<?> initialMicroFragment = nestedExtras.getParcelable("MicroFragment");
            mMicroFragmentHost = new SimpleMicroFragmentFlow(initialMicroFragment, R.id.microfragment_host)
                    .withPigeonCage(mMicroFragmentStateDovecote.cage()).start(this);
        } else {
            mMicroFragmentHost = savedInstanceState.getParcelable("microfragmenthost");
        }
        mAppBarLayout = findViewById(R.id.appbar);
        mFragmentHostView = findViewById(R.id.microfragment_host);
        mFragmentHostView.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
            // collapse appbar if the microfragment content doesn't fit on the screen
            Rect windowRect = new Rect();
            mAppBarLayout.getWindowVisibleDisplayFrame(windowRect);

            FrameLayout bottomView = mFragmentHostView
                    .findViewById(org.dmfs.android.microfragments.R.id.microfragments_host);
            if (bottomView.getChildCount() > 0) {
                View childView = bottomView.getChildAt(0);
                Rect childRect = new Rect();
                childView.getGlobalVisibleRect(childRect);
                if (!"collapsed".equals(childView.getTag()) && !windowRect.contains(childRect)) {
                    mAppBarLayout.postDelayed(() -> mAppBarLayout.setExpanded(false, true), 100);
                    // tag the child as "collapsed" so we don't collapse it again while visible
                    childView.setTag("collapsed");
                }
            }
        });
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelable("microfragmenthost", mMicroFragmentHost);
    }

    @Override
    protected void onDestroy() {
        mMicroFragmentStateDovecote.dispose();
        mBackDovecote.dispose();
        super.onDestroy();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            mMicroFragmentHost.execute(this, new BackTransition());
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onBackPressed() {
        mMicroFragmentHost.execute(this, new BackTransition(mBackDovecote.cage()));
    }

    @Override
    public void onPigeonReturn(@NonNull MicroFragmentState microFragmentState) {
        mCollapsingToolbar.setTitle(microFragmentState.currentStep().title(this));
        mActionBar.setTitle(microFragmentState.currentStep().title(this));
        mActionBar.setDisplayHomeAsUpEnabled(microFragmentState.backStackSize() > 0);
        mActionBar.setDisplayShowHomeEnabled(microFragmentState.backStackSize() > 0);
    }
}