GuidedActionsStylist.java revision 66e932ebd959ffe318f0780c5f689bac29b09b50
1ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing/* 2ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Copyright (C) 2015 The Android Open Source Project 3ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * 4ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * in compliance with the License. You may obtain a copy of the License at 6ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * 7ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * http://www.apache.org/licenses/LICENSE-2.0 8ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * 9ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Unless required by applicable law or agreed to in writing, software distributed under the License 10ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * or implied. See the License for the specific language governing permissions and limitations under 12ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * the License. 13ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 14ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingpackage android.support.v17.leanback.widget; 15ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 168e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikasimport static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP; 173103f63e99d47573823957f7aa34308555873221Aurimas Liutikasimport static android.support.v17.leanback.widget.GuidedAction.EDITING_ACTIVATOR_VIEW; 183103f63e99d47573823957f7aa34308555873221Aurimas Liutikasimport static android.support.v17.leanback.widget.GuidedAction.EDITING_DESCRIPTION; 193103f63e99d47573823957f7aa34308555873221Aurimas Liutikasimport static android.support.v17.leanback.widget.GuidedAction.EDITING_NONE; 203103f63e99d47573823957f7aa34308555873221Aurimas Liutikasimport static android.support.v17.leanback.widget.GuidedAction.EDITING_TITLE; 213103f63e99d47573823957f7aa34308555873221Aurimas Liutikas 22ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport android.animation.Animator; 23ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport android.animation.AnimatorInflater; 2466e932ebd959ffe318f0780c5f689bac29b09b50Dake Guimport android.animation.AnimatorListenerAdapter; 25ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport android.content.Context; 26ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport android.content.res.TypedArray; 27ae746be7c46297b910a99c07697e33e3a5fd7facDake Guimport android.graphics.Rect; 283103f63e99d47573823957f7aa34308555873221Aurimas Liutikasimport android.graphics.drawable.Drawable; 291ed9dc77616514e20c51baa67a04adab42e4135eDake Guimport android.os.Build.VERSION; 30ae746be7c46297b910a99c07697e33e3a5fd7facDake Guimport android.support.annotation.CallSuper; 31ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport android.support.annotation.NonNull; 32c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viveretteimport android.support.annotation.RestrictTo; 33ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport android.support.v17.leanback.R; 34ae746be7c46297b910a99c07697e33e3a5fd7facDake Guimport android.support.v17.leanback.transition.TransitionEpicenterCallback; 351ed9dc77616514e20c51baa67a04adab42e4135eDake Guimport android.support.v17.leanback.transition.TransitionHelper; 361ed9dc77616514e20c51baa67a04adab42e4135eDake Guimport android.support.v17.leanback.transition.TransitionListener; 37b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Guimport android.support.v17.leanback.widget.GuidedActionAdapter.EditListener; 38b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Guimport android.support.v17.leanback.widget.picker.DatePicker; 3911cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Guimport android.support.v4.content.ContextCompat; 40ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport android.support.v7.widget.RecyclerView; 41ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport android.text.TextUtils; 42ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport android.util.TypedValue; 431ed9dc77616514e20c51baa67a04adab42e4135eDake Guimport android.view.Gravity; 44ae746be7c46297b910a99c07697e33e3a5fd7facDake Guimport android.view.KeyEvent; 45ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport android.view.LayoutInflater; 46ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport android.view.View; 47b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Guimport android.view.View.AccessibilityDelegate; 48ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport android.view.ViewGroup; 49ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport android.view.WindowManager; 50b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Guimport android.view.accessibility.AccessibilityEvent; 51b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Guimport android.view.accessibility.AccessibilityNodeInfo; 5250c611b216a4b2c8eb2bbd2a2848bb6da34677besusnataimport android.view.inputmethod.EditorInfo; 5311cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Guimport android.widget.Checkable; 54ac07e9d12b10138d4a449522f7082a40f18861e2Kris Giesingimport android.widget.EditText; 55ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport android.widget.ImageView; 56ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport android.widget.TextView; 57ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 58b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Guimport java.util.Calendar; 59be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Guimport java.util.Collections; 60ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport java.util.List; 61ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 62ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing/** 63a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * GuidedActionsStylist is used within a {@link android.support.v17.leanback.app.GuidedStepFragment} 64a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * to supply the right-side panel where users can take actions. It consists of a container for the 65a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * list of actions, and a stationary selector view that indicates visually the location of focus. 66be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * GuidedActionsStylist has two different layouts: default is for normal actions including text, 67b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * radio, checkbox, DatePicker, etc, the other when {@link #setAsButtonActions()} is called is 68b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * recommended for button actions such as "yes", "no". 69ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <p> 70ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Many aspects of the base GuidedActionsStylist can be customized through theming; see the 71ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * theme attributes below. Note that these attributes are not set on individual elements in layout 72ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * XML, but instead would be set in a custom theme. See 73ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <a href="http://developer.android.com/guide/topics/ui/themes.html">Styles and Themes</a> 74ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * for more information. 75ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <p> 76ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * If these hooks are insufficient, this class may also be subclassed. Subclasses may wish to 77ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * override the {@link #onProvideLayoutId} method to change the layout used to display the 78b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * list container and selector; override {@link #onProvideItemLayoutId(int)} and 79b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * {@link #getItemViewType(GuidedAction)} method to change the layout used to display each action. 80b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * <p> 81b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * To support a "click to activate" view similar to DatePicker, app needs: 82b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * <li> Override {@link #onProvideItemLayoutId(int)} and {@link #getItemViewType(GuidedAction)}, 83b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * provides a layout id for the action. 84b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * <li> The layout must include a widget with id "guidedactions_activator_item", the widget is 85b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * toggled edit mode by {@link View#setActivated(boolean)}. 86b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * <li> Override {@link #onBindActivatorView(ViewHolder, GuidedAction)} to populate values into View. 87b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * <li> Override {@link #onUpdateActivatorView(ViewHolder, GuidedAction)} to update action. 88ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <p> 89ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Note: If an alternate list layout is provided, the following view IDs must be supplied: 90ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <ul> 91ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <li>{@link android.support.v17.leanback.R.id#guidedactions_list}</li> 92ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * </ul><p> 93ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * These view IDs must be present in order for the stylist to function. The list ID must correspond 94ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * to a {@link VerticalGridView} or subclass. 95ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <p> 96ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * If an alternate item layout is provided, the following view IDs should be used to refer to base 97ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * elements: 98ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <ul> 99ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <li>{@link android.support.v17.leanback.R.id#guidedactions_item_content}</li> 100ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <li>{@link android.support.v17.leanback.R.id#guidedactions_item_title}</li> 101ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <li>{@link android.support.v17.leanback.R.id#guidedactions_item_description}</li> 102ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <li>{@link android.support.v17.leanback.R.id#guidedactions_item_icon}</li> 103ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <li>{@link android.support.v17.leanback.R.id#guidedactions_item_checkmark}</li> 104ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <li>{@link android.support.v17.leanback.R.id#guidedactions_item_chevron}</li> 105ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * </ul><p> 106ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * These view IDs are allowed to be missing, in which case the corresponding views in {@link 107ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * GuidedActionsStylist.ViewHolder} will be null. 1084158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing * <p> 1094158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing * In order to support editable actions, the view associated with guidedactions_item_title should 1104158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing * be a subclass of {@link android.widget.EditText}, and should satisfy the {@link 1114158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing * ImeKeyMonitor} interface. 112ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * 1134158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedStepImeAppearingAnimation 1144158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedStepImeDisappearingAnimation 1151db5382081756ee276c1fb88f5ebdbc138b70249Dake Gu * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionsSelectorDrawable 116ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionsListStyle 117be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedSubActionsListStyle 118be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedButtonActionsListStyle 119ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionItemContainerStyle 120ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionItemCheckmarkStyle 121ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionItemIconStyle 122ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionItemContentStyle 123ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionItemTitleStyle 124ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionItemDescriptionStyle 125ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionItemChevronStyle 126ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionPressedAnimation 127ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionUnpressedAnimation 128ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionEnabledChevronAlpha 129ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionDisabledChevronAlpha 130ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionTitleMinLines 131ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionTitleMaxLines 132ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionDescriptionMinLines 133ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionVerticalPadding 13411cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * @see android.R.styleable#Theme_listChoiceIndicatorSingle 13511cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * @see android.R.styleable#Theme_listChoiceIndicatorMultiple 136ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @see android.support.v17.leanback.app.GuidedStepFragment 137ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @see GuidedAction 138ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 139ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingpublic class GuidedActionsStylist implements FragmentAnimationProvider { 140ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 141ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 142e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * Default viewType that associated with default layout Id for the action item. 143e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * @see #getItemViewType(GuidedAction) 144e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * @see #onProvideItemLayoutId(int) 145e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * @see #onCreateViewHolder(ViewGroup, int) 146e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu */ 147e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu public static final int VIEW_TYPE_DEFAULT = 0; 148e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu 149e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu /** 150b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * ViewType for DatePicker. 151b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu */ 152b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu public static final int VIEW_TYPE_DATE_PICKER = 1; 153b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu 15450c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata final static ItemAlignmentFacet sGuidedActionItemAlignFacet; 15550c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata static { 15650c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata sGuidedActionItemAlignFacet = new ItemAlignmentFacet(); 15750c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata ItemAlignmentFacet.ItemAlignmentDef alignedDef = new ItemAlignmentFacet.ItemAlignmentDef(); 15850c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata alignedDef.setItemAlignmentViewId(R.id.guidedactions_item_title); 15950c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata alignedDef.setAlignedToTextViewBaseline(true); 16050c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata alignedDef.setItemAlignmentOffset(0); 16150c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata alignedDef.setItemAlignmentOffsetWithPadding(true); 16250c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata alignedDef.setItemAlignmentOffsetPercent(0); 16350c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata sGuidedActionItemAlignFacet.setAlignmentDefs(new ItemAlignmentFacet.ItemAlignmentDef[]{alignedDef}); 16450c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata } 16550c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata 166b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu /** 167ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * ViewHolder caches information about the action item layouts' subviews. Subclasses of {@link 168ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * GuidedActionsStylist} may also wish to subclass this in order to add fields. 169ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @see GuidedAction 170ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 17150c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata public static class ViewHolder extends RecyclerView.ViewHolder implements FacetProvider { 172ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 17399ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas GuidedAction mAction; 174ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private View mContentView; 17599ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas TextView mTitleView; 17699ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas TextView mDescriptionView; 17799ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas View mActivatorView; 17899ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas ImageView mIconView; 17999ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas ImageView mCheckmarkView; 18099ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas ImageView mChevronView; 18199ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas int mEditingMode = EDITING_NONE; 182be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu private final boolean mIsSubAction; 18366e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu Animator mPressAnimator; 184ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 185b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu final AccessibilityDelegate mDelegate = new AccessibilityDelegate() { 186b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu @Override 187b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) { 188b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu super.onInitializeAccessibilityEvent(host, event); 189b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu event.setChecked(mAction != null && mAction.isChecked()); 190b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu } 191b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu 192b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu @Override 193b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { 194b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu super.onInitializeAccessibilityNodeInfo(host, info); 195b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu info.setCheckable( 196b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu mAction != null && mAction.getCheckSetId() != GuidedAction.NO_CHECK_SET); 197b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu info.setChecked(mAction != null && mAction.isChecked()); 198b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu } 199b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu }; 200b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu 201ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 202ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Constructs an ViewHolder and caches the relevant subviews. 203ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 204ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public ViewHolder(View v) { 205be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu this(v, false); 206be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 207be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu 208be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu /** 209be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * Constructs an ViewHolder for sub action and caches the relevant subviews. 210be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu */ 211be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu public ViewHolder(View v, boolean isSubAction) { 212be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu super(v); 213ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 214ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mContentView = v.findViewById(R.id.guidedactions_item_content); 215ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mTitleView = (TextView) v.findViewById(R.id.guidedactions_item_title); 216b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu mActivatorView = v.findViewById(R.id.guidedactions_activator_item); 217ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mDescriptionView = (TextView) v.findViewById(R.id.guidedactions_item_description); 218ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mIconView = (ImageView) v.findViewById(R.id.guidedactions_item_icon); 219ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mCheckmarkView = (ImageView) v.findViewById(R.id.guidedactions_item_checkmark); 220ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mChevronView = (ImageView) v.findViewById(R.id.guidedactions_item_chevron); 221be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu mIsSubAction = isSubAction; 222b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu 223b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu v.setAccessibilityDelegate(mDelegate); 224ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 225ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 226ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 227ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Returns the content view within this view holder's view, where title and description are 228ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * shown. 229ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 230ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public View getContentView() { 231ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return mContentView; 232ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 233ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 234ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 235ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Returns the title view within this view holder's view. 236ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 237ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public TextView getTitleView() { 238ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return mTitleView; 239ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 240ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 241ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 242ac07e9d12b10138d4a449522f7082a40f18861e2Kris Giesing * Convenience method to return an editable version of the title, if possible, 243ac07e9d12b10138d4a449522f7082a40f18861e2Kris Giesing * or null if the title view isn't an EditText. 244ac07e9d12b10138d4a449522f7082a40f18861e2Kris Giesing */ 245ac07e9d12b10138d4a449522f7082a40f18861e2Kris Giesing public EditText getEditableTitleView() { 246ac07e9d12b10138d4a449522f7082a40f18861e2Kris Giesing return (mTitleView instanceof EditText) ? (EditText)mTitleView : null; 247ac07e9d12b10138d4a449522f7082a40f18861e2Kris Giesing } 248ac07e9d12b10138d4a449522f7082a40f18861e2Kris Giesing 249ac07e9d12b10138d4a449522f7082a40f18861e2Kris Giesing /** 250ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Returns the description view within this view holder's view. 251ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 252ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public TextView getDescriptionView() { 253ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return mDescriptionView; 254ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 255ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 256ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 257c1741246af607f6be2389056da0182c40f938348Dake Gu * Convenience method to return an editable version of the description, if possible, 258c1741246af607f6be2389056da0182c40f938348Dake Gu * or null if the description view isn't an EditText. 259c1741246af607f6be2389056da0182c40f938348Dake Gu */ 260c1741246af607f6be2389056da0182c40f938348Dake Gu public EditText getEditableDescriptionView() { 261c1741246af607f6be2389056da0182c40f938348Dake Gu return (mDescriptionView instanceof EditText) ? (EditText)mDescriptionView : null; 262c1741246af607f6be2389056da0182c40f938348Dake Gu } 263c1741246af607f6be2389056da0182c40f938348Dake Gu 264c1741246af607f6be2389056da0182c40f938348Dake Gu /** 265ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Returns the icon view within this view holder's view. 266ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 267ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public ImageView getIconView() { 268ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return mIconView; 269ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 270ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 271ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 272ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Returns the checkmark view within this view holder's view. 273ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 274ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public ImageView getCheckmarkView() { 275ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return mCheckmarkView; 276ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 277ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 278ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 279ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Returns the chevron view within this view holder's view. 280ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 281ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public ImageView getChevronView() { 282ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return mChevronView; 283ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 284ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 285c1741246af607f6be2389056da0182c40f938348Dake Gu /** 286b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * Returns true if in editing title, description, or activator View, false otherwise. 287c1741246af607f6be2389056da0182c40f938348Dake Gu */ 288c1741246af607f6be2389056da0182c40f938348Dake Gu public boolean isInEditing() { 289b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu return mEditingMode != EDITING_NONE; 290b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 291b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu 292b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu /** 293b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * Returns true if in editing title, description, so IME would be open. 294b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * @return True if in editing title, description, so IME would be open, false otherwise. 295b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu */ 296b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu public boolean isInEditingText() { 297b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu return mEditingMode == EDITING_TITLE || mEditingMode == EDITING_DESCRIPTION; 298b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 299b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu 300b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu /** 301b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * Returns true if the TextView is in editing title, false otherwise. 302b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu */ 303b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu public boolean isInEditingTitle() { 304b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu return mEditingMode == EDITING_TITLE; 305c1741246af607f6be2389056da0182c40f938348Dake Gu } 306c1741246af607f6be2389056da0182c40f938348Dake Gu 307c1741246af607f6be2389056da0182c40f938348Dake Gu /** 308c1741246af607f6be2389056da0182c40f938348Dake Gu * Returns true if the TextView is in editing description, false otherwise. 309c1741246af607f6be2389056da0182c40f938348Dake Gu */ 310c1741246af607f6be2389056da0182c40f938348Dake Gu public boolean isInEditingDescription() { 311b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu return mEditingMode == EDITING_DESCRIPTION; 312b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 313b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu 314b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu /** 315b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * Returns true if is in editing activator view with id guidedactions_activator_item, false 316b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * otherwise. 317b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu */ 318b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu public boolean isInEditingActivatorView() { 319b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu return mEditingMode == EDITING_ACTIVATOR_VIEW; 320c1741246af607f6be2389056da0182c40f938348Dake Gu } 321c1741246af607f6be2389056da0182c40f938348Dake Gu 322be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu /** 323b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * @return Current editing title view or description view or activator view or null if not 324b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * in editing. 325be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu */ 326c1741246af607f6be2389056da0182c40f938348Dake Gu public View getEditingView() { 327b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu switch(mEditingMode) { 328b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu case EDITING_TITLE: 329b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu return mTitleView; 330b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu case EDITING_DESCRIPTION: 331b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu return mDescriptionView; 332b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu case EDITING_ACTIVATOR_VIEW: 333b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu return mActivatorView; 334b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu case EDITING_NONE: 335b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu default: 336c1741246af607f6be2389056da0182c40f938348Dake Gu return null; 337c1741246af607f6be2389056da0182c40f938348Dake Gu } 338c1741246af607f6be2389056da0182c40f938348Dake Gu } 339be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu 340be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu /** 341be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * @return True if bound action is inside {@link GuidedAction#getSubActions()}, false 342be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * otherwise. 343be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu */ 344be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu public boolean isSubAction() { 345be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu return mIsSubAction; 346be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 347be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu 348be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu /** 349be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * @return Currently bound action. 350be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu */ 351be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu public GuidedAction getAction() { 352be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu return mAction; 353be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 3540f96ae4965103bade4bebe7776b2ee35cd603112Dake Gu 3550f96ae4965103bade4bebe7776b2ee35cd603112Dake Gu void setActivated(boolean activated) { 3560f96ae4965103bade4bebe7776b2ee35cd603112Dake Gu mActivatorView.setActivated(activated); 3570f96ae4965103bade4bebe7776b2ee35cd603112Dake Gu if (itemView instanceof GuidedActionItemContainer) { 3580f96ae4965103bade4bebe7776b2ee35cd603112Dake Gu ((GuidedActionItemContainer) itemView).setFocusOutAllowed(!activated); 3590f96ae4965103bade4bebe7776b2ee35cd603112Dake Gu } 3600f96ae4965103bade4bebe7776b2ee35cd603112Dake Gu } 36150c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata 36250c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata @Override 36350c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata public Object getFacet(Class<?> facetClass) { 36450c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata if (facetClass == ItemAlignmentFacet.class) { 36550c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata return sGuidedActionItemAlignFacet; 36650c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata } 36750c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata return null; 36850c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata } 36966e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu 37066e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu void press(boolean pressed) { 37166e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu if (mPressAnimator != null) { 37266e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu mPressAnimator.cancel(); 37366e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu mPressAnimator = null; 37466e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu } 37566e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu final int themeAttrId = pressed ? R.attr.guidedActionPressedAnimation : 37666e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu R.attr.guidedActionUnpressedAnimation; 37766e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu Context ctx = itemView.getContext(); 37866e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu TypedValue typedValue = new TypedValue(); 37966e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu if (ctx.getTheme().resolveAttribute(themeAttrId, typedValue, true)) { 38066e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu mPressAnimator = AnimatorInflater.loadAnimator(ctx, typedValue.resourceId); 38166e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu mPressAnimator.setTarget(itemView); 38266e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu mPressAnimator.addListener(new AnimatorListenerAdapter() { 38366e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu @Override 38466e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu public void onAnimationEnd(Animator animation) { 38566e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu mPressAnimator = null; 38666e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu } 38766e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu }); 38866e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu mPressAnimator.start(); 38966e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu } 39066e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu } 391ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 392ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 393ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private static String TAG = "GuidedActionsStylist"; 394ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 39599ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas ViewGroup mMainView; 3960b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu private VerticalGridView mActionsGridView; 39799ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas VerticalGridView mSubActionsGridView; 398fa4d2cddf2cb9619088153a1fe07d09203d792faDake Gu private View mSubActionsBackground; 3990b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu private View mBgView; 4008e5ae27d6db125867640b672cc97d4a158fdfd48Dake Gu private View mContentView; 4010b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu private boolean mButtonActions; 402ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 403ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing // Cached values from resources 404c1741246af607f6be2389056da0182c40f938348Dake Gu private float mEnabledTextAlpha; 405c1741246af607f6be2389056da0182c40f938348Dake Gu private float mDisabledTextAlpha; 406c1741246af607f6be2389056da0182c40f938348Dake Gu private float mEnabledDescriptionAlpha; 407c1741246af607f6be2389056da0182c40f938348Dake Gu private float mDisabledDescriptionAlpha; 408ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private float mEnabledChevronAlpha; 409ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private float mDisabledChevronAlpha; 410ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private int mTitleMinLines; 411ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private int mTitleMaxLines; 412ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private int mDescriptionMinLines; 413ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private int mVerticalPadding; 414ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private int mDisplayHeight; 415ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 416b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu private EditListener mEditListener; 417b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu 418be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu private GuidedAction mExpandedAction = null; 41999ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas Object mExpandTransition; 420ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu private boolean mBackToCollapseSubActions = true; 421ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu private boolean mBackToCollapseActivatorView = true; 422ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 423ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu private float mKeyLinePercent; 424be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu 425ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 426ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Creates a view appropriate for displaying a list of GuidedActions, using the provided 427ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * inflater and container. 428ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <p> 429ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <i>Note: Does not actually add the created view to the container; the caller should do 430ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * this.</i> 431ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @param inflater The layout inflater to be used when constructing the view. 432ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @param container The view group to be passed in the call to 433ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <code>LayoutInflater.inflate</code>. 434ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @return The view to be added to the caller's view hierarchy. 435ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 43650c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata public View onCreateView(LayoutInflater inflater, final ViewGroup container) { 43750c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata TypedArray ta = inflater.getContext().getTheme().obtainStyledAttributes( 43850c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata R.styleable.LeanbackGuidedStepTheme); 43950c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata float keylinePercent = ta.getFloat(R.styleable.LeanbackGuidedStepTheme_guidedStepKeyline, 44050c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata 40); 4418e5ae27d6db125867640b672cc97d4a158fdfd48Dake Gu mMainView = (ViewGroup) inflater.inflate(onProvideLayoutId(), container, false); 442be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu mContentView = mMainView.findViewById(mButtonActions ? R.id.guidedactions_content2 : 443be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu R.id.guidedactions_content); 444be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu mBgView = mMainView.findViewById(mButtonActions ? R.id.guidedactions_list_background2 : 445be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu R.id.guidedactions_list_background); 446ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing if (mMainView instanceof VerticalGridView) { 447ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mActionsGridView = (VerticalGridView) mMainView; 448ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } else { 4493103f63e99d47573823957f7aa34308555873221Aurimas Liutikas mActionsGridView = (VerticalGridView) mMainView.findViewById(mButtonActions 4503103f63e99d47573823957f7aa34308555873221Aurimas Liutikas ? R.id.guidedactions_list2 : R.id.guidedactions_list); 451ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing if (mActionsGridView == null) { 452ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing throw new IllegalStateException("No ListView exists."); 453ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 45450c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata mActionsGridView.setWindowAlignmentOffsetPercent(keylinePercent); 455ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mActionsGridView.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_NO_EDGE); 456be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu if (!mButtonActions) { 457be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu mSubActionsGridView = (VerticalGridView) mMainView.findViewById( 458be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu R.id.guidedactions_sub_list); 459fa4d2cddf2cb9619088153a1fe07d09203d792faDake Gu mSubActionsBackground = mMainView.findViewById( 460fa4d2cddf2cb9619088153a1fe07d09203d792faDake Gu R.id.guidedactions_sub_list_background); 461ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 462ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 463015eaf265571c84b5d37311f58bc69b2eb4af8d4Dake Gu mActionsGridView.setFocusable(false); 464015eaf265571c84b5d37311f58bc69b2eb4af8d4Dake Gu mActionsGridView.setFocusableInTouchMode(false); 465ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 466ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing // Cache widths, chevron alpha values, max and min text lines, etc 467ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing Context ctx = mMainView.getContext(); 468ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing TypedValue val = new TypedValue(); 469ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mEnabledChevronAlpha = getFloat(ctx, val, R.attr.guidedActionEnabledChevronAlpha); 470ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mDisabledChevronAlpha = getFloat(ctx, val, R.attr.guidedActionDisabledChevronAlpha); 471ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mTitleMinLines = getInteger(ctx, val, R.attr.guidedActionTitleMinLines); 472ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mTitleMaxLines = getInteger(ctx, val, R.attr.guidedActionTitleMaxLines); 473ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mDescriptionMinLines = getInteger(ctx, val, R.attr.guidedActionDescriptionMinLines); 474ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mVerticalPadding = getDimension(ctx, val, R.attr.guidedActionVerticalPadding); 475ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mDisplayHeight = ((WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE)) 476ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing .getDefaultDisplay().getHeight(); 477ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 478c1741246af607f6be2389056da0182c40f938348Dake Gu mEnabledTextAlpha = Float.valueOf(ctx.getResources().getString(R.string 479c1741246af607f6be2389056da0182c40f938348Dake Gu .lb_guidedactions_item_unselected_text_alpha)); 480c1741246af607f6be2389056da0182c40f938348Dake Gu mDisabledTextAlpha = Float.valueOf(ctx.getResources().getString(R.string 481c1741246af607f6be2389056da0182c40f938348Dake Gu .lb_guidedactions_item_disabled_text_alpha)); 482c1741246af607f6be2389056da0182c40f938348Dake Gu mEnabledDescriptionAlpha = Float.valueOf(ctx.getResources().getString(R.string 483c1741246af607f6be2389056da0182c40f938348Dake Gu .lb_guidedactions_item_unselected_description_text_alpha)); 484c1741246af607f6be2389056da0182c40f938348Dake Gu mDisabledDescriptionAlpha = Float.valueOf(ctx.getResources().getString(R.string 485c1741246af607f6be2389056da0182c40f938348Dake Gu .lb_guidedactions_item_disabled_description_text_alpha)); 486ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 487ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu mKeyLinePercent = GuidanceStylingRelativeLayout.getKeyLinePercent(ctx); 488ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (mContentView instanceof GuidedActionsRelativeLayout) { 489ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu ((GuidedActionsRelativeLayout) mContentView).setInterceptKeyEventListener( 490ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu new GuidedActionsRelativeLayout.InterceptKeyEventListener() { 491ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu @Override 492ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu public boolean onInterceptKeyEvent(KeyEvent event) { 493ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (event.getKeyCode() == KeyEvent.KEYCODE_BACK 494ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu && event.getAction() == KeyEvent.ACTION_UP 495ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu && mExpandedAction != null) { 496ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if ((mExpandedAction.hasSubActions() 4973103f63e99d47573823957f7aa34308555873221Aurimas Liutikas && isBackKeyToCollapseSubActions()) 4983103f63e99d47573823957f7aa34308555873221Aurimas Liutikas || (mExpandedAction.hasEditableActivatorView() 499ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu && isBackKeyToCollapseActivatorView())) { 500ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu collapseAction(true); 501ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu return true; 502ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 503ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 504ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu return false; 505ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 506ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 507ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu ); 508ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 509ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return mMainView; 510ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 511ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 5120b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu /** 513be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * Choose the layout resource for button actions in {@link #onProvideLayoutId()}. 5140b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu */ 5150b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu public void setAsButtonActions() { 516be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu if (mMainView != null) { 517be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu throw new IllegalStateException("setAsButtonActions() must be called before creating " 518be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu + "views"); 5198e5ae27d6db125867640b672cc97d4a158fdfd48Dake Gu } 520be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu mButtonActions = true; 5210b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu } 5220b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu 5230b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu /** 524be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * Returns true if it is button actions list, false for normal actions list. 525be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * @return True if it is button actions list, false for normal actions list. 5260b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu */ 5270b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu public boolean isButtonActions() { 5280b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu return mButtonActions; 5290b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu } 5300b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu 531d14724d33d61385c27a00c31bbc67ad8eeb57b3cDake Gu /** 532d14724d33d61385c27a00c31bbc67ad8eeb57b3cDake Gu * Called when destroy the View created by GuidedActionsStylist. 533d14724d33d61385c27a00c31bbc67ad8eeb57b3cDake Gu */ 534d14724d33d61385c27a00c31bbc67ad8eeb57b3cDake Gu public void onDestroyView() { 535be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu mExpandedAction = null; 5361ed9dc77616514e20c51baa67a04adab42e4135eDake Gu mExpandTransition = null; 53743e10e99e55c1c2eeca31fa13e9cc84160850f59Dake Gu mActionsGridView = null; 538be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu mSubActionsGridView = null; 539fa4d2cddf2cb9619088153a1fe07d09203d792faDake Gu mSubActionsBackground = null; 5408e5ae27d6db125867640b672cc97d4a158fdfd48Dake Gu mContentView = null; 54143e10e99e55c1c2eeca31fa13e9cc84160850f59Dake Gu mBgView = null; 54243e10e99e55c1c2eeca31fa13e9cc84160850f59Dake Gu mMainView = null; 543d14724d33d61385c27a00c31bbc67ad8eeb57b3cDake Gu } 544d14724d33d61385c27a00c31bbc67ad8eeb57b3cDake Gu 545ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 546ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Returns the VerticalGridView that displays the list of GuidedActions. 547ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @return The VerticalGridView for this presenter. 548ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 549ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public VerticalGridView getActionsGridView() { 550ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return mActionsGridView; 551ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 552ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 553ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 554be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * Returns the VerticalGridView that displays the sub actions list of an expanded action. 555be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * @return The VerticalGridView that displays the sub actions list of an expanded action. 556be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu */ 557be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu public VerticalGridView getSubActionsGridView() { 558be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu return mSubActionsGridView; 559be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 560be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu 561be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu /** 562ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Provides the resource ID of the layout defining the host view for the list of guided actions. 563ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Subclasses may override to provide their own customized layouts. The base implementation 564be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * returns {@link android.support.v17.leanback.R.layout#lb_guidedactions} or 565be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * {@link android.support.v17.leanback.R.layout#lb_guidedbuttonactions} if 566be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * {@link #isButtonActions()} is true. If overridden, the substituted layout should contain 567be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * matching IDs for any views that should be managed by the base class; this can be achieved by 568be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * starting with a copy of the base layout file. 569be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * 570be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * @return The resource ID of the layout to be inflated to define the host view for the list of 571be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * GuidedActions. 572ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 573ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public int onProvideLayoutId() { 574be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu return mButtonActions ? R.layout.lb_guidedbuttonactions : R.layout.lb_guidedactions; 575ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 576ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 577ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 578e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * Return view type of action, each different type can have differently associated layout Id. 579e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * Default implementation returns {@link #VIEW_TYPE_DEFAULT}. 580e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * @param action The action object. 581e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * @return View type that used in {@link #onProvideItemLayoutId(int)}. 582e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu */ 583e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu public int getItemViewType(GuidedAction action) { 584b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (action instanceof GuidedDatePickerAction) { 585b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu return VIEW_TYPE_DATE_PICKER; 586b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 587e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu return VIEW_TYPE_DEFAULT; 588e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu } 589e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu 590e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu /** 591ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Provides the resource ID of the layout defining the view for an individual guided actions. 592ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Subclasses may override to provide their own customized layouts. The base implementation 593ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * returns {@link android.support.v17.leanback.R.layout#lb_guidedactions_item}. If overridden, 594ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * the substituted layout should contain matching IDs for any views that should be managed by 595ac07e9d12b10138d4a449522f7082a40f18861e2Kris Giesing * the base class; this can be achieved by starting with a copy of the base layout file. Note 596ac07e9d12b10138d4a449522f7082a40f18861e2Kris Giesing * that in order for the item to support editing, the title view should both subclass {@link 597ac07e9d12b10138d4a449522f7082a40f18861e2Kris Giesing * android.widget.EditText} and implement {@link ImeKeyMonitor}; see {@link 598e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * GuidedActionEditText}. To support different types of Layouts, override {@link 599e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * #onProvideItemLayoutId(int)}. 600ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @return The resource ID of the layout to be inflated to define the view to display an 601ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * individual GuidedAction. 602ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 603ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public int onProvideItemLayoutId() { 604ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return R.layout.lb_guidedactions_item; 605ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 606ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 607ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 608e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * Provides the resource ID of the layout defining the view for an individual guided actions. 609e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * Subclasses may override to provide their own customized layouts. The base implementation 610b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * supports: 611b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * <li>{@link android.support.v17.leanback.R.layout#lb_guidedactions_item} 612b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * <li>{{@link android.support.v17.leanback.R.layout#lb_guidedactions_datepicker_item}. If 613b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * overridden, the substituted layout should contain matching IDs for any views that should be 614b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * managed by the base class; this can be achieved by starting with a copy of the base layout 615b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * file. Note that in order for the item to support editing, the title view should both subclass 616b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * {@link android.widget.EditText} and implement {@link ImeKeyMonitor}; see 617b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * {@link GuidedActionEditText}. 618b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * 619e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * @param viewType View type returned by {@link #getItemViewType(GuidedAction)} 620e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * @return The resource ID of the layout to be inflated to define the view to display an 621b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * individual GuidedAction. 622e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu */ 623e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu public int onProvideItemLayoutId(int viewType) { 624e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu if (viewType == VIEW_TYPE_DEFAULT) { 625e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu return onProvideItemLayoutId(); 626b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } else if (viewType == VIEW_TYPE_DATE_PICKER) { 627b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu return R.layout.lb_guidedactions_datepicker_item; 628e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu } else { 6293103f63e99d47573823957f7aa34308555873221Aurimas Liutikas throw new RuntimeException("ViewType " + viewType 6303103f63e99d47573823957f7aa34308555873221Aurimas Liutikas + " not supported in GuidedActionsStylist"); 631e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu } 632e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu } 633e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu 634e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu /** 635ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Constructs a {@link ViewHolder} capable of representing {@link GuidedAction}s. Subclasses 636e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * may choose to return a subclass of ViewHolder. To support different view types, override 637e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * {@link #onCreateViewHolder(ViewGroup, int)} 638ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <p> 639ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <i>Note: Should not actually add the created view to the parent; the caller will do 640ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * this.</i> 641ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @param parent The view group to be used as the parent of the new view. 642ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @return The view to be added to the caller's view hierarchy. 643ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 644ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public ViewHolder onCreateViewHolder(ViewGroup parent) { 645ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing LayoutInflater inflater = LayoutInflater.from(parent.getContext()); 646ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing View v = inflater.inflate(onProvideItemLayoutId(), parent, false); 647be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu return new ViewHolder(v, parent == mSubActionsGridView); 648ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 649ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 650ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 651e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * Constructs a {@link ViewHolder} capable of representing {@link GuidedAction}s. Subclasses 652e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * may choose to return a subclass of ViewHolder. 653e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * <p> 654e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * <i>Note: Should not actually add the created view to the parent; the caller will do 655e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * this.</i> 656e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * @param parent The view group to be used as the parent of the new view. 657e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * @param viewType The viewType returned by {@link #getItemViewType(GuidedAction)} 658e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * @return The view to be added to the caller's view hierarchy. 659e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu */ 660e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 661e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu if (viewType == VIEW_TYPE_DEFAULT) { 662e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu return onCreateViewHolder(parent); 663e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu } 664e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu LayoutInflater inflater = LayoutInflater.from(parent.getContext()); 665e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu View v = inflater.inflate(onProvideItemLayoutId(viewType), parent, false); 666be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu return new ViewHolder(v, parent == mSubActionsGridView); 667e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu } 668e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu 669e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu /** 670ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Binds a {@link ViewHolder} to a particular {@link GuidedAction}. 671ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @param vh The view holder to be associated with the given action. 672ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @param action The guided action to be displayed by the view holder's view. 673ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @return The view to be added to the caller's view hierarchy. 674ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 675ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public void onBindViewHolder(ViewHolder vh, GuidedAction action) { 676ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 677be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu vh.mAction = action; 678ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing if (vh.mTitleView != null) { 679ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing vh.mTitleView.setText(action.getTitle()); 680c1741246af607f6be2389056da0182c40f938348Dake Gu vh.mTitleView.setAlpha(action.isEnabled() ? mEnabledTextAlpha : mDisabledTextAlpha); 6816626b899cb2565105f20e4ee2060a5104826d1ddDake Gu vh.mTitleView.setFocusable(false); 682ed6ddac644df9949403f1a01e1224a37cb568febDake Gu vh.mTitleView.setClickable(false); 683ed6ddac644df9949403f1a01e1224a37cb568febDake Gu vh.mTitleView.setLongClickable(false); 684ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 685ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing if (vh.mDescriptionView != null) { 686ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing vh.mDescriptionView.setText(action.getDescription()); 6873103f63e99d47573823957f7aa34308555873221Aurimas Liutikas vh.mDescriptionView.setVisibility(TextUtils.isEmpty(action.getDescription()) 6883103f63e99d47573823957f7aa34308555873221Aurimas Liutikas ? View.GONE : View.VISIBLE); 689c1741246af607f6be2389056da0182c40f938348Dake Gu vh.mDescriptionView.setAlpha(action.isEnabled() ? mEnabledDescriptionAlpha : 690c1741246af607f6be2389056da0182c40f938348Dake Gu mDisabledDescriptionAlpha); 6916626b899cb2565105f20e4ee2060a5104826d1ddDake Gu vh.mDescriptionView.setFocusable(false); 692ed6ddac644df9949403f1a01e1224a37cb568febDake Gu vh.mDescriptionView.setClickable(false); 693ed6ddac644df9949403f1a01e1224a37cb568febDake Gu vh.mDescriptionView.setLongClickable(false); 694ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 695ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing // Clients might want the check mark view to be gone entirely, in which case, ignore it. 69611cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu if (vh.mCheckmarkView != null) { 69711cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu onBindCheckMarkView(vh, action); 698ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 699023bf7d01378f30a63dce3d0a1112eb56bd6b99fDake Gu setIcon(vh.mIconView, action); 700ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 701ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing if (action.hasMultilineDescription()) { 702ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing if (vh.mTitleView != null) { 703918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu setMaxLines(vh.mTitleView, mTitleMaxLines); 704ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing if (vh.mDescriptionView != null) { 705be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu vh.mDescriptionView.setMaxHeight(getDescriptionMaxHeight( 706be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu vh.itemView.getContext(), vh.mTitleView)); 707ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 708ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 709ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } else { 710ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing if (vh.mTitleView != null) { 711918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu setMaxLines(vh.mTitleView, mTitleMinLines); 712ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 713ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing if (vh.mDescriptionView != null) { 714918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu setMaxLines(vh.mDescriptionView, mDescriptionMinLines); 715ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 716ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 717b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (vh.mActivatorView != null) { 718b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu onBindActivatorView(vh, action); 719b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 720ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu setEditingMode(vh, false /*editing*/, false /*withTransition*/); 7217af424644dc8daae5298a5ca2f655770270366feDake Gu if (action.isFocusable()) { 722be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu vh.itemView.setFocusable(true); 723be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu ((ViewGroup) vh.itemView).setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS); 7247af424644dc8daae5298a5ca2f655770270366feDake Gu } else { 725be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu vh.itemView.setFocusable(false); 726be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu ((ViewGroup) vh.itemView).setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); 7277af424644dc8daae5298a5ca2f655770270366feDake Gu } 7284705eed4421d3b00923b56062765206dea21387eDake Gu setupImeOptions(vh, action); 729be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu 730be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu updateChevronAndVisibility(vh); 7314705eed4421d3b00923b56062765206dea21387eDake Gu } 7324705eed4421d3b00923b56062765206dea21387eDake Gu 733918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu private static void setMaxLines(TextView view, int maxLines) { 734918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu // setSingleLine must be called before setMaxLines because it resets maximum to 735918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu // Integer.MAX_VALUE. 736918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu if (maxLines == 1) { 737918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu view.setSingleLine(true); 738918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu } else { 739918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu view.setSingleLine(false); 740918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu view.setMaxLines(maxLines); 741918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu } 742918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu } 743918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu 7444705eed4421d3b00923b56062765206dea21387eDake Gu /** 7454705eed4421d3b00923b56062765206dea21387eDake Gu * Called by {@link #onBindViewHolder(ViewHolder, GuidedAction)} to setup IME options. Default 7464705eed4421d3b00923b56062765206dea21387eDake Gu * implementation assigns {@link EditorInfo#IME_ACTION_DONE}. Subclass may override. 7474705eed4421d3b00923b56062765206dea21387eDake Gu * @param vh The view holder to be associated with the given action. 7484705eed4421d3b00923b56062765206dea21387eDake Gu * @param action The guided action to be displayed by the view holder's view. 7494705eed4421d3b00923b56062765206dea21387eDake Gu */ 7504705eed4421d3b00923b56062765206dea21387eDake Gu protected void setupImeOptions(ViewHolder vh, GuidedAction action) { 7514705eed4421d3b00923b56062765206dea21387eDake Gu setupNextImeOptions(vh.getEditableTitleView()); 7524705eed4421d3b00923b56062765206dea21387eDake Gu setupNextImeOptions(vh.getEditableDescriptionView()); 7534705eed4421d3b00923b56062765206dea21387eDake Gu } 7544705eed4421d3b00923b56062765206dea21387eDake Gu 7554705eed4421d3b00923b56062765206dea21387eDake Gu private void setupNextImeOptions(EditText edit) { 7564705eed4421d3b00923b56062765206dea21387eDake Gu if (edit != null) { 7574705eed4421d3b00923b56062765206dea21387eDake Gu edit.setImeOptions(EditorInfo.IME_ACTION_NEXT); 7584705eed4421d3b00923b56062765206dea21387eDake Gu } 759c1741246af607f6be2389056da0182c40f938348Dake Gu } 760c1741246af607f6be2389056da0182c40f938348Dake Gu 76177d397d533d04dfec663939692f2e048a072ee5bAlan Viverette /** 76277d397d533d04dfec663939692f2e048a072ee5bAlan Viverette * @deprecated This method is for internal library use only and should not 76377d397d533d04dfec663939692f2e048a072ee5bAlan Viverette * be called directly. 76477d397d533d04dfec663939692f2e048a072ee5bAlan Viverette */ 76577d397d533d04dfec663939692f2e048a072ee5bAlan Viverette @Deprecated 76677d397d533d04dfec663939692f2e048a072ee5bAlan Viverette public void setEditingMode(ViewHolder vh, GuidedAction action, boolean editing) { 76777d397d533d04dfec663939692f2e048a072ee5bAlan Viverette if (editing != vh.isInEditing() && isInExpandTransition()) { 76877d397d533d04dfec663939692f2e048a072ee5bAlan Viverette onEditingModeChange(vh, action, editing); 76977d397d533d04dfec663939692f2e048a072ee5bAlan Viverette } 77077d397d533d04dfec663939692f2e048a072ee5bAlan Viverette } 77177d397d533d04dfec663939692f2e048a072ee5bAlan Viverette 772ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu void setEditingMode(ViewHolder vh, boolean editing) { 773ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu setEditingMode(vh, editing, true /*withTransition*/); 774ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 775ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 776ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu void setEditingMode(ViewHolder vh, boolean editing, boolean withTransition) { 777b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (editing != vh.isInEditing() && !isInExpandTransition()) { 778ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu onEditingModeChange(vh, editing, withTransition); 779c1741246af607f6be2389056da0182c40f938348Dake Gu } 780c1741246af607f6be2389056da0182c40f938348Dake Gu } 781c1741246af607f6be2389056da0182c40f938348Dake Gu 782ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu /** 783ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @deprecated Use {@link #onEditingModeChange(ViewHolder, boolean, boolean)}. 784ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu */ 785ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu @Deprecated 786c1741246af607f6be2389056da0182c40f938348Dake Gu protected void onEditingModeChange(ViewHolder vh, GuidedAction action, boolean editing) { 787ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 788ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 789ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu /** 790ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * Called when editing mode of an ViewHolder is changed. Subclass must call 791ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * <code>super.onEditingModeChange(vh,editing,withTransition)</code>. 792ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * 793ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @param vh ViewHolder to change editing mode. 794ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @param editing True to enable editing, false to stop editing 795ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @param withTransition True to run expand transiiton, false otherwise. 796ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu */ 797ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu @CallSuper 798ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu protected void onEditingModeChange(ViewHolder vh, boolean editing, boolean withTransition) { 799ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu GuidedAction action = vh.getAction(); 800c1741246af607f6be2389056da0182c40f938348Dake Gu TextView titleView = vh.getTitleView(); 801c1741246af607f6be2389056da0182c40f938348Dake Gu TextView descriptionView = vh.getDescriptionView(); 802c1741246af607f6be2389056da0182c40f938348Dake Gu if (editing) { 803c1741246af607f6be2389056da0182c40f938348Dake Gu CharSequence editTitle = action.getEditTitle(); 804c1741246af607f6be2389056da0182c40f938348Dake Gu if (titleView != null && editTitle != null) { 805c1741246af607f6be2389056da0182c40f938348Dake Gu titleView.setText(editTitle); 806c1741246af607f6be2389056da0182c40f938348Dake Gu } 807c1741246af607f6be2389056da0182c40f938348Dake Gu CharSequence editDescription = action.getEditDescription(); 808c1741246af607f6be2389056da0182c40f938348Dake Gu if (descriptionView != null && editDescription != null) { 809c1741246af607f6be2389056da0182c40f938348Dake Gu descriptionView.setText(editDescription); 810c1741246af607f6be2389056da0182c40f938348Dake Gu } 811c1741246af607f6be2389056da0182c40f938348Dake Gu if (action.isDescriptionEditable()) { 812c1741246af607f6be2389056da0182c40f938348Dake Gu if (descriptionView != null) { 813c1741246af607f6be2389056da0182c40f938348Dake Gu descriptionView.setVisibility(View.VISIBLE); 8149562425bf9bc15281ac27df817141854769c1042Dake Gu descriptionView.setInputType(action.getDescriptionEditInputType()); 815c1741246af607f6be2389056da0182c40f938348Dake Gu } 816b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu vh.mEditingMode = EDITING_DESCRIPTION; 817b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } else if (action.isEditable()){ 8189562425bf9bc15281ac27df817141854769c1042Dake Gu if (titleView != null) { 8199562425bf9bc15281ac27df817141854769c1042Dake Gu titleView.setInputType(action.getEditInputType()); 8209562425bf9bc15281ac27df817141854769c1042Dake Gu } 821b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu vh.mEditingMode = EDITING_TITLE; 822b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } else if (vh.mActivatorView != null) { 823ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu onEditActivatorView(vh, editing, withTransition); 824b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu vh.mEditingMode = EDITING_ACTIVATOR_VIEW; 825c1741246af607f6be2389056da0182c40f938348Dake Gu } 826c1741246af607f6be2389056da0182c40f938348Dake Gu } else { 827c1741246af607f6be2389056da0182c40f938348Dake Gu if (titleView != null) { 828c1741246af607f6be2389056da0182c40f938348Dake Gu titleView.setText(action.getTitle()); 829c1741246af607f6be2389056da0182c40f938348Dake Gu } 830c1741246af607f6be2389056da0182c40f938348Dake Gu if (descriptionView != null) { 831c1741246af607f6be2389056da0182c40f938348Dake Gu descriptionView.setText(action.getDescription()); 832c1741246af607f6be2389056da0182c40f938348Dake Gu } 833b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (vh.mEditingMode == EDITING_DESCRIPTION) { 834c1741246af607f6be2389056da0182c40f938348Dake Gu if (descriptionView != null) { 8353103f63e99d47573823957f7aa34308555873221Aurimas Liutikas descriptionView.setVisibility(TextUtils.isEmpty(action.getDescription()) 8363103f63e99d47573823957f7aa34308555873221Aurimas Liutikas ? View.GONE : View.VISIBLE); 8379562425bf9bc15281ac27df817141854769c1042Dake Gu descriptionView.setInputType(action.getDescriptionInputType()); 838c1741246af607f6be2389056da0182c40f938348Dake Gu } 839b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } else if (vh.mEditingMode == EDITING_TITLE) { 8409562425bf9bc15281ac27df817141854769c1042Dake Gu if (titleView != null) { 8419562425bf9bc15281ac27df817141854769c1042Dake Gu titleView.setInputType(action.getInputType()); 8429562425bf9bc15281ac27df817141854769c1042Dake Gu } 843b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } else if (vh.mEditingMode == EDITING_ACTIVATOR_VIEW) { 844b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (vh.mActivatorView != null) { 845ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu onEditActivatorView(vh, editing, withTransition); 846b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 847c1741246af607f6be2389056da0182c40f938348Dake Gu } 848b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu vh.mEditingMode = EDITING_NONE; 849c1741246af607f6be2389056da0182c40f938348Dake Gu } 850ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu // call deprecated method for backward compatible 851ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu onEditingModeChange(vh, action, editing); 852ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 853ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 854ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 855ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Animates the view holder's view (or subviews thereof) when the action has had its focus 856ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * state changed. 857ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @param vh The view holder associated with the relevant action. 858ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @param focused True if the action has become focused, false if it has lost focus. 859ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 860ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public void onAnimateItemFocused(ViewHolder vh, boolean focused) { 861ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing // No animations for this, currently, because the animation is done on 862ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing // mSelectorView 863ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 864ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 865ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 866ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Animates the view holder's view (or subviews thereof) when the action has had its press 867ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * state changed. 868ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @param vh The view holder associated with the relevant action. 869ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @param pressed True if the action has been pressed, false if it has been unpressed. 870ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 871ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public void onAnimateItemPressed(ViewHolder vh, boolean pressed) { 87266e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu vh.press(pressed); 873ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 874ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 875ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 87619c1329def8d277c914cba46540d24bfde58b2a4Dake Gu * Resets the view holder's view to unpressed state. 87719c1329def8d277c914cba46540d24bfde58b2a4Dake Gu * @param vh The view holder associated with the relevant action. 87819c1329def8d277c914cba46540d24bfde58b2a4Dake Gu */ 87919c1329def8d277c914cba46540d24bfde58b2a4Dake Gu public void onAnimateItemPressedCancelled(ViewHolder vh) { 88066e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu vh.press(false); 88119c1329def8d277c914cba46540d24bfde58b2a4Dake Gu } 88219c1329def8d277c914cba46540d24bfde58b2a4Dake Gu 88319c1329def8d277c914cba46540d24bfde58b2a4Dake Gu /** 88411cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * Animates the view holder's view (or subviews thereof) when the action has had its check state 88511cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * changed. Default implementation calls setChecked() if {@link ViewHolder#getCheckmarkView()} 88611cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * is instance of {@link Checkable}. 88711cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * 888ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @param vh The view holder associated with the relevant action. 889ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @param checked True if the action has become checked, false if it has become unchecked. 89011cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * @see #onBindCheckMarkView(ViewHolder, GuidedAction) 891ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 892ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public void onAnimateItemChecked(ViewHolder vh, boolean checked) { 89311cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu if (vh.mCheckmarkView instanceof Checkable) { 89411cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu ((Checkable) vh.mCheckmarkView).setChecked(checked); 89511cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu } 89611cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu } 89711cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu 89811cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu /** 89911cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * Sets states of check mark view, called by {@link #onBindViewHolder(ViewHolder, GuidedAction)} 90011cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * when action's checkset Id is other than {@link GuidedAction#NO_CHECK_SET}. Default 90111cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * implementation assigns drawable loaded from theme attribute 90211cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * {@link android.R.attr#listChoiceIndicatorMultiple} for checkbox or 90311cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * {@link android.R.attr#listChoiceIndicatorSingle} for radio button. Subclass rarely needs 90411cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * override the method, instead app can provide its own drawable that supports transition 90511cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * animations, change theme attributes {@link android.R.attr#listChoiceIndicatorMultiple} and 90611cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * {@link android.R.attr#listChoiceIndicatorSingle} in {android.support.v17.leanback.R. 90711cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * styleable#LeanbackGuidedStepTheme}. 90811cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * 90911cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * @param vh The view holder associated with the relevant action. 91011cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * @param action The GuidedAction object to bind to. 91111cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * @see #onAnimateItemChecked(ViewHolder, boolean) 91211cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu */ 91311cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu public void onBindCheckMarkView(ViewHolder vh, GuidedAction action) { 91411cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu if (action.getCheckSetId() != GuidedAction.NO_CHECK_SET) { 91511cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu vh.mCheckmarkView.setVisibility(View.VISIBLE); 9163103f63e99d47573823957f7aa34308555873221Aurimas Liutikas int attrId = action.getCheckSetId() == GuidedAction.CHECKBOX_CHECK_SET_ID 9173103f63e99d47573823957f7aa34308555873221Aurimas Liutikas ? android.R.attr.listChoiceIndicatorMultiple 9183103f63e99d47573823957f7aa34308555873221Aurimas Liutikas : android.R.attr.listChoiceIndicatorSingle; 91911cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu final Context context = vh.mCheckmarkView.getContext(); 92011cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu Drawable drawable = null; 92111cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu TypedValue typedValue = new TypedValue(); 92211cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu if (context.getTheme().resolveAttribute(attrId, typedValue, true)) { 92311cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu drawable = ContextCompat.getDrawable(context, typedValue.resourceId); 924ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 92511cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu vh.mCheckmarkView.setImageDrawable(drawable); 92611cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu if (vh.mCheckmarkView instanceof Checkable) { 92711cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu ((Checkable) vh.mCheckmarkView).setChecked(action.isChecked()); 92811cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu } 92911cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu } else { 93011cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu vh.mCheckmarkView.setVisibility(View.GONE); 931ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 932ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 933ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 93411cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu /** 935b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * Performs binding activator view value to action. Default implementation supports 936b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * GuidedDatePickerAction, subclass may override to add support of other views. 937b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * @param vh ViewHolder of activator view. 938b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * @param action GuidedAction to bind. 939b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu */ 940b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu public void onBindActivatorView(ViewHolder vh, GuidedAction action) { 941b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (action instanceof GuidedDatePickerAction) { 942b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu GuidedDatePickerAction dateAction = (GuidedDatePickerAction) action; 943b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu DatePicker dateView = (DatePicker) vh.mActivatorView; 944b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu dateView.setDatePickerFormat(dateAction.getDatePickerFormat()); 945942f79291db75ccf6ecd0351d23a444a43dd0501Dake Gu if (dateAction.getMinDate() != Long.MIN_VALUE) { 946942f79291db75ccf6ecd0351d23a444a43dd0501Dake Gu dateView.setMinDate(dateAction.getMinDate()); 947942f79291db75ccf6ecd0351d23a444a43dd0501Dake Gu } 948942f79291db75ccf6ecd0351d23a444a43dd0501Dake Gu if (dateAction.getMaxDate() != Long.MAX_VALUE) { 949942f79291db75ccf6ecd0351d23a444a43dd0501Dake Gu dateView.setMaxDate(dateAction.getMaxDate()); 950942f79291db75ccf6ecd0351d23a444a43dd0501Dake Gu } 951b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu Calendar c = Calendar.getInstance(); 952942f79291db75ccf6ecd0351d23a444a43dd0501Dake Gu c.setTimeInMillis(dateAction.getDate()); 953b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu dateView.updateDate(c.get(Calendar.YEAR), c.get(Calendar.MONTH), 954b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu c.get(Calendar.DAY_OF_MONTH), false); 955b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 956b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 957b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu 958b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu /** 959b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * Performs updating GuidedAction from activator view. Default implementation supports 960b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * GuidedDatePickerAction, subclass may override to add support of other views. 961b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * @param vh ViewHolder of activator view. 962b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * @param action GuidedAction to update. 963b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * @return True if value has been updated, false otherwise. 964b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu */ 965b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu public boolean onUpdateActivatorView(ViewHolder vh, GuidedAction action) { 966b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (action instanceof GuidedDatePickerAction) { 967b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu GuidedDatePickerAction dateAction = (GuidedDatePickerAction) action; 968b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu DatePicker dateView = (DatePicker) vh.mActivatorView; 969b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (dateAction.getDate() != dateView.getDate()) { 970b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu dateAction.setDate(dateView.getDate()); 971b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu return true; 972b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 973b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 974b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu return false; 975b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 976b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu 977b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu /** 978b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * Sets listener for reporting view being edited. 979b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * @hide 980b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu */ 9818e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas @RestrictTo(LIBRARY_GROUP) 982b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu public void setEditListener(EditListener listener) { 983b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu mEditListener = listener; 984b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 985b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu 986ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu void onEditActivatorView(final ViewHolder vh, boolean editing, final boolean withTransition) { 987b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (editing) { 988b0818cc234e9df4312732f95fd6849922bfa0fa1Keyvan Amiri startExpanded(vh, withTransition); 9890f96ae4965103bade4bebe7776b2ee35cd603112Dake Gu vh.itemView.setFocusable(false); 990b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu vh.mActivatorView.requestFocus(); 991b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu vh.mActivatorView.setOnClickListener(new View.OnClickListener() { 992b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu @Override 993b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu public void onClick(View v) { 994b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (!isInExpandTransition()) { 995ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu ((GuidedActionAdapter) getActionsGridView().getAdapter()) 996ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu .performOnActionClick(vh); 997b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 998b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 999b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu }); 1000b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } else { 1001ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (onUpdateActivatorView(vh, vh.getAction())) { 1002b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (mEditListener != null) { 1003ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu mEditListener.onGuidedActionEditedAndProceed(vh.getAction()); 1004b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 1005b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 10060f96ae4965103bade4bebe7776b2ee35cd603112Dake Gu vh.itemView.setFocusable(true); 1007b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu vh.itemView.requestFocus(); 1008ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu startExpanded(null, withTransition); 1009b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu vh.mActivatorView.setOnClickListener(null); 10100f96ae4965103bade4bebe7776b2ee35cd603112Dake Gu vh.mActivatorView.setClickable(false); 1011b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 1012b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 1013b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu 1014b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu /** 101511cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * Sets states of chevron view, called by {@link #onBindViewHolder(ViewHolder, GuidedAction)}. 101611cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * Subclass may override. 101711cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * 101811cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * @param vh The view holder associated with the relevant action. 101911cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * @param action The GuidedAction object to bind to. 102011cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu */ 102111cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu public void onBindChevronView(ViewHolder vh, GuidedAction action) { 1022be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu final boolean hasNext = action.hasNext(); 1023be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu final boolean hasSubActions = action.hasSubActions(); 1024be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu if (hasNext || hasSubActions) { 1025be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu vh.mChevronView.setVisibility(View.VISIBLE); 1026be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu vh.mChevronView.setAlpha(action.isEnabled() ? mEnabledChevronAlpha : 1027be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu mDisabledChevronAlpha); 1028be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu if (hasNext) { 10297a45714d94e3e5566e3879042f7ee2b93eb5c62aDake Gu float r = mMainView != null 10307a45714d94e3e5566e3879042f7ee2b93eb5c62aDake Gu && mMainView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL ? 180f : 0f; 10317a45714d94e3e5566e3879042f7ee2b93eb5c62aDake Gu vh.mChevronView.setRotation(r); 1032be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } else if (action == mExpandedAction) { 1033be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu vh.mChevronView.setRotation(270); 1034be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } else { 1035be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu vh.mChevronView.setRotation(90); 1036be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 1037be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } else { 1038be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu vh.mChevronView.setVisibility(View.GONE); 1039be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu 1040be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 1041be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 1042be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu 1043be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu /** 1044ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * Expands or collapse the sub actions list view with transition animation 1045be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * @param avh When not null, fill sub actions list of this ViewHolder into sub actions list and 1046be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * hide the other items in main list. When null, collapse the sub actions list. 1047ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @deprecated use {@link #expandAction(GuidedAction, boolean)} and 1048ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * {@link #collapseAction(boolean)} 1049be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu */ 1050ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu @Deprecated 1051be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu public void setExpandedViewHolder(ViewHolder avh) { 1052ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu expandAction(avh == null ? null : avh.getAction(), isExpandTransitionSupported()); 10531ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } 10541ed9dc77616514e20c51baa67a04adab42e4135eDake Gu 10551ed9dc77616514e20c51baa67a04adab42e4135eDake Gu /** 10561ed9dc77616514e20c51baa67a04adab42e4135eDake Gu * Returns true if it is running an expanding or collapsing transition, false otherwise. 10571ed9dc77616514e20c51baa67a04adab42e4135eDake Gu * @return True if it is running an expanding or collapsing transition, false otherwise. 10581ed9dc77616514e20c51baa67a04adab42e4135eDake Gu */ 10591ed9dc77616514e20c51baa67a04adab42e4135eDake Gu public boolean isInExpandTransition() { 10601ed9dc77616514e20c51baa67a04adab42e4135eDake Gu return mExpandTransition != null; 10611ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } 10621ed9dc77616514e20c51baa67a04adab42e4135eDake Gu 10631ed9dc77616514e20c51baa67a04adab42e4135eDake Gu /** 10641ed9dc77616514e20c51baa67a04adab42e4135eDake Gu * Returns if expand/collapse animation is supported. When this method returns true, 10651ed9dc77616514e20c51baa67a04adab42e4135eDake Gu * {@link #startExpandedTransition(ViewHolder)} will be used. When this method returns false, 10661ed9dc77616514e20c51baa67a04adab42e4135eDake Gu * {@link #onUpdateExpandedViewHolder(ViewHolder)} will be called. 10671ed9dc77616514e20c51baa67a04adab42e4135eDake Gu * @return True if it is running an expanding or collapsing transition, false otherwise. 10681ed9dc77616514e20c51baa67a04adab42e4135eDake Gu */ 10691ed9dc77616514e20c51baa67a04adab42e4135eDake Gu public boolean isExpandTransitionSupported() { 10701ed9dc77616514e20c51baa67a04adab42e4135eDake Gu return VERSION.SDK_INT >= 21; 10711ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } 10721ed9dc77616514e20c51baa67a04adab42e4135eDake Gu 10731ed9dc77616514e20c51baa67a04adab42e4135eDake Gu /** 10741ed9dc77616514e20c51baa67a04adab42e4135eDake Gu * Start transition to expand or collapse GuidedActionStylist. 10751ed9dc77616514e20c51baa67a04adab42e4135eDake Gu * @param avh When not null, the GuidedActionStylist expands the sub actions of avh. When null 10761ed9dc77616514e20c51baa67a04adab42e4135eDake Gu * the GuidedActionStylist will collapse sub actions. 1077ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @deprecated use {@link #expandAction(GuidedAction, boolean)} and 1078ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * {@link #collapseAction(boolean)} 10791ed9dc77616514e20c51baa67a04adab42e4135eDake Gu */ 1080ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu @Deprecated 10811ed9dc77616514e20c51baa67a04adab42e4135eDake Gu public void startExpandedTransition(ViewHolder avh) { 1082ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu expandAction(avh == null ? null : avh.getAction(), isExpandTransitionSupported()); 1083ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1084ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 1085ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu /** 1086ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * Enable or disable using BACK key to collapse sub actions list. Default is enabled. 1087ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * 1088ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @param backToCollapse True to enable using BACK key to collapse sub actions list, false 1089ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * to disable. 1090ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @see GuidedAction#hasSubActions 1091ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @see GuidedAction#getSubActions 1092ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu */ 1093ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu public final void setBackKeyToCollapseSubActions(boolean backToCollapse) { 1094ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu mBackToCollapseSubActions = backToCollapse; 1095ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1096ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 1097ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu /** 1098ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @return True if using BACK key to collapse sub actions list, false otherwise. Default value 1099ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * is true. 1100ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * 1101ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @see GuidedAction#hasSubActions 1102ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @see GuidedAction#getSubActions 1103ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu */ 1104ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu public final boolean isBackKeyToCollapseSubActions() { 1105ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu return mBackToCollapseSubActions; 1106ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1107ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 1108ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu /** 1109ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * Enable or disable using BACK key to collapse {@link GuidedAction} with editable activator 1110ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * view. Default is enabled. 1111ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * 1112ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @param backToCollapse True to enable using BACK key to collapse {@link GuidedAction} with 1113ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * editable activator view. 1114ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @see GuidedAction#hasEditableActivatorView 1115ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu */ 1116ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu public final void setBackKeyToCollapseActivatorView(boolean backToCollapse) { 1117ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu mBackToCollapseActivatorView = backToCollapse; 1118ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1119ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 1120ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu /** 1121ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @return True if using BACK key to collapse {@link GuidedAction} with editable activator 1122ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * view, false otherwise. Default value is true. 1123ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * 1124ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @see GuidedAction#hasEditableActivatorView 1125ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu */ 1126ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu public final boolean isBackKeyToCollapseActivatorView() { 1127ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu return mBackToCollapseActivatorView; 1128ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1129ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 1130ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu /** 1131ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * Expand an action. Do nothing if it is in animation or there is action expanded. 1132ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * 1133ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @param action Action to expand. 1134ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @param withTransition True to run transition animation, false otherwsie. 1135ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu */ 1136ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu public void expandAction(GuidedAction action, final boolean withTransition) { 1137ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (isInExpandTransition() || mExpandedAction != null) { 1138ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu return; 1139ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1140ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu int actionPosition = 1141ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu ((GuidedActionAdapter) getActionsGridView().getAdapter()).indexOf(action); 1142ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (actionPosition < 0) { 1143ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu return; 1144ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1145ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu boolean runTransition = isExpandTransitionSupported() && withTransition; 1146ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (!runTransition) { 1147ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu getActionsGridView().setSelectedPosition(actionPosition, 1148ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu new ViewHolderTask() { 1149ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu @Override 1150ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu public void run(RecyclerView.ViewHolder vh) { 1151ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu GuidedActionsStylist.ViewHolder avh = 1152ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu (GuidedActionsStylist.ViewHolder)vh; 1153ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (avh.getAction().hasEditableActivatorView()) { 1154ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu setEditingMode(avh, true /*editing*/, false /*withTransition*/); 1155ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } else { 1156ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu onUpdateExpandedViewHolder(avh); 1157ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1158ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1159ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu }); 1160e5d263725fb60aa6a24f2221548afb20d0dc46e1Dake Gu if (action.hasSubActions()) { 1161e5d263725fb60aa6a24f2221548afb20d0dc46e1Dake Gu onUpdateSubActionsGridView(action, true); 1162e5d263725fb60aa6a24f2221548afb20d0dc46e1Dake Gu } 1163ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } else { 1164ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu getActionsGridView().setSelectedPosition(actionPosition, 1165ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu new ViewHolderTask() { 1166ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu @Override 1167ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu public void run(RecyclerView.ViewHolder vh) { 1168ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu GuidedActionsStylist.ViewHolder avh = 1169ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu (GuidedActionsStylist.ViewHolder)vh; 1170ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (avh.getAction().hasEditableActivatorView()) { 1171ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu setEditingMode(avh, true /*editing*/, true /*withTransition*/); 1172ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } else { 1173ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu startExpanded(avh, true); 1174ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1175ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1176ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu }); 1177ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1178ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 1179ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1180ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 1181ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu /** 1182ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * Collapse expanded action. Do nothing if it is in animation or there is no action expanded. 1183ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * 1184ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @param withTransition True to run transition animation, false otherwsie. 1185ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu */ 1186ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu public void collapseAction(boolean withTransition) { 1187ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (isInExpandTransition() || mExpandedAction == null) { 1188ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu return; 1189ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1190ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu boolean runTransition = isExpandTransitionSupported() && withTransition; 1191ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu int actionPosition = 1192ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu ((GuidedActionAdapter) getActionsGridView().getAdapter()).indexOf(mExpandedAction); 1193ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (actionPosition < 0) { 1194ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu return; 1195ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1196ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (mExpandedAction.hasEditableActivatorView()) { 1197ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu setEditingMode( 1198ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu ((ViewHolder) getActionsGridView().findViewHolderForPosition(actionPosition)), 1199ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu false /*editing*/, 1200ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu runTransition); 1201ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } else { 1202ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu startExpanded(null, runTransition); 1203ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1204ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1205ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 1206ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu int getKeyLine() { 1207ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu return (int) (mKeyLinePercent * mActionsGridView.getHeight() / 100); 1208ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1209ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 1210ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu /** 1211ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * Internal method with assumption we already scroll to the new ViewHolder or is currently 1212ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * expanded. 1213ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu */ 1214ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu void startExpanded(ViewHolder avh, final boolean withTransition) { 12151ed9dc77616514e20c51baa67a04adab42e4135eDake Gu ViewHolder focusAvh = null; // expand / collapse view holder 12161ed9dc77616514e20c51baa67a04adab42e4135eDake Gu final int count = mActionsGridView.getChildCount(); 12171ed9dc77616514e20c51baa67a04adab42e4135eDake Gu for (int i = 0; i < count; i++) { 12181ed9dc77616514e20c51baa67a04adab42e4135eDake Gu ViewHolder vh = (ViewHolder) mActionsGridView 12191ed9dc77616514e20c51baa67a04adab42e4135eDake Gu .getChildViewHolder(mActionsGridView.getChildAt(i)); 12201ed9dc77616514e20c51baa67a04adab42e4135eDake Gu if (avh == null && vh.itemView.getVisibility() == View.VISIBLE) { 12211ed9dc77616514e20c51baa67a04adab42e4135eDake Gu // going to collapse this one. 12221ed9dc77616514e20c51baa67a04adab42e4135eDake Gu focusAvh = vh; 12231ed9dc77616514e20c51baa67a04adab42e4135eDake Gu break; 12241ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } else if (avh != null && vh.getAction() == avh.getAction()) { 12251ed9dc77616514e20c51baa67a04adab42e4135eDake Gu // going to expand this one. 12261ed9dc77616514e20c51baa67a04adab42e4135eDake Gu focusAvh = vh; 12271ed9dc77616514e20c51baa67a04adab42e4135eDake Gu break; 12281ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } 12291ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } 12301ed9dc77616514e20c51baa67a04adab42e4135eDake Gu if (focusAvh == null) { 12311ed9dc77616514e20c51baa67a04adab42e4135eDake Gu // huh? 12321ed9dc77616514e20c51baa67a04adab42e4135eDake Gu return; 12331ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } 1234ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu boolean isExpand = avh != null; 1235b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu boolean isSubActionTransition = focusAvh.getAction().hasSubActions(); 1236ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (withTransition) { 1237ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu Object set = TransitionHelper.createTransitionSet(false); 1238ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu float slideDistance = isSubActionTransition ? focusAvh.itemView.getHeight() 1239ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu : focusAvh.itemView.getHeight() * 0.5f; 1240ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu Object slideAndFade = TransitionHelper.createFadeAndShortSlide( 1241ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu Gravity.TOP | Gravity.BOTTOM, 1242ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu slideDistance); 1243ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.setEpicenterCallback(slideAndFade, new TransitionEpicenterCallback() { 1244ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu Rect mRect = new Rect(); 1245ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu @Override 1246ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu public Rect onGetEpicenter(Object transition) { 1247ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu int centerY = getKeyLine(); 1248ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu int centerX = 0; 1249ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu mRect.set(centerX, centerY, centerX, centerY); 1250ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu return mRect; 1251b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 1252ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu }); 1253ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu Object changeFocusItemTransform = TransitionHelper.createChangeTransform(); 1254ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu Object changeFocusItemBounds = TransitionHelper.createChangeBounds(false); 12553103f63e99d47573823957f7aa34308555873221Aurimas Liutikas Object fade = TransitionHelper.createFadeTransition(TransitionHelper.FADE_IN 12563103f63e99d47573823957f7aa34308555873221Aurimas Liutikas | TransitionHelper.FADE_OUT); 1257ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu Object changeGridBounds = TransitionHelper.createChangeBounds(false); 1258ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (avh == null) { 1259ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.setStartDelay(slideAndFade, 150); 1260ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.setStartDelay(changeFocusItemTransform, 100); 1261ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.setStartDelay(changeFocusItemBounds, 100); 1262ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.setStartDelay(changeGridBounds, 100); 12631ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } else { 1264ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.setStartDelay(fade, 100); 1265ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.setStartDelay(changeGridBounds, 50); 1266ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.setStartDelay(changeFocusItemTransform, 50); 1267ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.setStartDelay(changeFocusItemBounds, 50); 12681ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } 1269ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu for (int i = 0; i < count; i++) { 1270ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu ViewHolder vh = (ViewHolder) mActionsGridView 1271ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu .getChildViewHolder(mActionsGridView.getChildAt(i)); 1272ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (vh == focusAvh) { 1273ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu // going to expand/collapse this one. 1274ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (isSubActionTransition) { 1275ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.include(changeFocusItemTransform, vh.itemView); 1276ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.include(changeFocusItemBounds, vh.itemView); 1277ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1278ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } else { 1279ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu // going to slide this item to top / bottom. 1280ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.include(slideAndFade, vh.itemView); 1281ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.exclude(fade, vh.itemView, true); 1282ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1283ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1284ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.include(changeGridBounds, mSubActionsGridView); 1285ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.include(changeGridBounds, mSubActionsBackground); 1286ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.addTransition(set, slideAndFade); 1287ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu // note that we don't run ChangeBounds for activating view due to the rounding problem 1288ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu // of multiple level views ChangeBounds animation causing vertical jittering. 1289ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (isSubActionTransition) { 1290ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.addTransition(set, changeFocusItemTransform); 1291ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.addTransition(set, changeFocusItemBounds); 12921ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } 1293ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.addTransition(set, fade); 1294ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.addTransition(set, changeGridBounds); 1295ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu mExpandTransition = set; 1296ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.addTransitionListener(mExpandTransition, new TransitionListener() { 12971ed9dc77616514e20c51baa67a04adab42e4135eDake Gu @Override 1298ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu public void onTransitionEnd(Object transition) { 1299ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu mExpandTransition = null; 13001ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } 13011ed9dc77616514e20c51baa67a04adab42e4135eDake Gu }); 1302ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (isExpand && isSubActionTransition) { 1303ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu // To expand sub actions, move original position of sub actions to bottom of item 1304ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu int startY = avh.itemView.getBottom(); 1305ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu mSubActionsGridView.offsetTopAndBottom(startY - mSubActionsGridView.getTop()); 1306ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu mSubActionsBackground.offsetTopAndBottom(startY - mSubActionsBackground.getTop()); 1307ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1308ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.beginDelayedTransition(mMainView, mExpandTransition); 13091ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } 13101ed9dc77616514e20c51baa67a04adab42e4135eDake Gu onUpdateExpandedViewHolder(avh); 1311ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (isSubActionTransition) { 1312ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu onUpdateSubActionsGridView(focusAvh.getAction(), isExpand); 1313ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1314be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 1315be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu 1316be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu /** 1317be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * @return True if sub actions list is expanded. 1318be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu */ 1319be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu public boolean isSubActionsExpanded() { 1320ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu return mExpandedAction != null && mExpandedAction.hasSubActions(); 1321ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1322ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 1323ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu /** 1324ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @return True if there is {@link #getExpandedAction()} is not null, false otherwise. 1325ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu */ 1326ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu public boolean isExpanded() { 1327be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu return mExpandedAction != null; 1328be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 1329be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu 1330be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu /** 1331be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * @return Current expanded GuidedAction or null if not expanded. 1332be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu */ 1333be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu public GuidedAction getExpandedAction() { 1334be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu return mExpandedAction; 1335be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 1336be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu 13371ed9dc77616514e20c51baa67a04adab42e4135eDake Gu /** 13381ed9dc77616514e20c51baa67a04adab42e4135eDake Gu * Expand or collapse GuidedActionStylist. 13391ed9dc77616514e20c51baa67a04adab42e4135eDake Gu * @param avh When not null, the GuidedActionStylist expands the sub actions of avh. When null 13401ed9dc77616514e20c51baa67a04adab42e4135eDake Gu * the GuidedActionStylist will collapse sub actions. 13411ed9dc77616514e20c51baa67a04adab42e4135eDake Gu */ 13421ed9dc77616514e20c51baa67a04adab42e4135eDake Gu public void onUpdateExpandedViewHolder(ViewHolder avh) { 1343b2121d7935303972c0d515c29b9771c74311c8baKeyvan Amiri 1344b2121d7935303972c0d515c29b9771c74311c8baKeyvan Amiri // Note about setting the prune child flag back & forth here: without this, the actions that 1345b2121d7935303972c0d515c29b9771c74311c8baKeyvan Amiri // go off the screen from the top or bottom become invisible forever. This is because once 1346b2121d7935303972c0d515c29b9771c74311c8baKeyvan Amiri // an action is expanded, it takes more space which in turn kicks out some other actions 1347b2121d7935303972c0d515c29b9771c74311c8baKeyvan Amiri // off of the screen. Once, this action is collapsed (after the second click) and the 1348b2121d7935303972c0d515c29b9771c74311c8baKeyvan Amiri // visibility flag is set back to true for all existing actions, 1349b2121d7935303972c0d515c29b9771c74311c8baKeyvan Amiri // the off-the-screen actions are pruned from the view, thus 1350b2121d7935303972c0d515c29b9771c74311c8baKeyvan Amiri // could not be accessed, had we not disabled pruning prior to this. 13511ed9dc77616514e20c51baa67a04adab42e4135eDake Gu if (avh == null) { 13521ed9dc77616514e20c51baa67a04adab42e4135eDake Gu mExpandedAction = null; 1353b2121d7935303972c0d515c29b9771c74311c8baKeyvan Amiri mActionsGridView.setPruneChild(true); 13541ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } else if (avh.getAction() != mExpandedAction) { 13551ed9dc77616514e20c51baa67a04adab42e4135eDake Gu mExpandedAction = avh.getAction(); 1356b2121d7935303972c0d515c29b9771c74311c8baKeyvan Amiri mActionsGridView.setPruneChild(false); 13571ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } 1358fb23f1271e21761bb523948d9ea9c60c42ae7251Dake Gu // In expanding mode, notifyItemChange on expanded item will reset the translationY by 1359fb23f1271e21761bb523948d9ea9c60c42ae7251Dake Gu // the default ItemAnimator. So disable ItemAnimation in expanding mode. 1360fb23f1271e21761bb523948d9ea9c60c42ae7251Dake Gu mActionsGridView.setAnimateChildLayout(false); 1361be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu final int count = mActionsGridView.getChildCount(); 1362be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu for (int i = 0; i < count; i++) { 1363be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu ViewHolder vh = (ViewHolder) mActionsGridView 1364be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu .getChildViewHolder(mActionsGridView.getChildAt(i)); 1365be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu updateChevronAndVisibility(vh); 1366be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 1367ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1368ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 1369ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu void onUpdateSubActionsGridView(GuidedAction action, boolean expand) { 1370be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu if (mSubActionsGridView != null) { 1371ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu ViewGroup.MarginLayoutParams lp = 1372ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu (ViewGroup.MarginLayoutParams) mSubActionsGridView.getLayoutParams(); 1373ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu GuidedActionAdapter adapter = (GuidedActionAdapter) mSubActionsGridView.getAdapter(); 1374ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (expand) { 1375ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu // set to negative value so GuidedActionRelativeLayout will override with 1376ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu // keyLine percentage. 1377ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu lp.topMargin = -2; 13781ed9dc77616514e20c51baa67a04adab42e4135eDake Gu lp.height = ViewGroup.MarginLayoutParams.MATCH_PARENT; 13791ed9dc77616514e20c51baa67a04adab42e4135eDake Gu mSubActionsGridView.setLayoutParams(lp); 13801ed9dc77616514e20c51baa67a04adab42e4135eDake Gu mSubActionsGridView.setVisibility(View.VISIBLE); 1381fa4d2cddf2cb9619088153a1fe07d09203d792faDake Gu mSubActionsBackground.setVisibility(View.VISIBLE); 13821ed9dc77616514e20c51baa67a04adab42e4135eDake Gu mSubActionsGridView.requestFocus(); 1383ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu adapter.setActions(action.getSubActions()); 1384ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } else { 1385ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu // set to explicit value, which will disable the keyLine percentage calculation 1386ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu // in GuidedRelativeLayout. 1387ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu int actionPosition = ((GuidedActionAdapter) mActionsGridView.getAdapter()) 1388ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu .indexOf(action); 1389ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu lp.topMargin = mActionsGridView.getLayoutManager() 1390ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu .findViewByPosition(actionPosition).getBottom(); 1391ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu lp.height = 0; 13921ed9dc77616514e20c51baa67a04adab42e4135eDake Gu mSubActionsGridView.setVisibility(View.INVISIBLE); 1393fa4d2cddf2cb9619088153a1fe07d09203d792faDake Gu mSubActionsBackground.setVisibility(View.INVISIBLE); 13941ed9dc77616514e20c51baa67a04adab42e4135eDake Gu mSubActionsGridView.setLayoutParams(lp); 1395ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu adapter.setActions(Collections.EMPTY_LIST); 13961ed9dc77616514e20c51baa67a04adab42e4135eDake Gu mActionsGridView.requestFocus(); 13971ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } 1398be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 1399be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 1400be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu 1401be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu private void updateChevronAndVisibility(ViewHolder vh) { 1402be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu if (!vh.isSubAction()) { 14031ed9dc77616514e20c51baa67a04adab42e4135eDake Gu if (mExpandedAction == null) { 14041ed9dc77616514e20c51baa67a04adab42e4135eDake Gu vh.itemView.setVisibility(View.VISIBLE); 14051ed9dc77616514e20c51baa67a04adab42e4135eDake Gu vh.itemView.setTranslationY(0); 1406b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (vh.mActivatorView != null) { 14070f96ae4965103bade4bebe7776b2ee35cd603112Dake Gu vh.setActivated(false); 1408b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 14091ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } else if (vh.getAction() == mExpandedAction) { 1410be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu vh.itemView.setVisibility(View.VISIBLE); 1411b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (vh.getAction().hasSubActions()) { 1412ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu vh.itemView.setTranslationY(getKeyLine() - vh.itemView.getBottom()); 1413b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } else if (vh.mActivatorView != null) { 1414b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu vh.itemView.setTranslationY(0); 14150f96ae4965103bade4bebe7776b2ee35cd603112Dake Gu vh.setActivated(true); 1416b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 1417be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } else { 1418be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu vh.itemView.setVisibility(View.INVISIBLE); 14191ed9dc77616514e20c51baa67a04adab42e4135eDake Gu vh.itemView.setTranslationY(0); 1420be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 1421be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 1422be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu if (vh.mChevronView != null) { 1423be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu onBindChevronView(vh, vh.getAction()); 1424be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 142511cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu } 142611cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu 1427ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /* 1428ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * ========================================== 1429ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * FragmentAnimationProvider overrides 1430ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * ========================================== 1431ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 1432ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 1433ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 1434ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * {@inheritDoc} 1435ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 1436ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing @Override 14374158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing public void onImeAppearing(@NonNull List<Animator> animators) { 14384158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing } 14394158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing 14404158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing /** 14414158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing * {@inheritDoc} 14424158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing */ 14434158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing @Override 14444158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing public void onImeDisappearing(@NonNull List<Animator> animators) { 14454158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing } 14464158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing 1447ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /* 1448ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * ========================================== 1449ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Private methods 1450ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * ========================================== 1451ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 1452ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 1453ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private float getFloat(Context ctx, TypedValue typedValue, int attrId) { 1454ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing ctx.getTheme().resolveAttribute(attrId, typedValue, true); 1455ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing // Android resources don't have a native float type, so we have to use strings. 1456ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return Float.valueOf(ctx.getResources().getString(typedValue.resourceId)); 1457ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 1458ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 1459ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private int getInteger(Context ctx, TypedValue typedValue, int attrId) { 1460ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing ctx.getTheme().resolveAttribute(attrId, typedValue, true); 1461ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return ctx.getResources().getInteger(typedValue.resourceId); 1462ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 1463ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 1464ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private int getDimension(Context ctx, TypedValue typedValue, int attrId) { 1465ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing ctx.getTheme().resolveAttribute(attrId, typedValue, true); 1466ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return ctx.getResources().getDimensionPixelSize(typedValue.resourceId); 1467ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 1468ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 1469ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private boolean setIcon(final ImageView iconView, GuidedAction action) { 1470ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing Drawable icon = null; 1471ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing if (iconView != null) { 1472ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing icon = action.getIcon(); 1473ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing if (icon != null) { 1474162b21598d9f4fd49748b3c7e27501fe1277210dChristopher Lane // setImageDrawable resets the drawable's level unless we set the view level first. 1475162b21598d9f4fd49748b3c7e27501fe1277210dChristopher Lane iconView.setImageLevel(icon.getLevel()); 1476ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing iconView.setImageDrawable(icon); 1477ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing iconView.setVisibility(View.VISIBLE); 1478ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } else { 1479ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing iconView.setVisibility(View.GONE); 1480ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 1481ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 1482ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return icon != null; 1483ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 1484ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 1485ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 1486ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @return the max height in pixels the description can be such that the 1487ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * action nicely takes up the entire screen. 1488ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 1489ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private int getDescriptionMaxHeight(Context context, TextView title) { 1490ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing // The 2 multiplier on the title height calculation is a 1491ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing // conservative estimate for font padding which can not be 1492ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing // calculated at this stage since the view hasn't been rendered yet. 1493ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return (int)(mDisplayHeight - 2*mVerticalPadding - 2*mTitleMaxLines*title.getLineHeight()); 1494ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 1495ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 1496ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing} 1497