Android Open Source - Skeleton Skeleton Activity






From Project

Back to project page Skeleton.

License

The source code is released under:

Apache License

If you think the Android project Skeleton listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.gordon.skeleton;
//from  ww w .  j a va  2s  .  co m
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.gordon.skeleton.annotations.AnnotationHelper;
import com.gordon.skeleton.annotations.MenuLayout;
import com.gordon.skeleton.containers.Container;
import com.gordon.skeleton.flow.FlowBundler;
import com.gordon.skeleton.flow.GsonParcer;
import com.gordon.skeleton.screens.Screen;
import com.gordon.skeleton.screens.ScreenManager;
import com.gordon.skeleton.utils.SkeletonDialog;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import flow.Backstack;
import flow.Flow;

/**
 * Created by kg on 11/26/14.
 */
public abstract class SkeletonActivity extends ActionBarActivity implements Flow.Listener, ScreenManager {

    protected abstract Container setContentView();

    private Menu menu;

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

        initFlow(savedInstanceState);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        saveFlow(outState);
        saveDialogs(outState);
    }

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

        restoreDialogs(savedInstanceState);
    }

    @Override
    public void onBackPressed() {
        if (!goBack()) {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        this.menu = menu;
        invalidateMenu();
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem menuItem) {
        if (getCurrentScreen().onOptionsItemSelected(menuItem)) return true;

        switch (menuItem.getItemId()) {
            case android.R.id.home:
                if (!goBack()) {
                    finish();
                }
                return true;
            default:
                return super.onOptionsItemSelected(menuItem);
        }
    }

    /**
     ======================================================
     Flow
     ======================================================
     */

    private FlowBundler flowBundler;
    private Container container;

    private void initFlow(Bundle savedInstanceState) {
        container = setContentView();
        flowBundler = new FlowBundler(container.getDefaultScreen(), this, new GsonParcer<>(new Gson()));
        flowBundler.onCreate(savedInstanceState);
        flowBundler.getFlow().resetTo(getCurrentScreen());
    }

    private void saveFlow(Bundle outState) {
        flowBundler.onSaveInstanceState(outState);
    }

    @Override
    public void go(Backstack nextBackstack, Flow.Direction direction, Flow.Callback callback) {
        dismissAllDialogs();

        Screen screen = (Screen) nextBackstack.current().getScreen();
        container.showScreen(screen);
        callback.onComplete();

        invalidateMenu();
        invalidateTitles();
    }

    @Override
    public boolean goBack() {
        return flowBundler.getFlow().goBack();
    }

    @Override
    public void showScreen(Screen screen) {
        flowBundler.getFlow().goTo(screen);
    }

    @Override
    public void invalidateTitles() {
        setTitle(getCurrentScreen().getTitle(this));
    }

    @Override
    public void setDisplayHomeAsUpEnabled(boolean enabled) {
        getSupportActionBar().setDisplayHomeAsUpEnabled(enabled);
    }

    private Screen getCurrentScreen() {
        return (Screen) flowBundler.getFlow().getBackstack().current().getScreen();
    }

    private void invalidateMenu() {
        if (menu != null) {
            menu.clear();
            MenuLayout menuLayout = AnnotationHelper.getAnnotation(getCurrentScreen(), MenuLayout.class);
            if (menuLayout != null) {
                getMenuInflater().inflate(menuLayout.value(), menu);
            }
        }
    }

    /**
     =======================================================
     Dialogs
     =======================================================
     */

    private static final String KEY_SAVED_DIALOGS = "key_saved_dialogs";
    private Map<Dialog, SkeletonDialog> dialogs = new HashMap<>();

    @Override
    public void showDialog(SkeletonDialog skeletonDialog) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setCancelable(skeletonDialog.cancelable);
        if (skeletonDialog.title > 0) builder.setTitle(skeletonDialog.title);
        if (skeletonDialog.message > 0) builder.setTitle(skeletonDialog.message);
        for (Map.Entry<SkeletonDialog.ButtonType, Integer> entry : skeletonDialog.buttons.entrySet()) {
            DialogInterface.OnClickListener onClickListener = getOnDialogClickListener(skeletonDialog);
            switch (entry.getKey()) {
                case POSITIVE:
                    builder.setPositiveButton(entry.getValue(), onClickListener);
                    break;
                case NEGATIVE:
                    builder.setNegativeButton(entry.getValue(), onClickListener);
                    break;
                case NEUTRAL:
                    builder.setNeutralButton(entry.getValue(), onClickListener);
                    break;
            }
        }
        AlertDialog dialog = builder.create();
        dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialog) {
                dialogs.remove(dialog); // TODO make sure this works
            }
        });
        dialog.show();

        dialogs.put(dialog, skeletonDialog);
    }

    private DialogInterface.OnClickListener getOnDialogClickListener(final SkeletonDialog skeletonDialog) {
        return new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Screen screen = getCurrentScreen();
                if (screen != null && screen instanceof SkeletonDialog.OnClickListener) {
                    ((SkeletonDialog.OnClickListener) screen).onDialogClick(skeletonDialog);
                }
            }
        };
    }

    /**
     * Note: Will only call OnDismissListener
     */
    private void dismissAllDialogs() {
        for (Map.Entry<Dialog, SkeletonDialog> entry : dialogs.entrySet()) {
            entry.getKey().dismiss();
        }
        dialogs.clear();
    }

    private void saveDialogs(Bundle outState) {
        outState.putString(KEY_SAVED_DIALOGS, new Gson().toJson(dialogs.values()));
    }

    private void restoreDialogs(Bundle savedInstanceState) {
        List<SkeletonDialog> skeletonDialogs = new Gson().fromJson(savedInstanceState.getString(KEY_SAVED_DIALOGS),
                new TypeToken<ArrayList<SkeletonDialog>>() {
                }.getType());
        for (SkeletonDialog dialog : skeletonDialogs) {
            showDialog(dialog);
        }
    }
}




Java Source Code List

com.gordon.skeleton.ApplicationTest.java
com.gordon.skeleton.SkeletonActivity.java
com.gordon.skeleton.annotations.AnnotationHelper.java
com.gordon.skeleton.annotations.LayoutHelper.java
com.gordon.skeleton.annotations.MenuLayout.java
com.gordon.skeleton.containers.Container.java
com.gordon.skeleton.flow.FlowBundler.java
com.gordon.skeleton.flow.GsonParcer.java
com.gordon.skeleton.presenters.Presenter.java
com.gordon.skeleton.screens.ScreenManager.java
com.gordon.skeleton.screens.ScreenSwitcher.java
com.gordon.skeleton.screens.Screen.java
com.gordon.skeleton.utils.SkeletonDialog.java