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.GuidedStepFragment; 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 androidx.leanback.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 GuidedStepFragment} used in device name 76 * 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 GuidedStepFragment} WITHOUT background used 91 * 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 @Override 103 public int onProvideItemLayoutId() { 104 return R.layout.device_name_input_item; 105 } 106 }; 107 } 108 109 /** 110 * Create a customized view for {@link androidx.leanback.app.GuidedStepFragment} used 111 * in device name setup. 112 */ 113 public static View createView(View view, GuidedStepFragment guidedStepFragment) { 114 // action_fragment_root's padding cannot be set via attributes so we do it programmatically. 115 final View actionFragmentRoot = view.findViewById(R.id.action_fragment_root); 116 if (actionFragmentRoot != null) { 117 actionFragmentRoot.setPadding(0, 0, 0, 0); 118 } 119 120 final VerticalGridView gridView = guidedStepFragment.getGuidedActionsStylist() 121 .getActionsGridView(); 122 gridView.setItemSpacing( 123 guidedStepFragment.getResources() 124 .getDimensionPixelSize(R.dimen.setup_list_item_margin)); 125 126 // Make the key line match with the item baseline. For our case, the item baseline is 127 // customized to be the mean line of title text view. 128 gridView.setWindowAlignment(BaseGridView.WINDOW_ALIGN_HIGH_EDGE); 129 gridView.setWindowAlignmentPreferKeyLineOverHighEdge(true); 130 return view; 131 } 132 133 /** 134 * Create a customized GuidanceStylist for {@link GuidedStepFragment} used in device name setup. 135 */ 136 public static GuidanceStylist createGuidanceStylist() { 137 return new GuidanceStylist() { 138 @Override 139 public int onProvideLayoutId() { 140 return R.layout.device_name_content; 141 } 142 }; 143 } 144 145 } 146