165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/* 265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Copyright (C) 2014 The Android Open Source Project 365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Licensed under the Apache License, Version 2.0 (the "License"); 565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * you may not use this file except in compliance with the License. 665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * You may obtain a copy of the License at 765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * http://www.apache.org/licenses/LICENSE-2.0 965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 1065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Unless required by applicable law or agreed to in writing, software 1165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * distributed under the License is distributed on an "AS IS" BASIS, 1265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * See the License for the specific language governing permissions and 1465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * limitations under the License. 1565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 1665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepackage com.android.tv.settings.dialog.old; 1865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.app.Fragment; 2065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.app.FragmentManager; 2165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.app.FragmentManager.OnBackStackChangedListener; 2265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.app.FragmentTransaction; 2365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.Context; 2465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.Intent; 2565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.graphics.Color; 2665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.graphics.drawable.ColorDrawable; 2765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.net.Uri; 2865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.Build; 2965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.Bundle; 30eae3ba62fcf7a7f159a9337bda08f38ce75b275eTony Mantlerimport android.support.annotation.NonNull; 3165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.LayoutInflater; 3265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.View; 3365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.ViewGroup; 3465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.animation.Interpolator; 3565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 3665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.R; 3762f1e6e5e7071c9b95911e2ab3120a42e269d53eLeif Hendrik Wildenimport com.android.tv.settings.core.instrumentation.InstrumentedActivity; 3865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 3965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.ArrayList; 4065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 4165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/** 4265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * A DialogActivity has 2 fragments, a content fragment and a list fragment. 4365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * <p> 4465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Subclasses should override to supply the content fragment and list items. 4565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * <p> 4665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * The DialogActivity will handle animating in and out. 4765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * <p> 4865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * This class will use a default layout, but a custom layout can be provided by 4965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * calling {@link #setLayoutProperties} 5065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 5162f1e6e5e7071c9b95911e2ab3120a42e269d53eLeif Hendrik Wildenpublic abstract class DialogActivity extends InstrumentedActivity 5265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane implements ActionAdapter.Listener, OnBackStackChangedListener { 5365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 5565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Dialog Content Fragment title. 5665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 5765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static final String EXTRA_DIALOG_TITLE = "dialog_title"; 5865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 6065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Dialog Content Fragment breadcrumb. 6165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 6265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static final String EXTRA_DIALOG_BREADCRUMB = "dialog_breadcrumb"; 6365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 6465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 6565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Dialog Content Fragment description. 6665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 6765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static final String EXTRA_DIALOG_DESCRIPTION = "dialog_description"; 6865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 6965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 7065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Dialog Content Fragment image uri. 7165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 7265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static final String EXTRA_DIALOG_IMAGE_URI = "dialog_image_uri"; 7365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 7465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 7565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Dialog Content Fragment image background color 7665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 7765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static final String EXTRA_DIALOG_IMAGE_BACKGROUND_COLOR 7865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane = "dialog_image_background_color"; 7965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 8065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 8165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Dialog Action Fragment actions starting index. 8265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 8365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static final String EXTRA_DIALOG_ACTIONS_START_INDEX = "dialog_actions_start_index"; 8465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 8565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 8665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Dialog Action Fragment actions. 8765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 8865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static final String EXTRA_PARCELABLE_ACTIONS = "parcelable_actions"; 8965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 9065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 9165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Whether DialogActivity should create Content Fragment and Action Fragment from extras. 9265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 9365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static final String EXTRA_CREATE_FRAGMENT_FROM_EXTRA = "create_fragment_from_extra"; 9465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 9565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static final String TAG_DIALOG = "tag_dialog"; 9665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static final String BACKSTACK_NAME_DIALOG = "backstack_name_dialog"; 9765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static final String KEY_BACKSTACK_COUNT = "backstack_count"; 9865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 9965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected static final int ANIMATE_IN_DURATION = 250; 10065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 10165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private DialogFragment mDialogFragment; 102eae3ba62fcf7a7f159a9337bda08f38ce75b275eTony Mantler private int mLayoutResId = R.layout.lb_dialog_fragment; 10365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private View mContent; 10465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private int mLastBackStackCount = 0; 10565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 10665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public DialogActivity() { 10765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mDialogFragment = new DialogFragment(); 10865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mDialogFragment.setActivity(this); 10965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 11065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 11165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static Intent createIntent(Context context, String title, 11265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String breadcrumb, String description, String imageUri, 11365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ArrayList<Action> actions) { 11465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return createIntent(context, title, breadcrumb, description, imageUri, 11565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Color.TRANSPARENT, actions); 11665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 11765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 11865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static Intent createIntent(Context context, String title, 11965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String breadcrumb, String description, String imageUri, 12065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int imageBackground, ArrayList<Action> actions) { 12165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Intent intent = new Intent(context, DialogActivity.class); 12265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.putExtra(EXTRA_DIALOG_TITLE, title); 12365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.putExtra(EXTRA_DIALOG_BREADCRUMB, breadcrumb); 12465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.putExtra(EXTRA_DIALOG_DESCRIPTION, description); 12565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.putExtra(EXTRA_DIALOG_IMAGE_URI, imageUri); 12665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.putExtra(EXTRA_DIALOG_IMAGE_BACKGROUND_COLOR, imageBackground); 12765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.putParcelableArrayListExtra(EXTRA_PARCELABLE_ACTIONS, actions); 12865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 12965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return intent; 13065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 13165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 13265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static Intent createIntent(Context context, String title, 13365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String breadcrumb, String description, String imageUri, 13465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ArrayList<Action> actions, Class<? extends DialogActivity> activityClass) { 13565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return createIntent(context, title, breadcrumb, description, imageUri, Color.TRANSPARENT, 13665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane actions, activityClass); 13765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 13865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 13965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static Intent createIntent(Context context, String title, 14065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String breadcrumb, String description, String imageUri, int imageBackground, 14165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ArrayList<Action> actions, Class<? extends DialogActivity> activityClass) { 14265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Intent intent = new Intent(context, activityClass); 14365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.putExtra(EXTRA_DIALOG_TITLE, title); 14465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.putExtra(EXTRA_DIALOG_BREADCRUMB, breadcrumb); 14565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.putExtra(EXTRA_DIALOG_DESCRIPTION, description); 14665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.putExtra(EXTRA_DIALOG_IMAGE_URI, imageUri); 14765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.putExtra(EXTRA_DIALOG_IMAGE_BACKGROUND_COLOR, imageBackground); 14865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.putParcelableArrayListExtra(EXTRA_PARCELABLE_ACTIONS, actions); 14965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 15065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return intent; 15165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 15265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 15365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static Intent createIntent(Context context, String title, 15465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String breadcrumb, String description, String imageUri, int imageBackground, 15565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ArrayList<Action> actions, Class<? extends DialogActivity> activityClass, 15665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int startIndex) { 15765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Intent intent = new Intent(context, activityClass); 15865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.putExtra(EXTRA_DIALOG_TITLE, title); 15965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.putExtra(EXTRA_DIALOG_BREADCRUMB, breadcrumb); 16065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.putExtra(EXTRA_DIALOG_DESCRIPTION, description); 16165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.putExtra(EXTRA_DIALOG_IMAGE_URI, imageUri); 16265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.putExtra(EXTRA_DIALOG_IMAGE_BACKGROUND_COLOR, imageBackground); 16365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.putParcelableArrayListExtra(EXTRA_PARCELABLE_ACTIONS, actions); 16465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.putExtra(EXTRA_DIALOG_ACTIONS_START_INDEX, startIndex); 16565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 16665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return intent; 16765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 16865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 16965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public View getContentView() { 17065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return mContent; 17165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 17265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 17365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 17465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void onCreate(Bundle savedInstanceState) { 17565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // TODO: replace these hardcoded values with the commented constants whenever Hangouts 17665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // updates their manifest to build against JB MR2. 17765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (Build.VERSION.SDK_INT >= 18 /* Build.VERSION_CODES.JELLY_BEAN_MR2 */) { 17865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane getWindow().addFlags(0x02000000 17965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /* WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN */); 18065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 18165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if(savedInstanceState != null) { 18265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mLastBackStackCount = savedInstanceState.getInt(KEY_BACKSTACK_COUNT); 18365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 18465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 18565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane super.onCreate(savedInstanceState); 18665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane getFragmentManager().addOnBackStackChangedListener(this); 18765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 18865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane LayoutInflater helium = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 18965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mContent = helium.inflate(mLayoutResId, null); 19065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane setContentView(mContent); 191eae3ba62fcf7a7f159a9337bda08f38ce75b275eTony Mantler if (mLayoutResId == R.layout.lb_dialog_fragment) { 19265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane helium.inflate(R.layout.dialog_container, (ViewGroup) mContent); 19365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane setDialogFragment(mDialogFragment); 19465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 19565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 19665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Bundle bundle = getIntent().getExtras(); 19765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (bundle != null) { 19865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean createFragmentFromExtra = bundle.getBoolean(EXTRA_CREATE_FRAGMENT_FROM_EXTRA); 19965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (createFragmentFromExtra) { 20065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // If intent bundle is not null, and flag indicates that should create fragments, 20165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // set ContentFragment and ActionFragment using bundle extras. 20265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String title = bundle.getString(EXTRA_DIALOG_TITLE); 20365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String breadcrumb = bundle.getString(EXTRA_DIALOG_BREADCRUMB); 20465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String description = bundle.getString(EXTRA_DIALOG_DESCRIPTION); 20565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String imageUriStr = bundle.getString(EXTRA_DIALOG_IMAGE_URI); 20665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Uri imageUri = Uri.parse(imageUriStr); 20765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int backgroundColor = bundle.getInt(EXTRA_DIALOG_IMAGE_BACKGROUND_COLOR); 20865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 20965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ArrayList<Action> actions = 21065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane bundle.getParcelableArrayList(EXTRA_PARCELABLE_ACTIONS); 21165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 21265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane setContentFragment(ContentFragment.newInstance(title, breadcrumb, 21365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane description, imageUri, backgroundColor)); 21465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 21565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane setActionFragment(ActionFragment.newInstance(actions)); 21665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 21765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 21865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 21965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 22065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 221eae3ba62fcf7a7f159a9337bda08f38ce75b275eTony Mantler protected void onSaveInstanceState(@NonNull Bundle savedInstanceState) { 22265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane super.onSaveInstanceState(savedInstanceState); 22365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane savedInstanceState.putInt(KEY_BACKSTACK_COUNT, mLastBackStackCount); 22465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 22565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 22665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 22765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void onStart() { 22865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane super.onStart(); 229eae3ba62fcf7a7f159a9337bda08f38ce75b275eTony Mantler if (mLayoutResId == R.layout.lb_dialog_fragment) { 23065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane getDialogFragment().performEntryTransition(); 23165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 23265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 23365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 23465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 23565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onBackStackChanged() { 23665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int count = getFragmentManager().getBackStackEntryCount(); 23765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (count > 0 && count < mLastBackStackCount && DialogActivity.BACKSTACK_NAME_DIALOG.equals( 23865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane getFragmentManager().getBackStackEntryAt(count - 1).getName())) { 23965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane getFragmentManager().popBackStack(); 24065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 24165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mLastBackStackCount = count; 24265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 24365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 24465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 24565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onActionClicked(Action action) { 24665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Intent intent = action.getIntent(); 24765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (intent != null) { 24865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane startActivity(intent); 24965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane finish(); 25065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 25165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 25265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 25365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 25465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Disables the entry animation that normally happens onStart(). 25565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 25665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void disableEntryAnimation() { 25765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane getDialogFragment().disableEntryAnimation(); 25865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 25965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 26065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 26165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * This method sets the layout property of this class. <br/> 26265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Activities extending {@link DialogActivity} should call this method 26365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * before calling {@link #onCreate(Bundle)} if they want to have a 26465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * custom view. 26565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 26665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param layoutResId resource if of the activity layout 26765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param contentAreaId id of the content area 26865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param actionAreaId id of the action area 26965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 27065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void setLayoutProperties(int layoutResId, int contentAreaId, int actionAreaId) { 27165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mLayoutResId = layoutResId; 27265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane getDialogFragment().setLayoutProperties(contentAreaId, actionAreaId); 27365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 27465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 27565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 27665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Animates a view. 27765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 27865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param v view to animate 27965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param initAlpha initial alpha 28065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param initTransX initial translation in the X 28165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param delay delay in ms 28265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param duration duration in ms 28365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param interpolator interpolator to be used, can be null 28465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param isIcon if {@code true}, this is the main icon being moved 28565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 28665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void prepareAndAnimateView(final View v, float initAlpha, float initTransX, int delay, 28765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int duration, Interpolator interpolator, final boolean isIcon) { 28865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane getDialogFragment().prepareAndAnimateView( 28965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane v, initAlpha, initTransX, delay, duration, interpolator, isIcon); 29065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 29165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 29265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 29365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Called when intro animation is finished. 29465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * <p> 29565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * If a subclass is going to alter the view, should wait until this is called. 29665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 29765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void onIntroAnimationFinished() { 29865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane getDialogFragment().onIntroAnimationFinished(); 29965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 30065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 30165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected boolean isIntroAnimationInProgress() { 30265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return getDialogFragment().isIntroAnimationInProgress(); 30365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 30465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 30565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected ColorDrawable getBackgroundDrawable() { 30665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return getDialogFragment().getBackgroundDrawable(); 30765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 30865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 30965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void setBackgroundDrawable(ColorDrawable drawable) { 31065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane getDialogFragment().setBackgroundDrawable(drawable); 31165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 31265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 31365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 31465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Sets the content fragment into the view. 31565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 31665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void setContentFragment(Fragment fragment) { 31765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane getDialogFragment().setContentFragment(fragment); 31865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 31965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 32065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 32165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Sets the action fragment into the view. 32265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * <p> 32365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * If an action fragment currently exists, this will be added to the back stack. 32465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 32565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void setActionFragment(Fragment fragment) { 32665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane getDialogFragment().setActionFragment(fragment); 32765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 32865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 32965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 33065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Sets the action fragment into the view. 33165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * <p> 33265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * If addToBackStack is true, and action fragment currently exists, 33365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * this will be added to the back stack. 33465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 33565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void setActionFragment(Fragment fragment, boolean addToBackStack) { 33665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane getDialogFragment().setActionFragment(fragment, addToBackStack); 33765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 33865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 33965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected Fragment getActionFragment() { 34065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return getDialogFragment().getActionFragment(); 34165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 34265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 34365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected Fragment getContentFragment() { 34465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return getDialogFragment().getContentFragment(); 34565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 34665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 34765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 34865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Set the content and action fragments in the same transaction. 34965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * <p> 35065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * If an action fragment currently exists, this will be added to the back stack. 35165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 35265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void setContentAndActionFragments(Fragment contentFragment, Fragment actionFragment) { 35365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane getDialogFragment().setContentAndActionFragments(contentFragment, actionFragment); 35465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 35565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 35665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 35765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Set the content and action fragments in the same transaction. 35865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * <p> 35965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * If addToBackStack and an action fragment currently exists, 36065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * this will be added to the back stack. 36165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 36265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void setContentAndActionFragments(Fragment contentFragment, Fragment actionFragment, 36365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean addToBackStack) { 36465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane getDialogFragment().setContentAndActionFragments( 36565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane contentFragment, actionFragment, addToBackStack); 36665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 36765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 36865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void setDialogFragment(DialogFragment fragment) { 36965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane setDialogFragment(fragment, true); 37065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 37165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 37265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void setDialogFragment(DialogFragment fragment, boolean addToBackStack) { 37365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mDialogFragment = fragment; 37465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane fragment.setActivity(this); 37565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane FragmentManager fm = getFragmentManager(); 37665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane FragmentTransaction ft = fm.beginTransaction(); 37765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean hasDialog = fm.findFragmentByTag(DialogActivity.TAG_DIALOG) != null; 37865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (hasDialog) { 37965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (addToBackStack) { 38065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ft.addToBackStack(DialogActivity.BACKSTACK_NAME_DIALOG); 38165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 38265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 38365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ft.replace(R.id.dialog_fragment, fragment, DialogActivity.TAG_DIALOG); 38465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ft.commit(); 38565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 38665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 38765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected DialogFragment getDialogFragment() { 388eae3ba62fcf7a7f159a9337bda08f38ce75b275eTony Mantler final DialogFragment fragment = 389eae3ba62fcf7a7f159a9337bda08f38ce75b275eTony Mantler (DialogFragment) getFragmentManager().findFragmentByTag(TAG_DIALOG); 390eae3ba62fcf7a7f159a9337bda08f38ce75b275eTony Mantler if (fragment != null) { 391eae3ba62fcf7a7f159a9337bda08f38ce75b275eTony Mantler mDialogFragment = fragment; 39265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 39365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 39465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return mDialogFragment; 39565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 39665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane} 397