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 */ 14ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.leanback.widget; 15ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 16ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP; 17ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.leanback.widget.GuidedAction.EDITING_ACTIVATOR_VIEW; 18ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.leanback.widget.GuidedAction.EDITING_DESCRIPTION; 19ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.leanback.widget.GuidedAction.EDITING_NONE; 20ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.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; 30306fba1d4665743f6b4f6e609fb2565e25c14c71jingjiangliimport android.text.InputType; 31ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport android.text.TextUtils; 32ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport android.util.TypedValue; 331ed9dc77616514e20c51baa67a04adab42e4135eDake Guimport android.view.Gravity; 34ae746be7c46297b910a99c07697e33e3a5fd7facDake Guimport android.view.KeyEvent; 35ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport android.view.LayoutInflater; 36ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport android.view.View; 37b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Guimport android.view.View.AccessibilityDelegate; 38ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport android.view.ViewGroup; 39ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport android.view.WindowManager; 40b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Guimport android.view.accessibility.AccessibilityEvent; 41b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Guimport android.view.accessibility.AccessibilityNodeInfo; 4250c611b216a4b2c8eb2bbd2a2848bb6da34677besusnataimport android.view.inputmethod.EditorInfo; 4311cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Guimport android.widget.Checkable; 44ac07e9d12b10138d4a449522f7082a40f18861e2Kris Giesingimport android.widget.EditText; 45ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport android.widget.ImageView; 46ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport android.widget.TextView; 47ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 488619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport androidx.annotation.CallSuper; 498619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport androidx.annotation.NonNull; 508619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport androidx.annotation.RestrictTo; 518619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport androidx.core.content.ContextCompat; 52d1d1d1a4a5a12a5e4541ccc37ce48cd130b2bc5dDake Guimport androidx.core.os.BuildCompat; 538619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport androidx.leanback.R; 548619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport androidx.leanback.transition.TransitionEpicenterCallback; 558619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport androidx.leanback.transition.TransitionHelper; 568619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport androidx.leanback.transition.TransitionListener; 578619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport androidx.leanback.widget.GuidedActionAdapter.EditListener; 588619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport androidx.leanback.widget.picker.DatePicker; 598619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport androidx.recyclerview.widget.RecyclerView; 608619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikas 61b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Guimport java.util.Calendar; 62be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Guimport java.util.Collections; 63ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingimport java.util.List; 64ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 65ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing/** 66ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * GuidedActionsStylist is used within a {@link androidx.leanback.app.GuidedStepFragment} 67a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * to supply the right-side panel where users can take actions. It consists of a container for the 68a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * list of actions, and a stationary selector view that indicates visually the location of focus. 69be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * GuidedActionsStylist has two different layouts: default is for normal actions including text, 70b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * radio, checkbox, DatePicker, etc, the other when {@link #setAsButtonActions()} is called is 71b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * recommended for button actions such as "yes", "no". 72ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <p> 73ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Many aspects of the base GuidedActionsStylist can be customized through theming; see the 74ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * theme attributes below. Note that these attributes are not set on individual elements in layout 75ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * XML, but instead would be set in a custom theme. See 76ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <a href="http://developer.android.com/guide/topics/ui/themes.html">Styles and Themes</a> 77ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * for more information. 78ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <p> 79ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * If these hooks are insufficient, this class may also be subclassed. Subclasses may wish to 80ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * override the {@link #onProvideLayoutId} method to change the layout used to display the 81b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * list container and selector; override {@link #onProvideItemLayoutId(int)} and 82b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * {@link #getItemViewType(GuidedAction)} method to change the layout used to display each action. 83b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * <p> 84b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * To support a "click to activate" view similar to DatePicker, app needs: 85b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * <li> Override {@link #onProvideItemLayoutId(int)} and {@link #getItemViewType(GuidedAction)}, 86b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * provides a layout id for the action. 87b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * <li> The layout must include a widget with id "guidedactions_activator_item", the widget is 88b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * toggled edit mode by {@link View#setActivated(boolean)}. 89b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * <li> Override {@link #onBindActivatorView(ViewHolder, GuidedAction)} to populate values into View. 90b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * <li> Override {@link #onUpdateActivatorView(ViewHolder, GuidedAction)} to update action. 91ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <p> 92ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Note: If an alternate list layout is provided, the following view IDs must be supplied: 93ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <ul> 94ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * <li>{@link androidx.leanback.R.id#guidedactions_list}</li> 95ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * </ul><p> 96ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * These view IDs must be present in order for the stylist to function. The list ID must correspond 97ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * to a {@link VerticalGridView} or subclass. 98ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <p> 99ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * If an alternate item layout is provided, the following view IDs should be used to refer to base 100ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * elements: 101ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <ul> 102ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * <li>{@link androidx.leanback.R.id#guidedactions_item_content}</li> 103ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * <li>{@link androidx.leanback.R.id#guidedactions_item_title}</li> 104ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * <li>{@link androidx.leanback.R.id#guidedactions_item_description}</li> 105ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * <li>{@link androidx.leanback.R.id#guidedactions_item_icon}</li> 106ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * <li>{@link androidx.leanback.R.id#guidedactions_item_checkmark}</li> 107ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * <li>{@link androidx.leanback.R.id#guidedactions_item_chevron}</li> 108ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * </ul><p> 109ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * These view IDs are allowed to be missing, in which case the corresponding views in {@link 110ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * GuidedActionsStylist.ViewHolder} will be null. 1114158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing * <p> 1124158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing * In order to support editable actions, the view associated with guidedactions_item_title should 1134158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing * be a subclass of {@link android.widget.EditText}, and should satisfy the {@link 114d1d1d1a4a5a12a5e4541ccc37ce48cd130b2bc5dDake Gu * ImeKeyMonitor} interface and {@link GuidedActionAutofillSupport} interface. 115ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * 116ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * @attr ref androidx.leanback.R.styleable#LeanbackGuidedStepTheme_guidedStepImeAppearingAnimation 117ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * @attr ref androidx.leanback.R.styleable#LeanbackGuidedStepTheme_guidedStepImeDisappearingAnimation 118ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * @attr ref androidx.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionsSelectorDrawable 119ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * @attr ref androidx.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionsListStyle 120ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * @attr ref androidx.leanback.R.styleable#LeanbackGuidedStepTheme_guidedSubActionsListStyle 121ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * @attr ref androidx.leanback.R.styleable#LeanbackGuidedStepTheme_guidedButtonActionsListStyle 122ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * @attr ref androidx.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionItemContainerStyle 123ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * @attr ref androidx.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionItemCheckmarkStyle 124ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * @attr ref androidx.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionItemIconStyle 125ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * @attr ref androidx.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionItemContentStyle 126ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * @attr ref androidx.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionItemTitleStyle 127ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * @attr ref androidx.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionItemDescriptionStyle 128ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * @attr ref androidx.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionItemChevronStyle 129ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * @attr ref androidx.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionPressedAnimation 130ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * @attr ref androidx.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionUnpressedAnimation 131ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * @attr ref androidx.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionEnabledChevronAlpha 132ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * @attr ref androidx.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionDisabledChevronAlpha 133ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * @attr ref androidx.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionTitleMinLines 134ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * @attr ref androidx.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionTitleMaxLines 135ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * @attr ref androidx.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionDescriptionMinLines 136ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * @attr ref androidx.leanback.R.styleable#LeanbackGuidedStepTheme_guidedActionVerticalPadding 13711cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * @see android.R.styleable#Theme_listChoiceIndicatorSingle 13811cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * @see android.R.styleable#Theme_listChoiceIndicatorMultiple 139ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * @see androidx.leanback.app.GuidedStepFragment 140ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @see GuidedAction 141ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 142ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesingpublic class GuidedActionsStylist implements FragmentAnimationProvider { 143ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 144ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 145e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * Default viewType that associated with default layout Id for the action item. 146e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * @see #getItemViewType(GuidedAction) 147e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * @see #onProvideItemLayoutId(int) 148e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * @see #onCreateViewHolder(ViewGroup, int) 149e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu */ 150e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu public static final int VIEW_TYPE_DEFAULT = 0; 151e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu 152e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu /** 153b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * ViewType for DatePicker. 154b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu */ 155b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu public static final int VIEW_TYPE_DATE_PICKER = 1; 156b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu 15750c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata final static ItemAlignmentFacet sGuidedActionItemAlignFacet; 158df715f15ab54e487840c51f9fedd9a4409856096susnata 15950c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata static { 16050c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata sGuidedActionItemAlignFacet = new ItemAlignmentFacet(); 16150c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata ItemAlignmentFacet.ItemAlignmentDef alignedDef = new ItemAlignmentFacet.ItemAlignmentDef(); 16250c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata alignedDef.setItemAlignmentViewId(R.id.guidedactions_item_title); 16350c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata alignedDef.setAlignedToTextViewBaseline(true); 16450c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata alignedDef.setItemAlignmentOffset(0); 16550c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata alignedDef.setItemAlignmentOffsetWithPadding(true); 16650c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata alignedDef.setItemAlignmentOffsetPercent(0); 16750c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata sGuidedActionItemAlignFacet.setAlignmentDefs(new ItemAlignmentFacet.ItemAlignmentDef[]{alignedDef}); 16850c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata } 16950c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata 170b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu /** 171ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * ViewHolder caches information about the action item layouts' subviews. Subclasses of {@link 172ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * GuidedActionsStylist} may also wish to subclass this in order to add fields. 173ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @see GuidedAction 174ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 17550c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata public static class ViewHolder extends RecyclerView.ViewHolder implements FacetProvider { 176ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 17799ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas GuidedAction mAction; 178ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private View mContentView; 17999ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas TextView mTitleView; 18099ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas TextView mDescriptionView; 18199ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas View mActivatorView; 18299ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas ImageView mIconView; 18399ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas ImageView mCheckmarkView; 18499ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas ImageView mChevronView; 18599ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas int mEditingMode = EDITING_NONE; 186be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu private final boolean mIsSubAction; 18766e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu Animator mPressAnimator; 188ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 189b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu final AccessibilityDelegate mDelegate = new AccessibilityDelegate() { 190b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu @Override 191b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) { 192b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu super.onInitializeAccessibilityEvent(host, event); 193b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu event.setChecked(mAction != null && mAction.isChecked()); 194b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu } 195b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu 196b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu @Override 197b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { 198b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu super.onInitializeAccessibilityNodeInfo(host, info); 199b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu info.setCheckable( 200b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu mAction != null && mAction.getCheckSetId() != GuidedAction.NO_CHECK_SET); 201b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu info.setChecked(mAction != null && mAction.isChecked()); 202b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu } 203b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu }; 204b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu 205ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 206ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Constructs an ViewHolder and caches the relevant subviews. 207ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 208ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public ViewHolder(View v) { 209be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu this(v, false); 210be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 211be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu 212be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu /** 213be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * Constructs an ViewHolder for sub action and caches the relevant subviews. 214be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu */ 215be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu public ViewHolder(View v, boolean isSubAction) { 216be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu super(v); 217ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 218ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mContentView = v.findViewById(R.id.guidedactions_item_content); 219ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mTitleView = (TextView) v.findViewById(R.id.guidedactions_item_title); 220b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu mActivatorView = v.findViewById(R.id.guidedactions_activator_item); 221ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mDescriptionView = (TextView) v.findViewById(R.id.guidedactions_item_description); 222ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mIconView = (ImageView) v.findViewById(R.id.guidedactions_item_icon); 223ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mCheckmarkView = (ImageView) v.findViewById(R.id.guidedactions_item_checkmark); 224ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mChevronView = (ImageView) v.findViewById(R.id.guidedactions_item_chevron); 225be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu mIsSubAction = isSubAction; 226b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu 227b6b910bb30da6b2af318e77d0ab2f3575187f7bcDake Gu v.setAccessibilityDelegate(mDelegate); 228ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 229ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 230ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 231ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Returns the content view within this view holder's view, where title and description are 232ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * shown. 233ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 234ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public View getContentView() { 235ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return mContentView; 236ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 237ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 238ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 239ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Returns the title view within this view holder's view. 240ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 241ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public TextView getTitleView() { 242ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return mTitleView; 243ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 244ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 245ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 246ac07e9d12b10138d4a449522f7082a40f18861e2Kris Giesing * Convenience method to return an editable version of the title, if possible, 247ac07e9d12b10138d4a449522f7082a40f18861e2Kris Giesing * or null if the title view isn't an EditText. 248ac07e9d12b10138d4a449522f7082a40f18861e2Kris Giesing */ 249ac07e9d12b10138d4a449522f7082a40f18861e2Kris Giesing public EditText getEditableTitleView() { 250ac07e9d12b10138d4a449522f7082a40f18861e2Kris Giesing return (mTitleView instanceof EditText) ? (EditText)mTitleView : null; 251ac07e9d12b10138d4a449522f7082a40f18861e2Kris Giesing } 252ac07e9d12b10138d4a449522f7082a40f18861e2Kris Giesing 253ac07e9d12b10138d4a449522f7082a40f18861e2Kris Giesing /** 254ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Returns the description view within this view holder's view. 255ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 256ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public TextView getDescriptionView() { 257ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return mDescriptionView; 258ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 259ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 260ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 261c1741246af607f6be2389056da0182c40f938348Dake Gu * Convenience method to return an editable version of the description, if possible, 262c1741246af607f6be2389056da0182c40f938348Dake Gu * or null if the description view isn't an EditText. 263c1741246af607f6be2389056da0182c40f938348Dake Gu */ 264c1741246af607f6be2389056da0182c40f938348Dake Gu public EditText getEditableDescriptionView() { 265c1741246af607f6be2389056da0182c40f938348Dake Gu return (mDescriptionView instanceof EditText) ? (EditText)mDescriptionView : null; 266c1741246af607f6be2389056da0182c40f938348Dake Gu } 267c1741246af607f6be2389056da0182c40f938348Dake Gu 268c1741246af607f6be2389056da0182c40f938348Dake Gu /** 269ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Returns the icon view within this view holder's view. 270ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 271ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public ImageView getIconView() { 272ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return mIconView; 273ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 274ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 275ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 276ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Returns the checkmark view within this view holder's view. 277ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 278ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public ImageView getCheckmarkView() { 279ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return mCheckmarkView; 280ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 281ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 282ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 283ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Returns the chevron view within this view holder's view. 284ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 285ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public ImageView getChevronView() { 286ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return mChevronView; 287ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 288ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 289c1741246af607f6be2389056da0182c40f938348Dake Gu /** 290b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * Returns true if in editing title, description, or activator View, false otherwise. 291c1741246af607f6be2389056da0182c40f938348Dake Gu */ 292c1741246af607f6be2389056da0182c40f938348Dake Gu public boolean isInEditing() { 293b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu return mEditingMode != EDITING_NONE; 294b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 295b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu 296b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu /** 297b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * Returns true if in editing title, description, so IME would be open. 298b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * @return True if in editing title, description, so IME would be open, false otherwise. 299b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu */ 300b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu public boolean isInEditingText() { 301b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu return mEditingMode == EDITING_TITLE || mEditingMode == EDITING_DESCRIPTION; 302b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 303b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu 304b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu /** 305b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * Returns true if the TextView is in editing title, false otherwise. 306b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu */ 307b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu public boolean isInEditingTitle() { 308b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu return mEditingMode == EDITING_TITLE; 309c1741246af607f6be2389056da0182c40f938348Dake Gu } 310c1741246af607f6be2389056da0182c40f938348Dake Gu 311c1741246af607f6be2389056da0182c40f938348Dake Gu /** 312c1741246af607f6be2389056da0182c40f938348Dake Gu * Returns true if the TextView is in editing description, false otherwise. 313c1741246af607f6be2389056da0182c40f938348Dake Gu */ 314c1741246af607f6be2389056da0182c40f938348Dake Gu public boolean isInEditingDescription() { 315b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu return mEditingMode == EDITING_DESCRIPTION; 316b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 317b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu 318b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu /** 319b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * Returns true if is in editing activator view with id guidedactions_activator_item, false 320b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * otherwise. 321b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu */ 322b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu public boolean isInEditingActivatorView() { 323b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu return mEditingMode == EDITING_ACTIVATOR_VIEW; 324c1741246af607f6be2389056da0182c40f938348Dake Gu } 325c1741246af607f6be2389056da0182c40f938348Dake Gu 326be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu /** 327b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * @return Current editing title view or description view or activator view or null if not 328b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * in editing. 329be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu */ 330c1741246af607f6be2389056da0182c40f938348Dake Gu public View getEditingView() { 331b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu switch(mEditingMode) { 332b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu case EDITING_TITLE: 333b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu return mTitleView; 334b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu case EDITING_DESCRIPTION: 335b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu return mDescriptionView; 336b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu case EDITING_ACTIVATOR_VIEW: 337b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu return mActivatorView; 338b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu case EDITING_NONE: 339b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu default: 340c1741246af607f6be2389056da0182c40f938348Dake Gu return null; 341c1741246af607f6be2389056da0182c40f938348Dake Gu } 342c1741246af607f6be2389056da0182c40f938348Dake Gu } 343be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu 344be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu /** 345be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * @return True if bound action is inside {@link GuidedAction#getSubActions()}, false 346be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * otherwise. 347be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu */ 348be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu public boolean isSubAction() { 349be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu return mIsSubAction; 350be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 351be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu 352be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu /** 353be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * @return Currently bound action. 354be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu */ 355be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu public GuidedAction getAction() { 356be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu return mAction; 357be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 3580f96ae4965103bade4bebe7776b2ee35cd603112Dake Gu 3590f96ae4965103bade4bebe7776b2ee35cd603112Dake Gu void setActivated(boolean activated) { 3600f96ae4965103bade4bebe7776b2ee35cd603112Dake Gu mActivatorView.setActivated(activated); 3610f96ae4965103bade4bebe7776b2ee35cd603112Dake Gu if (itemView instanceof GuidedActionItemContainer) { 3620f96ae4965103bade4bebe7776b2ee35cd603112Dake Gu ((GuidedActionItemContainer) itemView).setFocusOutAllowed(!activated); 3630f96ae4965103bade4bebe7776b2ee35cd603112Dake Gu } 3640f96ae4965103bade4bebe7776b2ee35cd603112Dake Gu } 36550c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata 36650c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata @Override 36750c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata public Object getFacet(Class<?> facetClass) { 36850c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata if (facetClass == ItemAlignmentFacet.class) { 36950c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata return sGuidedActionItemAlignFacet; 37050c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata } 37150c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata return null; 37250c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata } 37366e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu 37466e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu void press(boolean pressed) { 37566e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu if (mPressAnimator != null) { 37666e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu mPressAnimator.cancel(); 37766e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu mPressAnimator = null; 37866e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu } 37966e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu final int themeAttrId = pressed ? R.attr.guidedActionPressedAnimation : 38066e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu R.attr.guidedActionUnpressedAnimation; 38166e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu Context ctx = itemView.getContext(); 38266e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu TypedValue typedValue = new TypedValue(); 38366e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu if (ctx.getTheme().resolveAttribute(themeAttrId, typedValue, true)) { 38466e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu mPressAnimator = AnimatorInflater.loadAnimator(ctx, typedValue.resourceId); 38566e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu mPressAnimator.setTarget(itemView); 38666e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu mPressAnimator.addListener(new AnimatorListenerAdapter() { 38766e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu @Override 38866e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu public void onAnimationEnd(Animator animation) { 38966e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu mPressAnimator = null; 39066e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu } 39166e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu }); 39266e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu mPressAnimator.start(); 39366e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu } 39466e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu } 395ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 396ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 397f8a82a95a1a962ec05536f7196fcee0f1384a497Jake Wharton private static final String TAG = "GuidedActionsStylist"; 398ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 39999ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas ViewGroup mMainView; 4000b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu private VerticalGridView mActionsGridView; 40199ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas VerticalGridView mSubActionsGridView; 402fa4d2cddf2cb9619088153a1fe07d09203d792faDake Gu private View mSubActionsBackground; 4030b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu private View mBgView; 4048e5ae27d6db125867640b672cc97d4a158fdfd48Dake Gu private View mContentView; 4050b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu private boolean mButtonActions; 406ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 407ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing // Cached values from resources 408c1741246af607f6be2389056da0182c40f938348Dake Gu private float mEnabledTextAlpha; 409c1741246af607f6be2389056da0182c40f938348Dake Gu private float mDisabledTextAlpha; 410c1741246af607f6be2389056da0182c40f938348Dake Gu private float mEnabledDescriptionAlpha; 411c1741246af607f6be2389056da0182c40f938348Dake Gu private float mDisabledDescriptionAlpha; 412ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private float mEnabledChevronAlpha; 413ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private float mDisabledChevronAlpha; 414ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private int mTitleMinLines; 415ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private int mTitleMaxLines; 416ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private int mDescriptionMinLines; 417ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private int mVerticalPadding; 418ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private int mDisplayHeight; 419ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 420b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu private EditListener mEditListener; 421b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu 422be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu private GuidedAction mExpandedAction = null; 42399ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas Object mExpandTransition; 424ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu private boolean mBackToCollapseSubActions = true; 425ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu private boolean mBackToCollapseActivatorView = true; 426ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 427ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu private float mKeyLinePercent; 428be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu 429ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 430ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Creates a view appropriate for displaying a list of GuidedActions, using the provided 431ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * inflater and container. 432ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <p> 433ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <i>Note: Does not actually add the created view to the container; the caller should do 434ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * this.</i> 435ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @param inflater The layout inflater to be used when constructing the view. 436ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @param container The view group to be passed in the call to 437ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <code>LayoutInflater.inflate</code>. 438ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @return The view to be added to the caller's view hierarchy. 439ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 44050c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata public View onCreateView(LayoutInflater inflater, final ViewGroup container) { 44150c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata TypedArray ta = inflater.getContext().getTheme().obtainStyledAttributes( 44250c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata R.styleable.LeanbackGuidedStepTheme); 44350c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata float keylinePercent = ta.getFloat(R.styleable.LeanbackGuidedStepTheme_guidedStepKeyline, 44450c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata 40); 4458e5ae27d6db125867640b672cc97d4a158fdfd48Dake Gu mMainView = (ViewGroup) inflater.inflate(onProvideLayoutId(), container, false); 446be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu mContentView = mMainView.findViewById(mButtonActions ? R.id.guidedactions_content2 : 447be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu R.id.guidedactions_content); 448be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu mBgView = mMainView.findViewById(mButtonActions ? R.id.guidedactions_list_background2 : 449be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu R.id.guidedactions_list_background); 450ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing if (mMainView instanceof VerticalGridView) { 451ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mActionsGridView = (VerticalGridView) mMainView; 452ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } else { 4533103f63e99d47573823957f7aa34308555873221Aurimas Liutikas mActionsGridView = (VerticalGridView) mMainView.findViewById(mButtonActions 4543103f63e99d47573823957f7aa34308555873221Aurimas Liutikas ? R.id.guidedactions_list2 : R.id.guidedactions_list); 455ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing if (mActionsGridView == null) { 456ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing throw new IllegalStateException("No ListView exists."); 457ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 45850c611b216a4b2c8eb2bbd2a2848bb6da34677besusnata mActionsGridView.setWindowAlignmentOffsetPercent(keylinePercent); 459ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mActionsGridView.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_NO_EDGE); 460be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu if (!mButtonActions) { 461be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu mSubActionsGridView = (VerticalGridView) mMainView.findViewById( 462be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu R.id.guidedactions_sub_list); 463fa4d2cddf2cb9619088153a1fe07d09203d792faDake Gu mSubActionsBackground = mMainView.findViewById( 464fa4d2cddf2cb9619088153a1fe07d09203d792faDake Gu R.id.guidedactions_sub_list_background); 465ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 466ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 467015eaf265571c84b5d37311f58bc69b2eb4af8d4Dake Gu mActionsGridView.setFocusable(false); 468015eaf265571c84b5d37311f58bc69b2eb4af8d4Dake Gu mActionsGridView.setFocusableInTouchMode(false); 469ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 470ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing // Cache widths, chevron alpha values, max and min text lines, etc 471ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing Context ctx = mMainView.getContext(); 472ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing TypedValue val = new TypedValue(); 473ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mEnabledChevronAlpha = getFloat(ctx, val, R.attr.guidedActionEnabledChevronAlpha); 474ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mDisabledChevronAlpha = getFloat(ctx, val, R.attr.guidedActionDisabledChevronAlpha); 475ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mTitleMinLines = getInteger(ctx, val, R.attr.guidedActionTitleMinLines); 476ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mTitleMaxLines = getInteger(ctx, val, R.attr.guidedActionTitleMaxLines); 477ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mDescriptionMinLines = getInteger(ctx, val, R.attr.guidedActionDescriptionMinLines); 478ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mVerticalPadding = getDimension(ctx, val, R.attr.guidedActionVerticalPadding); 479ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing mDisplayHeight = ((WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE)) 480ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing .getDefaultDisplay().getHeight(); 481ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 482c1741246af607f6be2389056da0182c40f938348Dake Gu mEnabledTextAlpha = Float.valueOf(ctx.getResources().getString(R.string 483c1741246af607f6be2389056da0182c40f938348Dake Gu .lb_guidedactions_item_unselected_text_alpha)); 484c1741246af607f6be2389056da0182c40f938348Dake Gu mDisabledTextAlpha = Float.valueOf(ctx.getResources().getString(R.string 485c1741246af607f6be2389056da0182c40f938348Dake Gu .lb_guidedactions_item_disabled_text_alpha)); 486c1741246af607f6be2389056da0182c40f938348Dake Gu mEnabledDescriptionAlpha = Float.valueOf(ctx.getResources().getString(R.string 487c1741246af607f6be2389056da0182c40f938348Dake Gu .lb_guidedactions_item_unselected_description_text_alpha)); 488c1741246af607f6be2389056da0182c40f938348Dake Gu mDisabledDescriptionAlpha = Float.valueOf(ctx.getResources().getString(R.string 489c1741246af607f6be2389056da0182c40f938348Dake Gu .lb_guidedactions_item_disabled_description_text_alpha)); 490ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 491ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu mKeyLinePercent = GuidanceStylingRelativeLayout.getKeyLinePercent(ctx); 492ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (mContentView instanceof GuidedActionsRelativeLayout) { 493ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu ((GuidedActionsRelativeLayout) mContentView).setInterceptKeyEventListener( 494ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu new GuidedActionsRelativeLayout.InterceptKeyEventListener() { 495ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu @Override 496ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu public boolean onInterceptKeyEvent(KeyEvent event) { 497ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (event.getKeyCode() == KeyEvent.KEYCODE_BACK 498ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu && event.getAction() == KeyEvent.ACTION_UP 499ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu && mExpandedAction != null) { 500ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if ((mExpandedAction.hasSubActions() 5013103f63e99d47573823957f7aa34308555873221Aurimas Liutikas && isBackKeyToCollapseSubActions()) 5023103f63e99d47573823957f7aa34308555873221Aurimas Liutikas || (mExpandedAction.hasEditableActivatorView() 503ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu && isBackKeyToCollapseActivatorView())) { 504ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu collapseAction(true); 505ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu return true; 506ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 507ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 508ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu return false; 509ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 510ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 511ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu ); 512ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 513ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return mMainView; 514ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 515ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 5160b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu /** 517be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * Choose the layout resource for button actions in {@link #onProvideLayoutId()}. 5180b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu */ 5190b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu public void setAsButtonActions() { 520be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu if (mMainView != null) { 521be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu throw new IllegalStateException("setAsButtonActions() must be called before creating " 522be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu + "views"); 5238e5ae27d6db125867640b672cc97d4a158fdfd48Dake Gu } 524be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu mButtonActions = true; 5250b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu } 5260b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu 5270b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu /** 528be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * Returns true if it is button actions list, false for normal actions list. 529be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * @return True if it is button actions list, false for normal actions list. 5300b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu */ 5310b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu public boolean isButtonActions() { 5320b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu return mButtonActions; 5330b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu } 5340b3811639349fd5791a3f330b23b7e4b1c099c27Dake Gu 535d14724d33d61385c27a00c31bbc67ad8eeb57b3cDake Gu /** 536d14724d33d61385c27a00c31bbc67ad8eeb57b3cDake Gu * Called when destroy the View created by GuidedActionsStylist. 537d14724d33d61385c27a00c31bbc67ad8eeb57b3cDake Gu */ 538d14724d33d61385c27a00c31bbc67ad8eeb57b3cDake Gu public void onDestroyView() { 539be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu mExpandedAction = null; 5401ed9dc77616514e20c51baa67a04adab42e4135eDake Gu mExpandTransition = null; 54143e10e99e55c1c2eeca31fa13e9cc84160850f59Dake Gu mActionsGridView = null; 542be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu mSubActionsGridView = null; 543fa4d2cddf2cb9619088153a1fe07d09203d792faDake Gu mSubActionsBackground = null; 5448e5ae27d6db125867640b672cc97d4a158fdfd48Dake Gu mContentView = null; 54543e10e99e55c1c2eeca31fa13e9cc84160850f59Dake Gu mBgView = null; 54643e10e99e55c1c2eeca31fa13e9cc84160850f59Dake Gu mMainView = null; 547d14724d33d61385c27a00c31bbc67ad8eeb57b3cDake Gu } 548d14724d33d61385c27a00c31bbc67ad8eeb57b3cDake Gu 549ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 550ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Returns the VerticalGridView that displays the list of GuidedActions. 551ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @return The VerticalGridView for this presenter. 552ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 553ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public VerticalGridView getActionsGridView() { 554ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return mActionsGridView; 555ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 556ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 557ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 558be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * Returns the VerticalGridView that displays the sub actions list of an expanded action. 559be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * @return The VerticalGridView that displays the sub actions list of an expanded action. 560be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu */ 561be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu public VerticalGridView getSubActionsGridView() { 562be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu return mSubActionsGridView; 563be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 564be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu 565be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu /** 566ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Provides the resource ID of the layout defining the host view for the list of guided actions. 567ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Subclasses may override to provide their own customized layouts. The base implementation 568ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * returns {@link androidx.leanback.R.layout#lb_guidedactions} or 569ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * {@link androidx.leanback.R.layout#lb_guidedbuttonactions} if 570be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * {@link #isButtonActions()} is true. If overridden, the substituted layout should contain 571be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * matching IDs for any views that should be managed by the base class; this can be achieved by 572be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * starting with a copy of the base layout file. 573be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * 574be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * @return The resource ID of the layout to be inflated to define the host view for the list of 575be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * GuidedActions. 576ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 577ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public int onProvideLayoutId() { 578be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu return mButtonActions ? R.layout.lb_guidedbuttonactions : R.layout.lb_guidedactions; 579ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 580ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 581ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 582e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * Return view type of action, each different type can have differently associated layout Id. 583e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * Default implementation returns {@link #VIEW_TYPE_DEFAULT}. 584e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * @param action The action object. 585e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * @return View type that used in {@link #onProvideItemLayoutId(int)}. 586e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu */ 587e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu public int getItemViewType(GuidedAction action) { 588b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (action instanceof GuidedDatePickerAction) { 589b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu return VIEW_TYPE_DATE_PICKER; 590b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 591e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu return VIEW_TYPE_DEFAULT; 592e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu } 593e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu 594e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu /** 595ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Provides the resource ID of the layout defining the view for an individual guided actions. 596ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Subclasses may override to provide their own customized layouts. The base implementation 597ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * returns {@link androidx.leanback.R.layout#lb_guidedactions_item}. If overridden, 598ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * the substituted layout should contain matching IDs for any views that should be managed by 599ac07e9d12b10138d4a449522f7082a40f18861e2Kris Giesing * the base class; this can be achieved by starting with a copy of the base layout file. Note 600ac07e9d12b10138d4a449522f7082a40f18861e2Kris Giesing * that in order for the item to support editing, the title view should both subclass {@link 601d1d1d1a4a5a12a5e4541ccc37ce48cd130b2bc5dDake Gu * android.widget.EditText} and implement {@link ImeKeyMonitor}, 602d1d1d1a4a5a12a5e4541ccc37ce48cd130b2bc5dDake Gu * {@link GuidedActionAutofillSupport}; see {@link 603e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * GuidedActionEditText}. To support different types of Layouts, override {@link 604e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * #onProvideItemLayoutId(int)}. 605ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @return The resource ID of the layout to be inflated to define the view to display an 606ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * individual GuidedAction. 607ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 608ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public int onProvideItemLayoutId() { 609ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return R.layout.lb_guidedactions_item; 610ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 611ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 612ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 613e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * Provides the resource ID of the layout defining the view for an individual guided actions. 614e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * Subclasses may override to provide their own customized layouts. The base implementation 615b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * supports: 616ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * <li>{@link androidx.leanback.R.layout#lb_guidedactions_item} 617ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * <li>{{@link androidx.leanback.R.layout#lb_guidedactions_datepicker_item}. If 618b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * overridden, the substituted layout should contain matching IDs for any views that should be 619b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * managed by the base class; this can be achieved by starting with a copy of the base layout 620b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * file. Note that in order for the item to support editing, the title view should both subclass 621b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * {@link android.widget.EditText} and implement {@link ImeKeyMonitor}; see 622b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * {@link GuidedActionEditText}. 623b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * 624e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * @param viewType View type returned by {@link #getItemViewType(GuidedAction)} 625e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * @return The resource ID of the layout to be inflated to define the view to display an 626b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * individual GuidedAction. 627e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu */ 628e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu public int onProvideItemLayoutId(int viewType) { 629e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu if (viewType == VIEW_TYPE_DEFAULT) { 630e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu return onProvideItemLayoutId(); 631b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } else if (viewType == VIEW_TYPE_DATE_PICKER) { 632b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu return R.layout.lb_guidedactions_datepicker_item; 633e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu } else { 6343103f63e99d47573823957f7aa34308555873221Aurimas Liutikas throw new RuntimeException("ViewType " + viewType 6353103f63e99d47573823957f7aa34308555873221Aurimas Liutikas + " not supported in GuidedActionsStylist"); 636e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu } 637e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu } 638e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu 639e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu /** 640ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Constructs a {@link ViewHolder} capable of representing {@link GuidedAction}s. Subclasses 641e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * may choose to return a subclass of ViewHolder. To support different view types, override 642e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * {@link #onCreateViewHolder(ViewGroup, int)} 643ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <p> 644ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * <i>Note: Should not actually add the created view to the parent; the caller will do 645ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * this.</i> 646ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @param parent The view group to be used as the parent of the new view. 647ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @return The view to be added to the caller's view hierarchy. 648ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 649ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public ViewHolder onCreateViewHolder(ViewGroup parent) { 650ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing LayoutInflater inflater = LayoutInflater.from(parent.getContext()); 651ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing View v = inflater.inflate(onProvideItemLayoutId(), parent, false); 652be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu return new ViewHolder(v, parent == mSubActionsGridView); 653ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 654ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 655ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 656e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * Constructs a {@link ViewHolder} capable of representing {@link GuidedAction}s. Subclasses 657e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * may choose to return a subclass of ViewHolder. 658e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * <p> 659e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * <i>Note: Should not actually add the created view to the parent; the caller will do 660e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * this.</i> 661e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * @param parent The view group to be used as the parent of the new view. 662e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * @param viewType The viewType returned by {@link #getItemViewType(GuidedAction)} 663e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu * @return The view to be added to the caller's view hierarchy. 664e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu */ 665e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 666e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu if (viewType == VIEW_TYPE_DEFAULT) { 667e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu return onCreateViewHolder(parent); 668e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu } 669e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu LayoutInflater inflater = LayoutInflater.from(parent.getContext()); 670e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu View v = inflater.inflate(onProvideItemLayoutId(viewType), parent, false); 671be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu return new ViewHolder(v, parent == mSubActionsGridView); 672e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu } 673e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu 674e2f7aef2f45dcdfe116995b64f9a7be5c68a36a1Dake Gu /** 675ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Binds a {@link ViewHolder} to a particular {@link GuidedAction}. 676ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @param vh The view holder to be associated with the given action. 677ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @param action The guided action to be displayed by the view holder's view. 678ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @return The view to be added to the caller's view hierarchy. 679ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 680ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public void onBindViewHolder(ViewHolder vh, GuidedAction action) { 681be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu vh.mAction = action; 682ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing if (vh.mTitleView != null) { 683ce678995ede4a5e09486145727fe76f231a7c866Dake Gu vh.mTitleView.setInputType(action.getInputType()); 684ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing vh.mTitleView.setText(action.getTitle()); 685c1741246af607f6be2389056da0182c40f938348Dake Gu vh.mTitleView.setAlpha(action.isEnabled() ? mEnabledTextAlpha : mDisabledTextAlpha); 6866626b899cb2565105f20e4ee2060a5104826d1ddDake Gu vh.mTitleView.setFocusable(false); 687ed6ddac644df9949403f1a01e1224a37cb568febDake Gu vh.mTitleView.setClickable(false); 688ed6ddac644df9949403f1a01e1224a37cb568febDake Gu vh.mTitleView.setLongClickable(false); 689d1d1d1a4a5a12a5e4541ccc37ce48cd130b2bc5dDake Gu if (BuildCompat.isAtLeastP()) { 690d1d1d1a4a5a12a5e4541ccc37ce48cd130b2bc5dDake Gu if (action.isEditable()) { 691d1d1d1a4a5a12a5e4541ccc37ce48cd130b2bc5dDake Gu vh.mTitleView.setAutofillHints(action.getAutofillHints()); 692d1d1d1a4a5a12a5e4541ccc37ce48cd130b2bc5dDake Gu } else { 693d1d1d1a4a5a12a5e4541ccc37ce48cd130b2bc5dDake Gu vh.mTitleView.setAutofillHints((String[]) null); 694d1d1d1a4a5a12a5e4541ccc37ce48cd130b2bc5dDake Gu } 695d1d1d1a4a5a12a5e4541ccc37ce48cd130b2bc5dDake Gu } else if (VERSION.SDK_INT >= 26) { 696d1d1d1a4a5a12a5e4541ccc37ce48cd130b2bc5dDake Gu // disable autofill below P as dpad/keyboard is not supported 697d1d1d1a4a5a12a5e4541ccc37ce48cd130b2bc5dDake Gu vh.mTitleView.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO); 698d1d1d1a4a5a12a5e4541ccc37ce48cd130b2bc5dDake Gu } 699ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 700ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing if (vh.mDescriptionView != null) { 701ce678995ede4a5e09486145727fe76f231a7c866Dake Gu vh.mDescriptionView.setInputType(action.getDescriptionInputType()); 702ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing vh.mDescriptionView.setText(action.getDescription()); 7033103f63e99d47573823957f7aa34308555873221Aurimas Liutikas vh.mDescriptionView.setVisibility(TextUtils.isEmpty(action.getDescription()) 7043103f63e99d47573823957f7aa34308555873221Aurimas Liutikas ? View.GONE : View.VISIBLE); 705c1741246af607f6be2389056da0182c40f938348Dake Gu vh.mDescriptionView.setAlpha(action.isEnabled() ? mEnabledDescriptionAlpha : 706c1741246af607f6be2389056da0182c40f938348Dake Gu mDisabledDescriptionAlpha); 7076626b899cb2565105f20e4ee2060a5104826d1ddDake Gu vh.mDescriptionView.setFocusable(false); 708ed6ddac644df9949403f1a01e1224a37cb568febDake Gu vh.mDescriptionView.setClickable(false); 709ed6ddac644df9949403f1a01e1224a37cb568febDake Gu vh.mDescriptionView.setLongClickable(false); 710d1d1d1a4a5a12a5e4541ccc37ce48cd130b2bc5dDake Gu if (BuildCompat.isAtLeastP()) { 711d1d1d1a4a5a12a5e4541ccc37ce48cd130b2bc5dDake Gu if (action.isDescriptionEditable()) { 712d1d1d1a4a5a12a5e4541ccc37ce48cd130b2bc5dDake Gu vh.mDescriptionView.setAutofillHints(action.getAutofillHints()); 713d1d1d1a4a5a12a5e4541ccc37ce48cd130b2bc5dDake Gu } else { 714d1d1d1a4a5a12a5e4541ccc37ce48cd130b2bc5dDake Gu vh.mDescriptionView.setAutofillHints((String[]) null); 715d1d1d1a4a5a12a5e4541ccc37ce48cd130b2bc5dDake Gu } 716d1d1d1a4a5a12a5e4541ccc37ce48cd130b2bc5dDake Gu } else if (VERSION.SDK_INT >= 26) { 717d1d1d1a4a5a12a5e4541ccc37ce48cd130b2bc5dDake Gu // disable autofill below P as dpad/keyboard is not supported 718d1d1d1a4a5a12a5e4541ccc37ce48cd130b2bc5dDake Gu vh.mTitleView.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO); 719d1d1d1a4a5a12a5e4541ccc37ce48cd130b2bc5dDake Gu } 720ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 721ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing // Clients might want the check mark view to be gone entirely, in which case, ignore it. 72211cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu if (vh.mCheckmarkView != null) { 72311cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu onBindCheckMarkView(vh, action); 724ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 725023bf7d01378f30a63dce3d0a1112eb56bd6b99fDake Gu setIcon(vh.mIconView, action); 726ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 727ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing if (action.hasMultilineDescription()) { 728ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing if (vh.mTitleView != null) { 729918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu setMaxLines(vh.mTitleView, mTitleMaxLines); 730306fba1d4665743f6b4f6e609fb2565e25c14c71jingjiangli vh.mTitleView.setInputType( 731306fba1d4665743f6b4f6e609fb2565e25c14c71jingjiangli vh.mTitleView.getInputType() | InputType.TYPE_TEXT_FLAG_MULTI_LINE); 732ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing if (vh.mDescriptionView != null) { 733306fba1d4665743f6b4f6e609fb2565e25c14c71jingjiangli vh.mDescriptionView.setInputType(vh.mDescriptionView.getInputType() 734306fba1d4665743f6b4f6e609fb2565e25c14c71jingjiangli | InputType.TYPE_TEXT_FLAG_MULTI_LINE); 735be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu vh.mDescriptionView.setMaxHeight(getDescriptionMaxHeight( 736be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu vh.itemView.getContext(), vh.mTitleView)); 737ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 738ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 739ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } else { 740ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing if (vh.mTitleView != null) { 741918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu setMaxLines(vh.mTitleView, mTitleMinLines); 742ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 743ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing if (vh.mDescriptionView != null) { 744918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu setMaxLines(vh.mDescriptionView, mDescriptionMinLines); 745ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 746ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 747b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (vh.mActivatorView != null) { 748b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu onBindActivatorView(vh, action); 749b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 750ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu setEditingMode(vh, false /*editing*/, false /*withTransition*/); 7517af424644dc8daae5298a5ca2f655770270366feDake Gu if (action.isFocusable()) { 752be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu vh.itemView.setFocusable(true); 753be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu ((ViewGroup) vh.itemView).setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS); 7547af424644dc8daae5298a5ca2f655770270366feDake Gu } else { 755be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu vh.itemView.setFocusable(false); 756be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu ((ViewGroup) vh.itemView).setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); 7577af424644dc8daae5298a5ca2f655770270366feDake Gu } 7584705eed4421d3b00923b56062765206dea21387eDake Gu setupImeOptions(vh, action); 759be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu 760be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu updateChevronAndVisibility(vh); 7614705eed4421d3b00923b56062765206dea21387eDake Gu } 7624705eed4421d3b00923b56062765206dea21387eDake Gu 763df715f15ab54e487840c51f9fedd9a4409856096susnata /** 764df715f15ab54e487840c51f9fedd9a4409856096susnata * Switches action to edit mode and pops up the keyboard. 765df715f15ab54e487840c51f9fedd9a4409856096susnata */ 766df715f15ab54e487840c51f9fedd9a4409856096susnata public void openInEditMode(GuidedAction action) { 767df715f15ab54e487840c51f9fedd9a4409856096susnata final GuidedActionAdapter guidedActionAdapter = 768df715f15ab54e487840c51f9fedd9a4409856096susnata (GuidedActionAdapter) getActionsGridView().getAdapter(); 769df715f15ab54e487840c51f9fedd9a4409856096susnata int actionIndex = guidedActionAdapter.getActions().indexOf(action); 770df715f15ab54e487840c51f9fedd9a4409856096susnata if (actionIndex < 0 || !action.isEditable()) { 771df715f15ab54e487840c51f9fedd9a4409856096susnata return; 772df715f15ab54e487840c51f9fedd9a4409856096susnata } 773df715f15ab54e487840c51f9fedd9a4409856096susnata 774df715f15ab54e487840c51f9fedd9a4409856096susnata getActionsGridView().setSelectedPosition(actionIndex, new ViewHolderTask() { 775df715f15ab54e487840c51f9fedd9a4409856096susnata @Override 776df715f15ab54e487840c51f9fedd9a4409856096susnata public void run(RecyclerView.ViewHolder viewHolder) { 777df715f15ab54e487840c51f9fedd9a4409856096susnata ViewHolder vh = (ViewHolder) viewHolder; 778df715f15ab54e487840c51f9fedd9a4409856096susnata guidedActionAdapter.mGroup.openIme(guidedActionAdapter, vh); 779df715f15ab54e487840c51f9fedd9a4409856096susnata } 780df715f15ab54e487840c51f9fedd9a4409856096susnata }); 781df715f15ab54e487840c51f9fedd9a4409856096susnata } 782df715f15ab54e487840c51f9fedd9a4409856096susnata 783918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu private static void setMaxLines(TextView view, int maxLines) { 784918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu // setSingleLine must be called before setMaxLines because it resets maximum to 785918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu // Integer.MAX_VALUE. 786918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu if (maxLines == 1) { 787918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu view.setSingleLine(true); 788918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu } else { 789918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu view.setSingleLine(false); 790918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu view.setMaxLines(maxLines); 791918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu } 792918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu } 793918306ceb829009d348a749a7a648ba3a727e2c3Dake Gu 7944705eed4421d3b00923b56062765206dea21387eDake Gu /** 7954705eed4421d3b00923b56062765206dea21387eDake Gu * Called by {@link #onBindViewHolder(ViewHolder, GuidedAction)} to setup IME options. Default 7964705eed4421d3b00923b56062765206dea21387eDake Gu * implementation assigns {@link EditorInfo#IME_ACTION_DONE}. Subclass may override. 7974705eed4421d3b00923b56062765206dea21387eDake Gu * @param vh The view holder to be associated with the given action. 7984705eed4421d3b00923b56062765206dea21387eDake Gu * @param action The guided action to be displayed by the view holder's view. 7994705eed4421d3b00923b56062765206dea21387eDake Gu */ 8004705eed4421d3b00923b56062765206dea21387eDake Gu protected void setupImeOptions(ViewHolder vh, GuidedAction action) { 8014705eed4421d3b00923b56062765206dea21387eDake Gu setupNextImeOptions(vh.getEditableTitleView()); 8024705eed4421d3b00923b56062765206dea21387eDake Gu setupNextImeOptions(vh.getEditableDescriptionView()); 8034705eed4421d3b00923b56062765206dea21387eDake Gu } 8044705eed4421d3b00923b56062765206dea21387eDake Gu 8054705eed4421d3b00923b56062765206dea21387eDake Gu private void setupNextImeOptions(EditText edit) { 8064705eed4421d3b00923b56062765206dea21387eDake Gu if (edit != null) { 8074705eed4421d3b00923b56062765206dea21387eDake Gu edit.setImeOptions(EditorInfo.IME_ACTION_NEXT); 8084705eed4421d3b00923b56062765206dea21387eDake Gu } 809c1741246af607f6be2389056da0182c40f938348Dake Gu } 810c1741246af607f6be2389056da0182c40f938348Dake Gu 81177d397d533d04dfec663939692f2e048a072ee5bAlan Viverette /** 81277d397d533d04dfec663939692f2e048a072ee5bAlan Viverette * @deprecated This method is for internal library use only and should not 81377d397d533d04dfec663939692f2e048a072ee5bAlan Viverette * be called directly. 81477d397d533d04dfec663939692f2e048a072ee5bAlan Viverette */ 81577d397d533d04dfec663939692f2e048a072ee5bAlan Viverette @Deprecated 81677d397d533d04dfec663939692f2e048a072ee5bAlan Viverette public void setEditingMode(ViewHolder vh, GuidedAction action, boolean editing) { 81777d397d533d04dfec663939692f2e048a072ee5bAlan Viverette if (editing != vh.isInEditing() && isInExpandTransition()) { 81877d397d533d04dfec663939692f2e048a072ee5bAlan Viverette onEditingModeChange(vh, action, editing); 81977d397d533d04dfec663939692f2e048a072ee5bAlan Viverette } 82077d397d533d04dfec663939692f2e048a072ee5bAlan Viverette } 82177d397d533d04dfec663939692f2e048a072ee5bAlan Viverette 822ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu void setEditingMode(ViewHolder vh, boolean editing) { 823ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu setEditingMode(vh, editing, true /*withTransition*/); 824ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 825ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 826ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu void setEditingMode(ViewHolder vh, boolean editing, boolean withTransition) { 827b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (editing != vh.isInEditing() && !isInExpandTransition()) { 828ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu onEditingModeChange(vh, editing, withTransition); 829c1741246af607f6be2389056da0182c40f938348Dake Gu } 830c1741246af607f6be2389056da0182c40f938348Dake Gu } 831c1741246af607f6be2389056da0182c40f938348Dake Gu 832ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu /** 833ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @deprecated Use {@link #onEditingModeChange(ViewHolder, boolean, boolean)}. 834ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu */ 835ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu @Deprecated 836c1741246af607f6be2389056da0182c40f938348Dake Gu protected void onEditingModeChange(ViewHolder vh, GuidedAction action, boolean editing) { 837ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 838ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 839ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu /** 840ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * Called when editing mode of an ViewHolder is changed. Subclass must call 841ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * <code>super.onEditingModeChange(vh,editing,withTransition)</code>. 842ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * 843ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @param vh ViewHolder to change editing mode. 844ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @param editing True to enable editing, false to stop editing 845ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @param withTransition True to run expand transiiton, false otherwise. 846ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu */ 847ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu @CallSuper 848ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu protected void onEditingModeChange(ViewHolder vh, boolean editing, boolean withTransition) { 849ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu GuidedAction action = vh.getAction(); 850c1741246af607f6be2389056da0182c40f938348Dake Gu TextView titleView = vh.getTitleView(); 851c1741246af607f6be2389056da0182c40f938348Dake Gu TextView descriptionView = vh.getDescriptionView(); 852c1741246af607f6be2389056da0182c40f938348Dake Gu if (editing) { 853c1741246af607f6be2389056da0182c40f938348Dake Gu CharSequence editTitle = action.getEditTitle(); 854c1741246af607f6be2389056da0182c40f938348Dake Gu if (titleView != null && editTitle != null) { 855c1741246af607f6be2389056da0182c40f938348Dake Gu titleView.setText(editTitle); 856c1741246af607f6be2389056da0182c40f938348Dake Gu } 857c1741246af607f6be2389056da0182c40f938348Dake Gu CharSequence editDescription = action.getEditDescription(); 858c1741246af607f6be2389056da0182c40f938348Dake Gu if (descriptionView != null && editDescription != null) { 859c1741246af607f6be2389056da0182c40f938348Dake Gu descriptionView.setText(editDescription); 860c1741246af607f6be2389056da0182c40f938348Dake Gu } 861c1741246af607f6be2389056da0182c40f938348Dake Gu if (action.isDescriptionEditable()) { 862c1741246af607f6be2389056da0182c40f938348Dake Gu if (descriptionView != null) { 863c1741246af607f6be2389056da0182c40f938348Dake Gu descriptionView.setVisibility(View.VISIBLE); 8649562425bf9bc15281ac27df817141854769c1042Dake Gu descriptionView.setInputType(action.getDescriptionEditInputType()); 865c1741246af607f6be2389056da0182c40f938348Dake Gu } 866b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu vh.mEditingMode = EDITING_DESCRIPTION; 867b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } else if (action.isEditable()){ 8689562425bf9bc15281ac27df817141854769c1042Dake Gu if (titleView != null) { 8699562425bf9bc15281ac27df817141854769c1042Dake Gu titleView.setInputType(action.getEditInputType()); 8709562425bf9bc15281ac27df817141854769c1042Dake Gu } 871b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu vh.mEditingMode = EDITING_TITLE; 872b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } else if (vh.mActivatorView != null) { 873ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu onEditActivatorView(vh, editing, withTransition); 874b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu vh.mEditingMode = EDITING_ACTIVATOR_VIEW; 875c1741246af607f6be2389056da0182c40f938348Dake Gu } 876c1741246af607f6be2389056da0182c40f938348Dake Gu } else { 877c1741246af607f6be2389056da0182c40f938348Dake Gu if (titleView != null) { 878c1741246af607f6be2389056da0182c40f938348Dake Gu titleView.setText(action.getTitle()); 879c1741246af607f6be2389056da0182c40f938348Dake Gu } 880c1741246af607f6be2389056da0182c40f938348Dake Gu if (descriptionView != null) { 881c1741246af607f6be2389056da0182c40f938348Dake Gu descriptionView.setText(action.getDescription()); 882c1741246af607f6be2389056da0182c40f938348Dake Gu } 883b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (vh.mEditingMode == EDITING_DESCRIPTION) { 884c1741246af607f6be2389056da0182c40f938348Dake Gu if (descriptionView != null) { 8853103f63e99d47573823957f7aa34308555873221Aurimas Liutikas descriptionView.setVisibility(TextUtils.isEmpty(action.getDescription()) 8863103f63e99d47573823957f7aa34308555873221Aurimas Liutikas ? View.GONE : View.VISIBLE); 8879562425bf9bc15281ac27df817141854769c1042Dake Gu descriptionView.setInputType(action.getDescriptionInputType()); 888c1741246af607f6be2389056da0182c40f938348Dake Gu } 889b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } else if (vh.mEditingMode == EDITING_TITLE) { 8909562425bf9bc15281ac27df817141854769c1042Dake Gu if (titleView != null) { 8919562425bf9bc15281ac27df817141854769c1042Dake Gu titleView.setInputType(action.getInputType()); 8929562425bf9bc15281ac27df817141854769c1042Dake Gu } 893b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } else if (vh.mEditingMode == EDITING_ACTIVATOR_VIEW) { 894b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (vh.mActivatorView != null) { 895ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu onEditActivatorView(vh, editing, withTransition); 896b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 897c1741246af607f6be2389056da0182c40f938348Dake Gu } 898b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu vh.mEditingMode = EDITING_NONE; 899c1741246af607f6be2389056da0182c40f938348Dake Gu } 900ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu // call deprecated method for backward compatible 901ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu onEditingModeChange(vh, action, editing); 902ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 903ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 904ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 905ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Animates the view holder's view (or subviews thereof) when the action has had its focus 906ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * state changed. 907ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @param vh The view holder associated with the relevant action. 908ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @param focused True if the action has become focused, false if it has lost focus. 909ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 910ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public void onAnimateItemFocused(ViewHolder vh, boolean focused) { 911ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing // No animations for this, currently, because the animation is done on 912ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing // mSelectorView 913ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 914ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 915ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 916ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Animates the view holder's view (or subviews thereof) when the action has had its press 917ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * state changed. 918ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @param vh The view holder associated with the relevant action. 919ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @param pressed True if the action has been pressed, false if it has been unpressed. 920ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 921ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public void onAnimateItemPressed(ViewHolder vh, boolean pressed) { 92266e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu vh.press(pressed); 923ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 924ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 925ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 92619c1329def8d277c914cba46540d24bfde58b2a4Dake Gu * Resets the view holder's view to unpressed state. 92719c1329def8d277c914cba46540d24bfde58b2a4Dake Gu * @param vh The view holder associated with the relevant action. 92819c1329def8d277c914cba46540d24bfde58b2a4Dake Gu */ 92919c1329def8d277c914cba46540d24bfde58b2a4Dake Gu public void onAnimateItemPressedCancelled(ViewHolder vh) { 93066e932ebd959ffe318f0780c5f689bac29b09b50Dake Gu vh.press(false); 93119c1329def8d277c914cba46540d24bfde58b2a4Dake Gu } 93219c1329def8d277c914cba46540d24bfde58b2a4Dake Gu 93319c1329def8d277c914cba46540d24bfde58b2a4Dake Gu /** 93411cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * Animates the view holder's view (or subviews thereof) when the action has had its check state 93511cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * changed. Default implementation calls setChecked() if {@link ViewHolder#getCheckmarkView()} 93611cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * is instance of {@link Checkable}. 93711cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * 938ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @param vh The view holder associated with the relevant action. 939ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @param checked True if the action has become checked, false if it has become unchecked. 94011cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * @see #onBindCheckMarkView(ViewHolder, GuidedAction) 941ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 942ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing public void onAnimateItemChecked(ViewHolder vh, boolean checked) { 94311cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu if (vh.mCheckmarkView instanceof Checkable) { 94411cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu ((Checkable) vh.mCheckmarkView).setChecked(checked); 94511cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu } 94611cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu } 94711cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu 94811cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu /** 94911cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * Sets states of check mark view, called by {@link #onBindViewHolder(ViewHolder, GuidedAction)} 95011cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * when action's checkset Id is other than {@link GuidedAction#NO_CHECK_SET}. Default 95111cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * implementation assigns drawable loaded from theme attribute 95211cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * {@link android.R.attr#listChoiceIndicatorMultiple} for checkbox or 95311cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * {@link android.R.attr#listChoiceIndicatorSingle} for radio button. Subclass rarely needs 95411cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * override the method, instead app can provide its own drawable that supports transition 95511cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * animations, change theme attributes {@link android.R.attr#listChoiceIndicatorMultiple} and 956ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * {@link android.R.attr#listChoiceIndicatorSingle} in {androidx.leanback.R. 95711cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * styleable#LeanbackGuidedStepTheme}. 95811cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * 95911cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * @param vh The view holder associated with the relevant action. 96011cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * @param action The GuidedAction object to bind to. 96111cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * @see #onAnimateItemChecked(ViewHolder, boolean) 96211cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu */ 96311cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu public void onBindCheckMarkView(ViewHolder vh, GuidedAction action) { 96411cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu if (action.getCheckSetId() != GuidedAction.NO_CHECK_SET) { 96511cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu vh.mCheckmarkView.setVisibility(View.VISIBLE); 9663103f63e99d47573823957f7aa34308555873221Aurimas Liutikas int attrId = action.getCheckSetId() == GuidedAction.CHECKBOX_CHECK_SET_ID 9673103f63e99d47573823957f7aa34308555873221Aurimas Liutikas ? android.R.attr.listChoiceIndicatorMultiple 9683103f63e99d47573823957f7aa34308555873221Aurimas Liutikas : android.R.attr.listChoiceIndicatorSingle; 96911cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu final Context context = vh.mCheckmarkView.getContext(); 97011cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu Drawable drawable = null; 97111cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu TypedValue typedValue = new TypedValue(); 97211cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu if (context.getTheme().resolveAttribute(attrId, typedValue, true)) { 97311cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu drawable = ContextCompat.getDrawable(context, typedValue.resourceId); 974ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 97511cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu vh.mCheckmarkView.setImageDrawable(drawable); 97611cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu if (vh.mCheckmarkView instanceof Checkable) { 97711cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu ((Checkable) vh.mCheckmarkView).setChecked(action.isChecked()); 97811cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu } 97911cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu } else { 98011cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu vh.mCheckmarkView.setVisibility(View.GONE); 981ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 982ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 983ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 98411cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu /** 985b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * Performs binding activator view value to action. Default implementation supports 986b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * GuidedDatePickerAction, subclass may override to add support of other views. 987b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * @param vh ViewHolder of activator view. 988b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * @param action GuidedAction to bind. 989b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu */ 990b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu public void onBindActivatorView(ViewHolder vh, GuidedAction action) { 991b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (action instanceof GuidedDatePickerAction) { 992b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu GuidedDatePickerAction dateAction = (GuidedDatePickerAction) action; 993b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu DatePicker dateView = (DatePicker) vh.mActivatorView; 994b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu dateView.setDatePickerFormat(dateAction.getDatePickerFormat()); 995942f79291db75ccf6ecd0351d23a444a43dd0501Dake Gu if (dateAction.getMinDate() != Long.MIN_VALUE) { 996942f79291db75ccf6ecd0351d23a444a43dd0501Dake Gu dateView.setMinDate(dateAction.getMinDate()); 997942f79291db75ccf6ecd0351d23a444a43dd0501Dake Gu } 998942f79291db75ccf6ecd0351d23a444a43dd0501Dake Gu if (dateAction.getMaxDate() != Long.MAX_VALUE) { 999942f79291db75ccf6ecd0351d23a444a43dd0501Dake Gu dateView.setMaxDate(dateAction.getMaxDate()); 1000942f79291db75ccf6ecd0351d23a444a43dd0501Dake Gu } 1001b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu Calendar c = Calendar.getInstance(); 1002942f79291db75ccf6ecd0351d23a444a43dd0501Dake Gu c.setTimeInMillis(dateAction.getDate()); 1003b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu dateView.updateDate(c.get(Calendar.YEAR), c.get(Calendar.MONTH), 1004b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu c.get(Calendar.DAY_OF_MONTH), false); 1005b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 1006b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 1007b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu 1008b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu /** 1009b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * Performs updating GuidedAction from activator view. Default implementation supports 1010b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * GuidedDatePickerAction, subclass may override to add support of other views. 1011b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * @param vh ViewHolder of activator view. 1012b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * @param action GuidedAction to update. 1013b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * @return True if value has been updated, false otherwise. 1014b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu */ 1015b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu public boolean onUpdateActivatorView(ViewHolder vh, GuidedAction action) { 1016b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (action instanceof GuidedDatePickerAction) { 1017b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu GuidedDatePickerAction dateAction = (GuidedDatePickerAction) action; 1018b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu DatePicker dateView = (DatePicker) vh.mActivatorView; 1019b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (dateAction.getDate() != dateView.getDate()) { 1020b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu dateAction.setDate(dateView.getDate()); 1021b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu return true; 1022b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 1023b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 1024b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu return false; 1025b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 1026b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu 1027b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu /** 1028b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * Sets listener for reporting view being edited. 1029b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu * @hide 1030b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu */ 10318e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas @RestrictTo(LIBRARY_GROUP) 1032b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu public void setEditListener(EditListener listener) { 1033b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu mEditListener = listener; 1034b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 1035b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu 1036ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu void onEditActivatorView(final ViewHolder vh, boolean editing, final boolean withTransition) { 1037b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (editing) { 1038b0818cc234e9df4312732f95fd6849922bfa0fa1Keyvan Amiri startExpanded(vh, withTransition); 10390f96ae4965103bade4bebe7776b2ee35cd603112Dake Gu vh.itemView.setFocusable(false); 1040b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu vh.mActivatorView.requestFocus(); 1041b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu vh.mActivatorView.setOnClickListener(new View.OnClickListener() { 1042b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu @Override 1043b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu public void onClick(View v) { 1044b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (!isInExpandTransition()) { 1045ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu ((GuidedActionAdapter) getActionsGridView().getAdapter()) 1046ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu .performOnActionClick(vh); 1047b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 1048b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 1049b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu }); 1050b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } else { 1051ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (onUpdateActivatorView(vh, vh.getAction())) { 1052b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (mEditListener != null) { 1053ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu mEditListener.onGuidedActionEditedAndProceed(vh.getAction()); 1054b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 1055b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 10560f96ae4965103bade4bebe7776b2ee35cd603112Dake Gu vh.itemView.setFocusable(true); 1057b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu vh.itemView.requestFocus(); 1058ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu startExpanded(null, withTransition); 1059b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu vh.mActivatorView.setOnClickListener(null); 10600f96ae4965103bade4bebe7776b2ee35cd603112Dake Gu vh.mActivatorView.setClickable(false); 1061b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 1062b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 1063b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu 1064b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu /** 106511cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * Sets states of chevron view, called by {@link #onBindViewHolder(ViewHolder, GuidedAction)}. 106611cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * Subclass may override. 106711cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * 106811cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * @param vh The view holder associated with the relevant action. 106911cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu * @param action The GuidedAction object to bind to. 107011cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu */ 107111cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu public void onBindChevronView(ViewHolder vh, GuidedAction action) { 1072be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu final boolean hasNext = action.hasNext(); 1073be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu final boolean hasSubActions = action.hasSubActions(); 1074be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu if (hasNext || hasSubActions) { 1075be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu vh.mChevronView.setVisibility(View.VISIBLE); 1076be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu vh.mChevronView.setAlpha(action.isEnabled() ? mEnabledChevronAlpha : 1077be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu mDisabledChevronAlpha); 1078be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu if (hasNext) { 10797a45714d94e3e5566e3879042f7ee2b93eb5c62aDake Gu float r = mMainView != null 10807a45714d94e3e5566e3879042f7ee2b93eb5c62aDake Gu && mMainView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL ? 180f : 0f; 10817a45714d94e3e5566e3879042f7ee2b93eb5c62aDake Gu vh.mChevronView.setRotation(r); 1082be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } else if (action == mExpandedAction) { 1083be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu vh.mChevronView.setRotation(270); 1084be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } else { 1085be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu vh.mChevronView.setRotation(90); 1086be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 1087be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } else { 1088be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu vh.mChevronView.setVisibility(View.GONE); 1089be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu 1090be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 1091be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 1092be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu 1093be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu /** 1094ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * Expands or collapse the sub actions list view with transition animation 1095be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * @param avh When not null, fill sub actions list of this ViewHolder into sub actions list and 1096be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * hide the other items in main list. When null, collapse the sub actions list. 1097ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @deprecated use {@link #expandAction(GuidedAction, boolean)} and 1098ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * {@link #collapseAction(boolean)} 1099be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu */ 1100ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu @Deprecated 1101be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu public void setExpandedViewHolder(ViewHolder avh) { 1102ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu expandAction(avh == null ? null : avh.getAction(), isExpandTransitionSupported()); 11031ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } 11041ed9dc77616514e20c51baa67a04adab42e4135eDake Gu 11051ed9dc77616514e20c51baa67a04adab42e4135eDake Gu /** 11061ed9dc77616514e20c51baa67a04adab42e4135eDake Gu * Returns true if it is running an expanding or collapsing transition, false otherwise. 11071ed9dc77616514e20c51baa67a04adab42e4135eDake Gu * @return True if it is running an expanding or collapsing transition, false otherwise. 11081ed9dc77616514e20c51baa67a04adab42e4135eDake Gu */ 11091ed9dc77616514e20c51baa67a04adab42e4135eDake Gu public boolean isInExpandTransition() { 11101ed9dc77616514e20c51baa67a04adab42e4135eDake Gu return mExpandTransition != null; 11111ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } 11121ed9dc77616514e20c51baa67a04adab42e4135eDake Gu 11131ed9dc77616514e20c51baa67a04adab42e4135eDake Gu /** 11141ed9dc77616514e20c51baa67a04adab42e4135eDake Gu * Returns if expand/collapse animation is supported. When this method returns true, 11151ed9dc77616514e20c51baa67a04adab42e4135eDake Gu * {@link #startExpandedTransition(ViewHolder)} will be used. When this method returns false, 11161ed9dc77616514e20c51baa67a04adab42e4135eDake Gu * {@link #onUpdateExpandedViewHolder(ViewHolder)} will be called. 11171ed9dc77616514e20c51baa67a04adab42e4135eDake Gu * @return True if it is running an expanding or collapsing transition, false otherwise. 11181ed9dc77616514e20c51baa67a04adab42e4135eDake Gu */ 11191ed9dc77616514e20c51baa67a04adab42e4135eDake Gu public boolean isExpandTransitionSupported() { 11201ed9dc77616514e20c51baa67a04adab42e4135eDake Gu return VERSION.SDK_INT >= 21; 11211ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } 11221ed9dc77616514e20c51baa67a04adab42e4135eDake Gu 11231ed9dc77616514e20c51baa67a04adab42e4135eDake Gu /** 11241ed9dc77616514e20c51baa67a04adab42e4135eDake Gu * Start transition to expand or collapse GuidedActionStylist. 11251ed9dc77616514e20c51baa67a04adab42e4135eDake Gu * @param avh When not null, the GuidedActionStylist expands the sub actions of avh. When null 11261ed9dc77616514e20c51baa67a04adab42e4135eDake Gu * the GuidedActionStylist will collapse sub actions. 1127ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @deprecated use {@link #expandAction(GuidedAction, boolean)} and 1128ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * {@link #collapseAction(boolean)} 11291ed9dc77616514e20c51baa67a04adab42e4135eDake Gu */ 1130ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu @Deprecated 11311ed9dc77616514e20c51baa67a04adab42e4135eDake Gu public void startExpandedTransition(ViewHolder avh) { 1132ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu expandAction(avh == null ? null : avh.getAction(), isExpandTransitionSupported()); 1133ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1134ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 1135ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu /** 1136ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * Enable or disable using BACK key to collapse sub actions list. Default is enabled. 1137ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * 1138ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @param backToCollapse True to enable using BACK key to collapse sub actions list, false 1139ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * to disable. 1140ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @see GuidedAction#hasSubActions 1141ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @see GuidedAction#getSubActions 1142ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu */ 1143ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu public final void setBackKeyToCollapseSubActions(boolean backToCollapse) { 1144ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu mBackToCollapseSubActions = backToCollapse; 1145ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1146ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 1147ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu /** 1148ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @return True if using BACK key to collapse sub actions list, false otherwise. Default value 1149ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * is true. 1150ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * 1151ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @see GuidedAction#hasSubActions 1152ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @see GuidedAction#getSubActions 1153ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu */ 1154ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu public final boolean isBackKeyToCollapseSubActions() { 1155ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu return mBackToCollapseSubActions; 1156ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1157ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 1158ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu /** 1159ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * Enable or disable using BACK key to collapse {@link GuidedAction} with editable activator 1160ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * view. Default is enabled. 1161ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * 1162ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @param backToCollapse True to enable using BACK key to collapse {@link GuidedAction} with 1163ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * editable activator view. 1164ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @see GuidedAction#hasEditableActivatorView 1165ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu */ 1166ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu public final void setBackKeyToCollapseActivatorView(boolean backToCollapse) { 1167ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu mBackToCollapseActivatorView = backToCollapse; 1168ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1169ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 1170ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu /** 1171ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @return True if using BACK key to collapse {@link GuidedAction} with editable activator 1172ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * view, false otherwise. Default value is true. 1173ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * 1174ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @see GuidedAction#hasEditableActivatorView 1175ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu */ 1176ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu public final boolean isBackKeyToCollapseActivatorView() { 1177ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu return mBackToCollapseActivatorView; 1178ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1179ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 1180ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu /** 1181ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * Expand an action. Do nothing if it is in animation or there is action expanded. 1182ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * 1183ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @param action Action to expand. 1184ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @param withTransition True to run transition animation, false otherwsie. 1185ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu */ 1186ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu public void expandAction(GuidedAction action, final boolean withTransition) { 1187ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (isInExpandTransition() || mExpandedAction != null) { 1188ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu return; 1189ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1190ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu int actionPosition = 1191ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu ((GuidedActionAdapter) getActionsGridView().getAdapter()).indexOf(action); 1192ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (actionPosition < 0) { 1193ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu return; 1194ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1195ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu boolean runTransition = isExpandTransitionSupported() && withTransition; 1196ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (!runTransition) { 1197ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu getActionsGridView().setSelectedPosition(actionPosition, 1198ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu new ViewHolderTask() { 1199ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu @Override 1200ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu public void run(RecyclerView.ViewHolder vh) { 1201ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu GuidedActionsStylist.ViewHolder avh = 1202ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu (GuidedActionsStylist.ViewHolder)vh; 1203ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (avh.getAction().hasEditableActivatorView()) { 1204ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu setEditingMode(avh, true /*editing*/, false /*withTransition*/); 1205ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } else { 1206ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu onUpdateExpandedViewHolder(avh); 1207ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1208ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1209ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu }); 1210e5d263725fb60aa6a24f2221548afb20d0dc46e1Dake Gu if (action.hasSubActions()) { 1211e5d263725fb60aa6a24f2221548afb20d0dc46e1Dake Gu onUpdateSubActionsGridView(action, true); 1212e5d263725fb60aa6a24f2221548afb20d0dc46e1Dake Gu } 1213ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } else { 1214ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu getActionsGridView().setSelectedPosition(actionPosition, 1215ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu new ViewHolderTask() { 1216ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu @Override 1217ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu public void run(RecyclerView.ViewHolder vh) { 1218ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu GuidedActionsStylist.ViewHolder avh = 1219ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu (GuidedActionsStylist.ViewHolder)vh; 1220ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (avh.getAction().hasEditableActivatorView()) { 1221ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu setEditingMode(avh, true /*editing*/, true /*withTransition*/); 1222ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } else { 1223ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu startExpanded(avh, true); 1224ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1225ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1226ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu }); 1227ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1228ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 1229ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1230ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 1231ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu /** 1232ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * Collapse expanded action. Do nothing if it is in animation or there is no action expanded. 1233ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * 1234ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @param withTransition True to run transition animation, false otherwsie. 1235ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu */ 1236ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu public void collapseAction(boolean withTransition) { 1237ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (isInExpandTransition() || mExpandedAction == null) { 1238ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu return; 1239ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1240ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu boolean runTransition = isExpandTransitionSupported() && withTransition; 1241ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu int actionPosition = 1242ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu ((GuidedActionAdapter) getActionsGridView().getAdapter()).indexOf(mExpandedAction); 1243ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (actionPosition < 0) { 1244ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu return; 1245ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1246ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (mExpandedAction.hasEditableActivatorView()) { 1247ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu setEditingMode( 1248ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu ((ViewHolder) getActionsGridView().findViewHolderForPosition(actionPosition)), 1249ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu false /*editing*/, 1250ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu runTransition); 1251ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } else { 1252ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu startExpanded(null, runTransition); 1253ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1254ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1255ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 1256ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu int getKeyLine() { 1257ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu return (int) (mKeyLinePercent * mActionsGridView.getHeight() / 100); 1258ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1259ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 1260ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu /** 1261ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * Internal method with assumption we already scroll to the new ViewHolder or is currently 1262ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * expanded. 1263ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu */ 1264ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu void startExpanded(ViewHolder avh, final boolean withTransition) { 12651ed9dc77616514e20c51baa67a04adab42e4135eDake Gu ViewHolder focusAvh = null; // expand / collapse view holder 12661ed9dc77616514e20c51baa67a04adab42e4135eDake Gu final int count = mActionsGridView.getChildCount(); 12671ed9dc77616514e20c51baa67a04adab42e4135eDake Gu for (int i = 0; i < count; i++) { 12681ed9dc77616514e20c51baa67a04adab42e4135eDake Gu ViewHolder vh = (ViewHolder) mActionsGridView 12691ed9dc77616514e20c51baa67a04adab42e4135eDake Gu .getChildViewHolder(mActionsGridView.getChildAt(i)); 12701ed9dc77616514e20c51baa67a04adab42e4135eDake Gu if (avh == null && vh.itemView.getVisibility() == View.VISIBLE) { 12711ed9dc77616514e20c51baa67a04adab42e4135eDake Gu // going to collapse this one. 12721ed9dc77616514e20c51baa67a04adab42e4135eDake Gu focusAvh = vh; 12731ed9dc77616514e20c51baa67a04adab42e4135eDake Gu break; 12741ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } else if (avh != null && vh.getAction() == avh.getAction()) { 12751ed9dc77616514e20c51baa67a04adab42e4135eDake Gu // going to expand this one. 12761ed9dc77616514e20c51baa67a04adab42e4135eDake Gu focusAvh = vh; 12771ed9dc77616514e20c51baa67a04adab42e4135eDake Gu break; 12781ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } 12791ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } 12801ed9dc77616514e20c51baa67a04adab42e4135eDake Gu if (focusAvh == null) { 12811ed9dc77616514e20c51baa67a04adab42e4135eDake Gu // huh? 12821ed9dc77616514e20c51baa67a04adab42e4135eDake Gu return; 12831ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } 1284ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu boolean isExpand = avh != null; 1285b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu boolean isSubActionTransition = focusAvh.getAction().hasSubActions(); 1286ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (withTransition) { 1287ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu Object set = TransitionHelper.createTransitionSet(false); 1288ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu float slideDistance = isSubActionTransition ? focusAvh.itemView.getHeight() 1289ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu : focusAvh.itemView.getHeight() * 0.5f; 1290ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu Object slideAndFade = TransitionHelper.createFadeAndShortSlide( 1291ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu Gravity.TOP | Gravity.BOTTOM, 1292ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu slideDistance); 1293ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.setEpicenterCallback(slideAndFade, new TransitionEpicenterCallback() { 1294ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu Rect mRect = new Rect(); 1295ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu @Override 1296ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu public Rect onGetEpicenter(Object transition) { 1297ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu int centerY = getKeyLine(); 1298ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu int centerX = 0; 1299ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu mRect.set(centerX, centerY, centerX, centerY); 1300ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu return mRect; 1301b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 1302ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu }); 1303ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu Object changeFocusItemTransform = TransitionHelper.createChangeTransform(); 1304ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu Object changeFocusItemBounds = TransitionHelper.createChangeBounds(false); 13053103f63e99d47573823957f7aa34308555873221Aurimas Liutikas Object fade = TransitionHelper.createFadeTransition(TransitionHelper.FADE_IN 13063103f63e99d47573823957f7aa34308555873221Aurimas Liutikas | TransitionHelper.FADE_OUT); 1307ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu Object changeGridBounds = TransitionHelper.createChangeBounds(false); 1308ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (avh == null) { 1309ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.setStartDelay(slideAndFade, 150); 1310ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.setStartDelay(changeFocusItemTransform, 100); 1311ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.setStartDelay(changeFocusItemBounds, 100); 1312ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.setStartDelay(changeGridBounds, 100); 13131ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } else { 1314ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.setStartDelay(fade, 100); 1315ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.setStartDelay(changeGridBounds, 50); 1316ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.setStartDelay(changeFocusItemTransform, 50); 1317ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.setStartDelay(changeFocusItemBounds, 50); 13181ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } 1319ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu for (int i = 0; i < count; i++) { 1320ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu ViewHolder vh = (ViewHolder) mActionsGridView 1321ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu .getChildViewHolder(mActionsGridView.getChildAt(i)); 1322ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (vh == focusAvh) { 1323ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu // going to expand/collapse this one. 1324ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (isSubActionTransition) { 1325ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.include(changeFocusItemTransform, vh.itemView); 1326ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.include(changeFocusItemBounds, vh.itemView); 1327ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1328ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } else { 1329ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu // going to slide this item to top / bottom. 1330ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.include(slideAndFade, vh.itemView); 1331ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.exclude(fade, vh.itemView, true); 1332ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1333ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1334ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.include(changeGridBounds, mSubActionsGridView); 1335ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.include(changeGridBounds, mSubActionsBackground); 1336ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.addTransition(set, slideAndFade); 1337ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu // note that we don't run ChangeBounds for activating view due to the rounding problem 1338ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu // of multiple level views ChangeBounds animation causing vertical jittering. 1339ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (isSubActionTransition) { 1340ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.addTransition(set, changeFocusItemTransform); 1341ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.addTransition(set, changeFocusItemBounds); 13421ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } 1343ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.addTransition(set, fade); 1344ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.addTransition(set, changeGridBounds); 1345ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu mExpandTransition = set; 1346ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.addTransitionListener(mExpandTransition, new TransitionListener() { 13471ed9dc77616514e20c51baa67a04adab42e4135eDake Gu @Override 1348ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu public void onTransitionEnd(Object transition) { 1349ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu mExpandTransition = null; 13501ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } 13511ed9dc77616514e20c51baa67a04adab42e4135eDake Gu }); 1352ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (isExpand && isSubActionTransition) { 1353ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu // To expand sub actions, move original position of sub actions to bottom of item 1354ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu int startY = avh.itemView.getBottom(); 1355ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu mSubActionsGridView.offsetTopAndBottom(startY - mSubActionsGridView.getTop()); 1356ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu mSubActionsBackground.offsetTopAndBottom(startY - mSubActionsBackground.getTop()); 1357ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1358ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu TransitionHelper.beginDelayedTransition(mMainView, mExpandTransition); 13591ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } 13601ed9dc77616514e20c51baa67a04adab42e4135eDake Gu onUpdateExpandedViewHolder(avh); 1361ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (isSubActionTransition) { 1362ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu onUpdateSubActionsGridView(focusAvh.getAction(), isExpand); 1363ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1364be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 1365be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu 1366be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu /** 1367be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * @return True if sub actions list is expanded. 1368be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu */ 1369be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu public boolean isSubActionsExpanded() { 1370ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu return mExpandedAction != null && mExpandedAction.hasSubActions(); 1371ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1372ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 1373ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu /** 1374ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu * @return True if there is {@link #getExpandedAction()} is not null, false otherwise. 1375ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu */ 1376ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu public boolean isExpanded() { 1377be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu return mExpandedAction != null; 1378be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 1379be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu 1380be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu /** 1381be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu * @return Current expanded GuidedAction or null if not expanded. 1382be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu */ 1383be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu public GuidedAction getExpandedAction() { 1384be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu return mExpandedAction; 1385be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 1386be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu 13871ed9dc77616514e20c51baa67a04adab42e4135eDake Gu /** 13881ed9dc77616514e20c51baa67a04adab42e4135eDake Gu * Expand or collapse GuidedActionStylist. 13891ed9dc77616514e20c51baa67a04adab42e4135eDake Gu * @param avh When not null, the GuidedActionStylist expands the sub actions of avh. When null 13901ed9dc77616514e20c51baa67a04adab42e4135eDake Gu * the GuidedActionStylist will collapse sub actions. 13911ed9dc77616514e20c51baa67a04adab42e4135eDake Gu */ 13921ed9dc77616514e20c51baa67a04adab42e4135eDake Gu public void onUpdateExpandedViewHolder(ViewHolder avh) { 1393b2121d7935303972c0d515c29b9771c74311c8baKeyvan Amiri 1394b2121d7935303972c0d515c29b9771c74311c8baKeyvan Amiri // Note about setting the prune child flag back & forth here: without this, the actions that 1395b2121d7935303972c0d515c29b9771c74311c8baKeyvan Amiri // go off the screen from the top or bottom become invisible forever. This is because once 1396b2121d7935303972c0d515c29b9771c74311c8baKeyvan Amiri // an action is expanded, it takes more space which in turn kicks out some other actions 1397b2121d7935303972c0d515c29b9771c74311c8baKeyvan Amiri // off of the screen. Once, this action is collapsed (after the second click) and the 1398b2121d7935303972c0d515c29b9771c74311c8baKeyvan Amiri // visibility flag is set back to true for all existing actions, 1399b2121d7935303972c0d515c29b9771c74311c8baKeyvan Amiri // the off-the-screen actions are pruned from the view, thus 1400b2121d7935303972c0d515c29b9771c74311c8baKeyvan Amiri // could not be accessed, had we not disabled pruning prior to this. 14011ed9dc77616514e20c51baa67a04adab42e4135eDake Gu if (avh == null) { 14021ed9dc77616514e20c51baa67a04adab42e4135eDake Gu mExpandedAction = null; 1403b2121d7935303972c0d515c29b9771c74311c8baKeyvan Amiri mActionsGridView.setPruneChild(true); 14041ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } else if (avh.getAction() != mExpandedAction) { 14051ed9dc77616514e20c51baa67a04adab42e4135eDake Gu mExpandedAction = avh.getAction(); 1406b2121d7935303972c0d515c29b9771c74311c8baKeyvan Amiri mActionsGridView.setPruneChild(false); 14071ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } 1408fb23f1271e21761bb523948d9ea9c60c42ae7251Dake Gu // In expanding mode, notifyItemChange on expanded item will reset the translationY by 1409fb23f1271e21761bb523948d9ea9c60c42ae7251Dake Gu // the default ItemAnimator. So disable ItemAnimation in expanding mode. 1410fb23f1271e21761bb523948d9ea9c60c42ae7251Dake Gu mActionsGridView.setAnimateChildLayout(false); 1411be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu final int count = mActionsGridView.getChildCount(); 1412be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu for (int i = 0; i < count; i++) { 1413be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu ViewHolder vh = (ViewHolder) mActionsGridView 1414be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu .getChildViewHolder(mActionsGridView.getChildAt(i)); 1415be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu updateChevronAndVisibility(vh); 1416be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 1417ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } 1418ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu 1419ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu void onUpdateSubActionsGridView(GuidedAction action, boolean expand) { 1420be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu if (mSubActionsGridView != null) { 1421ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu ViewGroup.MarginLayoutParams lp = 1422ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu (ViewGroup.MarginLayoutParams) mSubActionsGridView.getLayoutParams(); 1423ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu GuidedActionAdapter adapter = (GuidedActionAdapter) mSubActionsGridView.getAdapter(); 1424ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu if (expand) { 1425ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu // set to negative value so GuidedActionRelativeLayout will override with 1426ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu // keyLine percentage. 1427ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu lp.topMargin = -2; 14281ed9dc77616514e20c51baa67a04adab42e4135eDake Gu lp.height = ViewGroup.MarginLayoutParams.MATCH_PARENT; 14291ed9dc77616514e20c51baa67a04adab42e4135eDake Gu mSubActionsGridView.setLayoutParams(lp); 14301ed9dc77616514e20c51baa67a04adab42e4135eDake Gu mSubActionsGridView.setVisibility(View.VISIBLE); 1431fa4d2cddf2cb9619088153a1fe07d09203d792faDake Gu mSubActionsBackground.setVisibility(View.VISIBLE); 14321ed9dc77616514e20c51baa67a04adab42e4135eDake Gu mSubActionsGridView.requestFocus(); 1433ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu adapter.setActions(action.getSubActions()); 1434ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu } else { 1435ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu // set to explicit value, which will disable the keyLine percentage calculation 1436ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu // in GuidedRelativeLayout. 1437ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu int actionPosition = ((GuidedActionAdapter) mActionsGridView.getAdapter()) 1438ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu .indexOf(action); 1439ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu lp.topMargin = mActionsGridView.getLayoutManager() 1440ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu .findViewByPosition(actionPosition).getBottom(); 1441ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu lp.height = 0; 14421ed9dc77616514e20c51baa67a04adab42e4135eDake Gu mSubActionsGridView.setVisibility(View.INVISIBLE); 1443fa4d2cddf2cb9619088153a1fe07d09203d792faDake Gu mSubActionsBackground.setVisibility(View.INVISIBLE); 14441ed9dc77616514e20c51baa67a04adab42e4135eDake Gu mSubActionsGridView.setLayoutParams(lp); 1445ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu adapter.setActions(Collections.EMPTY_LIST); 14461ed9dc77616514e20c51baa67a04adab42e4135eDake Gu mActionsGridView.requestFocus(); 14471ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } 1448be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 1449be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 1450be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu 1451be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu private void updateChevronAndVisibility(ViewHolder vh) { 1452be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu if (!vh.isSubAction()) { 14531ed9dc77616514e20c51baa67a04adab42e4135eDake Gu if (mExpandedAction == null) { 14541ed9dc77616514e20c51baa67a04adab42e4135eDake Gu vh.itemView.setVisibility(View.VISIBLE); 14551ed9dc77616514e20c51baa67a04adab42e4135eDake Gu vh.itemView.setTranslationY(0); 1456b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (vh.mActivatorView != null) { 14570f96ae4965103bade4bebe7776b2ee35cd603112Dake Gu vh.setActivated(false); 1458b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 14591ed9dc77616514e20c51baa67a04adab42e4135eDake Gu } else if (vh.getAction() == mExpandedAction) { 1460be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu vh.itemView.setVisibility(View.VISIBLE); 1461b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu if (vh.getAction().hasSubActions()) { 1462ae746be7c46297b910a99c07697e33e3a5fd7facDake Gu vh.itemView.setTranslationY(getKeyLine() - vh.itemView.getBottom()); 1463b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } else if (vh.mActivatorView != null) { 1464b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu vh.itemView.setTranslationY(0); 14650f96ae4965103bade4bebe7776b2ee35cd603112Dake Gu vh.setActivated(true); 1466b88b36aa081a500eb0e9d4be0bac85b33cd57ddeDake Gu } 1467be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } else { 1468be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu vh.itemView.setVisibility(View.INVISIBLE); 14691ed9dc77616514e20c51baa67a04adab42e4135eDake Gu vh.itemView.setTranslationY(0); 1470be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 1471be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 1472be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu if (vh.mChevronView != null) { 1473be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu onBindChevronView(vh, vh.getAction()); 1474be6eb618b4ba8a74d69fa04c77c717b1fcbea818Dake Gu } 147511cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu } 147611cb62de8bfc6b5b6d22811ad12a1e60451b82beDake Gu 1477ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /* 1478ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * ========================================== 1479ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * FragmentAnimationProvider overrides 1480ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * ========================================== 1481ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 1482ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 1483ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 1484ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * {@inheritDoc} 1485ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 1486ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing @Override 14874158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing public void onImeAppearing(@NonNull List<Animator> animators) { 14884158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing } 14894158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing 14904158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing /** 14914158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing * {@inheritDoc} 14924158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing */ 14934158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing @Override 14944158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing public void onImeDisappearing(@NonNull List<Animator> animators) { 14954158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing } 14964158705d3f0751d419a08c47a659abeae5f6c196Kris Giesing 1497ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /* 1498ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * ========================================== 1499ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * Private methods 1500ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * ========================================== 1501ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 1502ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 1503ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private float getFloat(Context ctx, TypedValue typedValue, int attrId) { 1504ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing ctx.getTheme().resolveAttribute(attrId, typedValue, true); 1505ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing // Android resources don't have a native float type, so we have to use strings. 1506ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return Float.valueOf(ctx.getResources().getString(typedValue.resourceId)); 1507ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 1508ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 1509ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private int getInteger(Context ctx, TypedValue typedValue, int attrId) { 1510ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing ctx.getTheme().resolveAttribute(attrId, typedValue, true); 1511ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return ctx.getResources().getInteger(typedValue.resourceId); 1512ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 1513ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 1514ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private int getDimension(Context ctx, TypedValue typedValue, int attrId) { 1515ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing ctx.getTheme().resolveAttribute(attrId, typedValue, true); 1516ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return ctx.getResources().getDimensionPixelSize(typedValue.resourceId); 1517ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 1518ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 1519ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private boolean setIcon(final ImageView iconView, GuidedAction action) { 1520ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing Drawable icon = null; 1521ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing if (iconView != null) { 1522ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing icon = action.getIcon(); 1523ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing if (icon != null) { 1524162b21598d9f4fd49748b3c7e27501fe1277210dChristopher Lane // setImageDrawable resets the drawable's level unless we set the view level first. 1525162b21598d9f4fd49748b3c7e27501fe1277210dChristopher Lane iconView.setImageLevel(icon.getLevel()); 1526ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing iconView.setImageDrawable(icon); 1527ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing iconView.setVisibility(View.VISIBLE); 1528ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } else { 1529ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing iconView.setVisibility(View.GONE); 1530ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 1531ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 1532ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return icon != null; 1533ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 1534ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 1535ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing /** 1536ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * @return the max height in pixels the description can be such that the 1537ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing * action nicely takes up the entire screen. 1538ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing */ 1539ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing private int getDescriptionMaxHeight(Context context, TextView title) { 1540ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing // The 2 multiplier on the title height calculation is a 1541ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing // conservative estimate for font padding which can not be 1542ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing // calculated at this stage since the view hasn't been rendered yet. 1543ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing return (int)(mDisplayHeight - 2*mVerticalPadding - 2*mTitleMaxLines*title.getLineHeight()); 1544ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing } 1545ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing 1546ebd3d9078dbaebd10a9506ca086435eb63e8a2d2Kris Giesing} 1547