165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/* 265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Copyright (C) 2014 The Android Open Source Project 365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Licensed under the Apache License, Version 2.0 (the "License"); 565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * you may not use this file except in compliance with the License. 665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * You may obtain a copy of the License at 765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * http://www.apache.org/licenses/LICENSE-2.0 965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 1065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Unless required by applicable law or agreed to in writing, software 1165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * distributed under the License is distributed on an "AS IS" BASIS, 1265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * See the License for the specific language governing permissions and 1465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * limitations under the License. 1565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 1665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepackage com.android.tv.settings.base; 1865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.app.Activity; 2065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.app.Fragment; 2165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.Context; 2265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.Bundle; 2365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.Handler; 2465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.text.InputType; 2565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.text.method.PasswordTransformationMethod; 2665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.KeyEvent; 2765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.LayoutInflater; 2865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.View; 2965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.ViewGroup; 3065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.inputmethod.InputMethodManager; 3165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.widget.EditText; 3265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.widget.TextView; 3365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 3465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.R; 3565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.util.AccessibilityHelper; 3665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 3765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/** 3865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Displays a UI for text input in the "wizard" style. 3965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * TODO: Merge with EditTextFragment 4065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 4165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepublic class TextInputWizardFragment extends Fragment { 4265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 4365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public interface Listener { 4465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 4565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Called when text input is complete. 4665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 4765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param text the text that was input. 4865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @return true if the text is acceptable; false if not. 4965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 5065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean onTextInputComplete(String text); 5165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 5265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String EXTRA_TITLE = "title"; 5465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String EXTRA_IS_PASSWORD = "is_password"; 5565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String EXTRA_PREFILL = "prefill"; 5665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String EXTRA_IS_NUMERIC = "is_numeric"; 5765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static TextInputWizardFragment newInstance(String title, boolean isPassword, 5965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String prefill) { 6065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return newInstance(title, isPassword, prefill, false); 6165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 6265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 6365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static TextInputWizardFragment newInstance(String title, boolean isPassword, 6465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String prefill, boolean isNumeric) { 6565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TextInputWizardFragment fragment = new TextInputWizardFragment(); 6665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Bundle args = new Bundle(); 6765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane args.putString(EXTRA_TITLE, title); 6865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane args.putBoolean(EXTRA_IS_PASSWORD, isPassword); 6965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane args.putString(EXTRA_PREFILL, prefill); 7065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane args.putBoolean(EXTRA_IS_NUMERIC, isNumeric); 7165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane fragment.setArguments(args); 7265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return fragment; 7365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 7465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 7565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private Handler mHandler; 7665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private EditText mTextInput; 7765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 7865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 7965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle icicle) { 8065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mHandler = new Handler(); 8165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane View view = inflater.inflate(R.layout.setup_content_area, container, false); 8265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane View content = inflater.inflate(R.layout.wifi_content, null); 8365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane View action = inflater.inflate(R.layout.wifi_text_input, null); 8465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ((ViewGroup) view.findViewById(R.id.description)).addView(content); 8565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ((ViewGroup) view.findViewById(R.id.action)).addView(action); 8665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 8765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TextView titleText = (TextView) content.findViewById(R.id.title_text); 8865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mTextInput = (EditText) action.findViewById(R.id.text_input); 8965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 9065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Bundle args = getArguments(); 9165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String title = args.getString(EXTRA_TITLE); 9265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean isPassword = args.getBoolean(EXTRA_IS_PASSWORD); 9365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String prefill = args.getString(EXTRA_PREFILL); 9465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean isNumeric = args.getBoolean(EXTRA_IS_NUMERIC); 9565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 9665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (title != null) { 9765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane titleText.setText(title); 9865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane titleText.setVisibility(View.VISIBLE); 9965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (AccessibilityHelper.forceFocusableViews(getActivity())) { 10065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane titleText.setFocusable(true); 10165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane titleText.setFocusableInTouchMode(true); 10265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 10365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 10465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane titleText.setVisibility(View.GONE); 10565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 10665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 10765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (isNumeric) { 10865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mTextInput.setInputType(InputType.TYPE_CLASS_NUMBER); 10965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 11065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 11165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (isPassword) { 11265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mTextInput.setTransformationMethod(new PasswordTransformationMethod()); 11365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 11465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 11565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (prefill != null) { 11665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mTextInput.setText(prefill); 11765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mTextInput.setSelection(mTextInput.getText().length(), mTextInput.getText().length()); 11865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 11965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 12065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mTextInput.setOnEditorActionListener(new TextView.OnEditorActionListener() { 12165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 12265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 12365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (event == null || event.getAction() == KeyEvent.ACTION_UP) { 12465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Activity a = getActivity(); 12565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (a instanceof Listener) { 12665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return ((Listener) a).onTextInputComplete(v.getText().toString()); 12765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 12865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return false; 12965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 13065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return true; // If we don't return true on ACTION_DOWN, we don't get the ACTION_UP. 13165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 13265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane }); 13365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 13465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return view; 13565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 13665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 13765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 13865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onResume() { 13965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane super.onResume(); 14065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mHandler.post(new Runnable() { 14165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 14265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void run() { 14365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane InputMethodManager inputMethodManager = (InputMethodManager) getActivity() 14465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .getSystemService(Context.INPUT_METHOD_SERVICE); 14565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane inputMethodManager.showSoftInput(mTextInput, 0); 14665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mTextInput.requestFocus(); 14765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 14865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane }); 14965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 15065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane} 151