1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.tv.settings.util; 18 19 import android.view.LayoutInflater; 20 import android.view.View; 21 import android.view.ViewGroup; 22 23 import androidx.leanback.app.GuidedStepSupportFragment; 24 import androidx.leanback.widget.BaseGridView; 25 import androidx.leanback.widget.FacetProvider; 26 import androidx.leanback.widget.GuidanceStylist; 27 import androidx.leanback.widget.GuidedActionsStylist; 28 import androidx.leanback.widget.ItemAlignmentFacet; 29 import androidx.leanback.widget.ItemAlignmentFacet.ItemAlignmentDef; 30 import androidx.leanback.widget.VerticalGridView; 31 32 import com.android.tv.settings.R; 33 34 35 /** 36 * Utilities to align the ActionGridView so that the baseline of the title view matches with 37 * the keyline of the fragment. 38 */ 39 public class GuidedActionsAlignUtil { 40 41 /** 42 * As we want to align to the mean line of the text view, we should always provide a customized 43 * viewholder with the new facet when we are creating a GuidedActionStylist. 44 */ 45 private static class SetupViewHolder extends GuidedActionsStylist.ViewHolder implements 46 FacetProvider { SetupViewHolder(View v)47 SetupViewHolder(View v) { 48 super(v); 49 } 50 51 // Provide a customized ItemAlignmentFacet so that the mean line of textView is matched. 52 // Here we use mean line of the textview to work as the baseline to be matched with 53 // guidance title baseline. 54 @Override getFacet(Class facet)55 public Object getFacet(Class facet) { 56 if (facet.equals(ItemAlignmentFacet.class)) { 57 ItemAlignmentFacet.ItemAlignmentDef alignedDef = 58 new ItemAlignmentFacet.ItemAlignmentDef(); 59 alignedDef.setItemAlignmentViewId( 60 R.id.guidedactions_item_title); 61 alignedDef.setAlignedToTextViewBaseline(false); 62 alignedDef.setItemAlignmentOffset(0); 63 alignedDef.setItemAlignmentOffsetWithPadding(true); 64 // 50 refers to 50 percent, which refers to mid position of textView. 65 alignedDef.setItemAlignmentOffsetPercent(50); 66 ItemAlignmentFacet f = new ItemAlignmentFacet(); 67 f.setAlignmentDefs(new ItemAlignmentDef[]{alignedDef}); 68 return f; 69 } 70 return null; 71 } 72 } 73 74 /** 75 * Create a customized GuidedActionsStylist for {@link GuidedStepSupportFragment} used in device 76 * name setup. 77 */ createGuidedActionsStylist()78 public static GuidedActionsStylist createGuidedActionsStylist() { 79 return new GuidedActionsStylist() { 80 @Override 81 public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 82 LayoutInflater inflater = LayoutInflater.from(parent.getContext()); 83 View v = inflater.inflate(onProvideItemLayoutId(viewType), parent, false); 84 return new GuidedActionsAlignUtil.SetupViewHolder(v); 85 } 86 }; 87 } 88 89 /** 90 * Create a customized GuidedActionsStylist {@link GuidedStepSupportFragment} WITHOUT background 91 * used in device name customization input step. 92 */ 93 public static GuidedActionsStylist createNoBackgroundGuidedActionsStylist() { 94 return new GuidedActionsStylist() { 95 @Override 96 public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 97 LayoutInflater inflater = LayoutInflater.from(parent.getContext()); 98 View v = inflater.inflate(onProvideItemLayoutId(viewType), parent, false); 99 v.setBackground(null); 100 return new GuidedActionsAlignUtil.SetupViewHolder(v); 101 } 102 103 @Override 104 public int onProvideItemLayoutId() { 105 return R.layout.device_name_input_item; 106 } 107 }; 108 } 109 110 /** 111 * Create a customized view for {@link GuidedStepSupportFragment} used 112 * in device name setup. 113 */ 114 public static View createView(View view, GuidedStepSupportFragment guidedStepFragment) { 115 // action_fragment_root's padding cannot be set via attributes so we do it programmatically. 116 final View actionFragmentRoot = view.findViewById(R.id.action_fragment_root); 117 if (actionFragmentRoot != null) { 118 actionFragmentRoot.setPadding(0, 0, 0, 0); 119 } 120 121 final VerticalGridView gridView = guidedStepFragment.getGuidedActionsStylist() 122 .getActionsGridView(); 123 gridView.setItemSpacing( 124 guidedStepFragment.getResources() 125 .getDimensionPixelSize(R.dimen.setup_list_item_margin)); 126 127 // Make the key line match with the item baseline. For our case, the item baseline is 128 // customized to be the mean line of title text view. 129 gridView.setWindowAlignment(BaseGridView.WINDOW_ALIGN_HIGH_EDGE); 130 gridView.setWindowAlignmentPreferKeyLineOverHighEdge(true); 131 return view; 132 } 133 134 /** 135 * Create a customized GuidanceStylist for {@link GuidedStepSupportFragment} used in device name 136 * setup. 137 */ 138 public static GuidanceStylist createGuidanceStylist() { 139 return new GuidanceStylist() { 140 @Override 141 public int onProvideLayoutId() { 142 return R.layout.device_name_content; 143 } 144 }; 145 } 146 147 } 148