From ec9a6feb3110fde5805f999a9666a18be82089c1 Mon Sep 17 00:00:00 2001 From: Yorke Lee Date: Fri, 28 Mar 2014 17:43:03 -0700 Subject: Refactor dialpad into its own view Initial work needed to make the dialpad shareable within Dialer and InCallUI. This CL refactors the code that controls the appearance of the dialpad into a new custom view called DialpadView. The parent activity/fragment is still responsible for assigning listeners and handling event callbacks from the DialpadView. Change-Id: I11ab8159619413caf1c3d8fa16fff475b822633b --- res/layout/dialpad_fragment.xml | 41 +----- res/layout/dialpad_view.xml | 89 +++++++++++++ .../android/dialer/dialpad/DialpadFragment.java | 102 +++------------ src/com/android/dialer/dialpad/DialpadView.java | 145 +++++++++++++++++++++ 4 files changed, 253 insertions(+), 124 deletions(-) create mode 100644 res/layout/dialpad_view.xml create mode 100644 src/com/android/dialer/dialpad/DialpadView.java diff --git a/res/layout/dialpad_fragment.xml b/res/layout/dialpad_fragment.xml index 9d3c62043..33324d1e0 100644 --- a/res/layout/dialpad_fragment.xml +++ b/res/layout/dialpad_fragment.xml @@ -30,47 +30,14 @@ android:layout_width="match_parent" android:layout_height="3dp" android:background="@drawable/shadow_fade_up" /> - - - - - - - - - - - - - - - - - - diff --git a/res/layout/dialpad_view.xml b/res/layout/dialpad_view.xml new file mode 100644 index 000000000..148e5ac4c --- /dev/null +++ b/res/layout/dialpad_view.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/com/android/dialer/dialpad/DialpadFragment.java b/src/com/android/dialer/dialpad/DialpadFragment.java index 0ca26e99b..ce2db3c67 100644 --- a/src/com/android/dialer/dialpad/DialpadFragment.java +++ b/src/com/android/dialer/dialpad/DialpadFragment.java @@ -142,30 +142,6 @@ public class DialpadFragment extends Fragment } } - /** - * LinearLayout that always returns true for onHoverEvent callbacks, to fix - * problems with accessibility due to the dialpad overlaying other fragments. - */ - public static class HoverIgnoringLinearLayout extends LinearLayout { - - public HoverIgnoringLinearLayout(Context context) { - super(context); - } - - public HoverIgnoringLinearLayout(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public HoverIgnoringLinearLayout(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } - - @Override - public boolean onHoverEvent(MotionEvent event) { - return true; - } - } - public interface OnDialpadQueryChangedListener { void onDialpadQueryChanged(String query); } @@ -191,11 +167,7 @@ public class DialpadFragment extends Fragment private OnDialpadQueryChangedListener mDialpadQueryListener; - /** - * View (usually FrameLayout) containing mDigits field. This can be null, in which mDigits - * isn't enclosed by the container. - */ - private View mDigitsContainer; + private DialpadView mDialpadView; private EditText mDigits; /** Remembers if we need to clear digits field when the screen is completely gone. */ @@ -206,7 +178,6 @@ public class DialpadFragment extends Fragment private View mDelete; private ToneGenerator mToneGenerator; private final Object mToneGeneratorLock = new Object(); - private View mDialpad; private View mSpacer; /** @@ -398,8 +369,10 @@ public class DialpadFragment extends Fragment vto.addOnPreDrawListener(preDrawListener); - mDigitsContainer = fragmentView.findViewById(R.id.digits_container); - mDigits = (EditText) fragmentView.findViewById(R.id.digits); + Resources r = getResources(); + + mDialpadView = (DialpadView) fragmentView.findViewById(R.id.dialpad_view); + mDigits = mDialpadView.getDigits(); mDigits.setKeyListener(UnicodeDialerKeyListener.INSTANCE); mDigits.setOnClickListener(this); mDigits.setOnKeyListener(this); @@ -410,10 +383,11 @@ public class DialpadFragment extends Fragment // Check for the presence of the keypad View oneButton = fragmentView.findViewById(R.id.one); if (oneButton != null) { - setupKeypad(fragmentView); + configureKeypadListeners(fragmentView); } - mDelete = fragmentView.findViewById(R.id.deleteButton); + mDelete = mDialpadView.getDeleteButton(); + if (mDelete != null) { mDelete.setOnClickListener(this); mDelete.setOnLongClickListener(this); @@ -431,14 +405,7 @@ public class DialpadFragment extends Fragment } }); - mDialpad = fragmentView.findViewById(R.id.dialpad); // This is null in landscape mode. - - // In landscape we put the keyboard in phone mode. - if (null == mDialpad) { - mDigits.setInputType(android.text.InputType.TYPE_CLASS_PHONE); - } else { - mDigits.setCursorVisible(false); - } + mDigits.setCursorVisible(false); // Set up the "dialpad chooser" UI; see showDialpadChooser(). mDialpadChooser = (ListView) fragmentView.findViewById(R.id.dialpadChooser); @@ -596,53 +563,23 @@ public class DialpadFragment extends Fragment } } - private void setupKeypad(View fragmentView) { + private void configureKeypadListeners(View fragmentView) { final int[] buttonIds = new int[] {R.id.zero, R.id.one, R.id.two, R.id.three, R.id.four, R.id.five, R.id.six, R.id.seven, R.id.eight, R.id.nine, R.id.star, R.id.pound}; - - final int[] numberIds = new int[] {R.string.dialpad_0_number, R.string.dialpad_1_number, - R.string.dialpad_2_number, R.string.dialpad_3_number, R.string.dialpad_4_number, - R.string.dialpad_5_number, R.string.dialpad_6_number, R.string.dialpad_7_number, - R.string.dialpad_8_number, R.string.dialpad_9_number, R.string.dialpad_star_number, - R.string.dialpad_pound_number}; - - final int[] letterIds = new int[] {R.string.dialpad_0_letters, R.string.dialpad_1_letters, - R.string.dialpad_2_letters, R.string.dialpad_3_letters, R.string.dialpad_4_letters, - R.string.dialpad_5_letters, R.string.dialpad_6_letters, R.string.dialpad_7_letters, - R.string.dialpad_8_letters, R.string.dialpad_9_letters, - R.string.dialpad_star_letters, R.string.dialpad_pound_letters}; - - final Resources resources = getResources(); - DialpadKeyButton dialpadKey; - TextView numberView; - TextView lettersView; for (int i = 0; i < buttonIds.length; i++) { dialpadKey = (DialpadKeyButton) fragmentView.findViewById(buttonIds[i]); dialpadKey.setOnPressedListener(this); - numberView = (TextView) dialpadKey.findViewById(R.id.dialpad_key_number); - lettersView = (TextView) dialpadKey.findViewById(R.id.dialpad_key_letters); - final String numberString = resources.getString(numberIds[i]); - numberView.setText(numberString); - numberView.setElegantTextHeight(false); - dialpadKey.setContentDescription(numberString); - if (lettersView != null) { - lettersView.setText(resources.getString(letterIds[i])); - } } // Long-pressing one button will initiate Voicemail. final DialpadKeyButton one = (DialpadKeyButton) fragmentView.findViewById(R.id.one); one.setOnLongClickListener(this); - one.setLongHoverContentDescription( - resources.getText(R.string.description_voicemail_button)); // Long-pressing zero button will enter '+' instead. final DialpadKeyButton zero = (DialpadKeyButton) fragmentView.findViewById(R.id.zero); zero.setOnLongClickListener(this); - zero.setLongHoverContentDescription( - resources.getText(R.string.description_image_button_plus)); mAddContactButton = fragmentView.findViewById(R.id.dialpad_add_contact); mAddContactButton.setOnClickListener(this); @@ -984,10 +921,6 @@ public class DialpadFragment extends Fragment switch (id) { case R.id.deleteButton: { digits.clear(); - // TODO: The framework forgets to clear the pressed - // status of disabled button. Until this is fixed, - // clear manually the pressed status. b/2133127 - mDelete.setPressed(false); return true; } case R.id.one: { @@ -1149,7 +1082,7 @@ public class DialpadFragment extends Fragment } // Clear the digits just in case. - mDigits.getText().clear(); + clearDialpad(); } else { final Intent intent = CallUtil.getCallIntent(number, (getActivity() instanceof DialtactsActivity ? @@ -1287,13 +1220,9 @@ public class DialpadFragment extends Fragment if (enabled) { // Log.i(TAG, "Showing dialpad chooser!"); - if (mDigitsContainer != null) { - mDigitsContainer.setVisibility(View.GONE); - } else { - // mDigits is not enclosed by the container. Make the digits field itself gone. - mDigits.setVisibility(View.GONE); + if (mDialpadView != null) { + mDialpadView.setVisibility(View.GONE); } - if (mDialpad != null) mDialpad.setVisibility(View.GONE); ((HostInterface) getActivity()).setDialButtonContainerVisible(false); mDialpadChooser.setVisibility(View.VISIBLE); @@ -1306,12 +1235,11 @@ public class DialpadFragment extends Fragment mDialpadChooser.setAdapter(mDialpadChooserAdapter); } else { // Log.i(TAG, "Displaying normal Dialer UI."); - if (mDigitsContainer != null) { - mDigitsContainer.setVisibility(View.VISIBLE); + if (mDialpadView != null) { + mDialpadView.setVisibility(View.VISIBLE); } else { mDigits.setVisibility(View.VISIBLE); } - if (mDialpad != null) mDialpad.setVisibility(View.VISIBLE); ((HostInterface) getActivity()).setDialButtonContainerVisible(true); mDialpadChooser.setVisibility(View.GONE); } diff --git a/src/com/android/dialer/dialpad/DialpadView.java b/src/com/android/dialer/dialpad/DialpadView.java new file mode 100644 index 000000000..d81be4d2a --- /dev/null +++ b/src/com/android/dialer/dialpad/DialpadView.java @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.dialer.dialpad; + +import android.content.Context; +import android.content.res.Resources; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.LinearLayout; +import android.widget.TableRow; +import android.widget.TextView; + +import com.android.dialer.R; + +/** + * View that displays a twelve-key phone dialpad. + */ +public class DialpadView extends LinearLayout { + private static final String TAG = DialpadView.class.getSimpleName(); + + private EditText mDigits; + private ImageButton mDelete; + + public DialpadView(Context context) { + this(context, null); + } + + public DialpadView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public DialpadView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + @Override + protected void onFinishInflate() { + setupKeypad(); + mDigits = (EditText) findViewById(R.id.digits); + mDelete = (ImageButton) findViewById(R.id.deleteButton); + } + + private void setupKeypad() { + final int[] buttonIds = new int[] {R.id.zero, R.id.one, R.id.two, R.id.three, R.id.four, + R.id.five, R.id.six, R.id.seven, R.id.eight, R.id.nine, R.id.star, R.id.pound}; + + final int[] numberIds = new int[] {R.string.dialpad_0_number, R.string.dialpad_1_number, + R.string.dialpad_2_number, R.string.dialpad_3_number, R.string.dialpad_4_number, + R.string.dialpad_5_number, R.string.dialpad_6_number, R.string.dialpad_7_number, + R.string.dialpad_8_number, R.string.dialpad_9_number, R.string.dialpad_star_number, + R.string.dialpad_pound_number}; + + final int[] letterIds = new int[] {R.string.dialpad_0_letters, R.string.dialpad_1_letters, + R.string.dialpad_2_letters, R.string.dialpad_3_letters, R.string.dialpad_4_letters, + R.string.dialpad_5_letters, R.string.dialpad_6_letters, R.string.dialpad_7_letters, + R.string.dialpad_8_letters, R.string.dialpad_9_letters, + R.string.dialpad_star_letters, R.string.dialpad_pound_letters}; + + final Resources resources = getContext().getResources(); + + DialpadKeyButton dialpadKey; + TextView numberView; + TextView lettersView; + + for (int i = 0; i < buttonIds.length; i++) { + dialpadKey = (DialpadKeyButton) findViewById(buttonIds[i]); + numberView = (TextView) dialpadKey.findViewById(R.id.dialpad_key_number); + lettersView = (TextView) dialpadKey.findViewById(R.id.dialpad_key_letters); + final String numberString = resources.getString(numberIds[i]); + numberView.setText(numberString); + numberView.setElegantTextHeight(false); + dialpadKey.setContentDescription(numberString); + if (lettersView != null) { + lettersView.setText(resources.getString(letterIds[i])); + } + } + + final DialpadKeyButton one = (DialpadKeyButton) findViewById(R.id.one); + one.setLongHoverContentDescription( + resources.getText(R.string.description_voicemail_button)); + + final DialpadKeyButton zero = (DialpadKeyButton) findViewById(R.id.zero); + zero.setLongHoverContentDescription( + resources.getText(R.string.description_image_button_plus)); + + } + + public void setShowVoicemailButton(boolean show) { + View view = findViewById(R.id.dialpad_key_voicemail); + if (view != null) { + view.setVisibility(show ? View.VISIBLE : View.INVISIBLE); + } + } + + /** + * Whether or not the digits above the dialer can be edited. + * + * @param canBeEdited If true, the backspace button will be shown and the digits EditText + * will be configured to allow text manipulation. + */ + public void setDigitsCanBeEdited(boolean canBeEdited) { + View deleteButton = findViewById(R.id.deleteButton); + deleteButton.setVisibility(canBeEdited ? View.VISIBLE : View.GONE); + + EditText digits = (EditText) findViewById(R.id.digits); + digits.setClickable(canBeEdited); + digits.setLongClickable(canBeEdited); + digits.setFocusableInTouchMode(canBeEdited); + digits.setCursorVisible(false); + } + + /** + * Always returns true for onHoverEvent callbacks, to fix problems with accessibility due to + * the dialpad overlaying other fragments. + */ + @Override + public boolean onHoverEvent(MotionEvent event) { + return true; + } + + public EditText getDigits() { + return mDigits; + } + + public ImageButton getDeleteButton() { + return mDelete; + } +} -- cgit v1.2.3