1 /* 2 * Copyright (C) 2017 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.tuner.setup; 18 19 import android.os.Bundle; 20 import android.support.annotation.NonNull; 21 import androidx.leanback.widget.GuidanceStylist.Guidance; 22 import androidx.leanback.widget.GuidedAction; 23 import androidx.leanback.widget.GuidedActionsStylist; 24 import android.text.InputFilter; 25 import android.text.InputFilter.AllCaps; 26 import android.view.View; 27 import android.widget.TextView; 28 import com.android.tv.common.ui.setup.SetupGuidedStepFragment; 29 import com.android.tv.common.ui.setup.SetupMultiPaneFragment; 30 import com.android.tv.common.util.LocationUtils; 31 import com.android.tv.common.util.PostalCodeUtils; 32 import com.android.tv.tuner.R; 33 import java.util.List; 34 35 /** A fragment for users to enter postal code. */ 36 public class PostalCodeFragment extends SetupMultiPaneFragment { 37 public static final String ACTION_CATEGORY = "com.android.tv.tuner.setup.PostalCodeFragment"; 38 public static final String KEY_POSTAL_CODE = "postal_code"; 39 public static final String KEY_GET_LOCATION_FAILED = "get_location_failed"; 40 private static final int VIEW_TYPE_EDITABLE = 1; 41 42 @Override onCreateContentFragment()43 protected SetupGuidedStepFragment onCreateContentFragment() { 44 ContentFragment fragment = new ContentFragment(); 45 Bundle arguments = new Bundle(); 46 arguments.putBoolean(SetupGuidedStepFragment.KEY_THREE_PANE, true); 47 if (getArguments() != null) { 48 arguments.putBoolean( 49 KEY_GET_LOCATION_FAILED, 50 getArguments().getBoolean(KEY_GET_LOCATION_FAILED, false)); 51 } 52 fragment.setArguments(arguments); 53 return fragment; 54 } 55 56 @Override getActionCategory()57 protected String getActionCategory() { 58 return ACTION_CATEGORY; 59 } 60 61 @Override needsDoneButton()62 protected boolean needsDoneButton() { 63 return true; 64 } 65 66 @Override needsSkipButton()67 protected boolean needsSkipButton() { 68 return true; 69 } 70 71 @Override setOnClickAction(View view, final String category, final int actionId)72 protected void setOnClickAction(View view, final String category, final int actionId) { 73 if (actionId == ACTION_DONE) { 74 view.setOnClickListener( 75 new View.OnClickListener() { 76 @Override 77 public void onClick(View view) { 78 CharSequence postalCode = 79 ((ContentFragment) getContentFragment()) 80 .mEditedActionTitleView.getText(); 81 String region = LocationUtils.getCurrentCountry(getContext()); 82 if (postalCode != null && PostalCodeUtils.matches(postalCode, region)) { 83 String postalCodeString = postalCode.toString(); 84 PostalCodeUtils.setLastPostalCode(getContext(), postalCodeString); 85 Bundle params = new Bundle(); 86 params.putString(KEY_POSTAL_CODE, postalCodeString); 87 onActionClick(category, actionId, params); 88 } else { 89 ContentFragment contentFragment = 90 (ContentFragment) getContentFragment(); 91 contentFragment.mEditAction.setDescription( 92 getString(R.string.postal_code_invalid_warning)); 93 contentFragment.notifyActionChanged(0); 94 contentFragment.mEditedActionView.performClick(); 95 } 96 } 97 }); 98 } else if (actionId == ACTION_SKIP) { 99 super.setOnClickAction(view, category, ACTION_SKIP); 100 } 101 } 102 103 /** The content fragment of {@link PostalCodeFragment}. */ 104 public static class ContentFragment extends SetupGuidedStepFragment { 105 private GuidedAction mEditAction; 106 private View mEditedActionView; 107 private TextView mEditedActionTitleView; 108 private View mDoneActionView; 109 private boolean mProceed; 110 111 @Override onGuidedActionFocused(GuidedAction action)112 public void onGuidedActionFocused(GuidedAction action) { 113 if (action.equals(mEditAction)) { 114 if (mProceed) { 115 // "NEXT" in IME was just clicked, moves focus to Done button. 116 if (mDoneActionView == null) { 117 mDoneActionView = getDoneButton(); 118 } 119 mDoneActionView.requestFocus(); 120 mProceed = false; 121 } else { 122 // Directly opens IME to input postal/zip code. 123 if (mEditedActionView == null) { 124 int maxLength = PostalCodeUtils.getRegionMaxLength(getContext()); 125 mEditedActionView = getView().findViewById(R.id.guidedactions_editable); 126 mEditedActionTitleView = 127 mEditedActionView.findViewById(R.id.guidedactions_item_title); 128 mEditedActionTitleView.setFilters( 129 new InputFilter[] { 130 new InputFilter.LengthFilter(maxLength), new AllCaps() 131 }); 132 } 133 mEditedActionView.performClick(); 134 } 135 } 136 } 137 138 @Override onGuidedActionEditedAndProceed(GuidedAction action)139 public long onGuidedActionEditedAndProceed(GuidedAction action) { 140 mProceed = true; 141 return 0; 142 } 143 144 @NonNull 145 @Override onCreateGuidance(Bundle savedInstanceState)146 public Guidance onCreateGuidance(Bundle savedInstanceState) { 147 String title = getString(R.string.postal_code_guidance_title); 148 StringBuilder description = new StringBuilder(); 149 if (getArguments().getBoolean(KEY_GET_LOCATION_FAILED, false)) { 150 description 151 .append(getString(R.string 152 .postal_code_guidance_description_get_location_failed)) 153 .append(" "); 154 } 155 description.append(getString(R.string.postal_code_guidance_description)); 156 String breadcrumb = getString(R.string.ut_setup_breadcrumb); 157 return new Guidance(title, description.toString(), breadcrumb, null); 158 } 159 160 @Override onCreateActions( @onNull List<GuidedAction> actions, Bundle savedInstanceState)161 public void onCreateActions( 162 @NonNull List<GuidedAction> actions, Bundle savedInstanceState) { 163 String description = getString(R.string.postal_code_action_description); 164 mEditAction = 165 new GuidedAction.Builder(getActivity()) 166 .id(0) 167 .editable(true) 168 .description(description) 169 .build(); 170 actions.add(mEditAction); 171 } 172 173 @Override getActionCategory()174 protected String getActionCategory() { 175 return ACTION_CATEGORY; 176 } 177 178 @Override onCreateActionsStylist()179 public GuidedActionsStylist onCreateActionsStylist() { 180 return new GuidedActionsStylist() { 181 @Override 182 public int getItemViewType(GuidedAction action) { 183 if (action.isEditable()) { 184 return VIEW_TYPE_EDITABLE; 185 } 186 return super.getItemViewType(action); 187 } 188 189 @Override 190 public int onProvideItemLayoutId(int viewType) { 191 if (viewType == VIEW_TYPE_EDITABLE) { 192 return R.layout.guided_action_editable; 193 } 194 return super.onProvideItemLayoutId(viewType); 195 } 196 }; 197 } 198 } 199 } 200