| // Copyright 2010-2015, Google Inc. |
| // All rights reserved. |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are |
| // met: |
| // |
| // * Redistributions of source code must retain the above copyright |
| // notice, this list of conditions and the following disclaimer. |
| // * Redistributions in binary form must reproduce the above |
| // copyright notice, this list of conditions and the following disclaimer |
| // in the documentation and/or other materials provided with the |
| // distribution. |
| // * Neither the name of Google Inc. nor the names of its |
| // contributors may be used to endorse or promote products derived from |
| // this software without specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| package org.mozc.android.inputmethod.japanese.preference; |
| |
| import org.mozc.android.inputmethod.japanese.resources.R; |
| |
| import android.content.Context; |
| import android.content.res.TypedArray; |
| import android.preference.Preference; |
| import android.util.AttributeSet; |
| import android.view.LayoutInflater; |
| import android.view.View; |
| import android.view.ViewGroup; |
| import android.view.ViewGroup.LayoutParams; |
| import android.view.ViewGroup.MarginLayoutParams; |
| import android.view.ViewParent; |
| import android.widget.SeekBar; |
| import android.widget.SeekBar.OnSeekBarChangeListener; |
| import android.widget.TextView; |
| |
| /** |
| * Preference to configure the flick sensitivity. |
| * |
| * This preference has a seekbar and its indicators to manipulate flick sensitivity, |
| * in addition to other regular preferences. |
| * |
| */ |
| public class SeekbarPreference extends Preference { |
| private class SeekBarChangeListener implements OnSeekBarChangeListener { |
| private final TextView sensitivityTextView; |
| SeekBarChangeListener(TextView textView) { |
| this.sensitivityTextView = textView; |
| } |
| |
| @Override |
| public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { |
| if (sensitivityTextView != null) { |
| sensitivityTextView.setText(String.valueOf(progress + offset)); |
| } |
| } |
| |
| @Override |
| public void onStartTrackingTouch(SeekBar seekBar) { |
| } |
| |
| @Override |
| public void onStopTrackingTouch(SeekBar seekBar) { |
| setValue(seekBar.getProgress() + offset); |
| } |
| } |
| |
| private int max; |
| private int offset; |
| private int value; |
| private String unit; |
| private String lowText; |
| private String middleText; |
| private String highText; |
| |
| public SeekbarPreference(Context context) { |
| super(context); |
| } |
| |
| public SeekbarPreference(Context context, AttributeSet attrs) { |
| super(context, attrs); |
| init(context, attrs); |
| } |
| |
| public SeekbarPreference(Context context, AttributeSet attrs, int defStyle) { |
| super(context, attrs, defStyle); |
| init(context, attrs); |
| } |
| |
| private void init(Context context, AttributeSet attrs) { |
| int[] attributeArray = { |
| android.R.attr.max, |
| android.R.attr.progress, |
| R.attr.seekbar_offset, |
| R.attr.seekbar_unit, |
| R.attr.seekbar_low_text, |
| R.attr.seekbar_middle_text, |
| R.attr.seekbar_high_text, |
| }; |
| TypedArray typedArray = context.obtainStyledAttributes(attrs, attributeArray); |
| try { |
| offset = typedArray.getInt(2, 0); |
| max = typedArray.getInt(0, 0); |
| value = typedArray.getInt(1, 0) + offset; |
| unit = typedArray.getString(3); |
| lowText = typedArray.getString(4); |
| middleText = typedArray.getString(5); |
| highText = typedArray.getString(6); |
| } finally { |
| typedArray.recycle(); |
| } |
| } |
| |
| @Override |
| protected View onCreateView(ViewGroup parent) { |
| LayoutInflater inflater = LayoutInflater.from(getContext()); |
| View view = inflater.inflate(R.layout.pref_seekbar, parent, false); |
| ViewGroup preferenceFrame = ViewGroup.class.cast(view.findViewById(R.id.preference_frame)); |
| // Note: Invoking getLayoutResource() is a hack to obtain the default resource id. |
| inflater.inflate(getLayoutResource(), preferenceFrame); |
| initializeOriginalView(view); |
| return view; |
| } |
| |
| /** |
| * Initializes the original preferecen's parameters. |
| */ |
| private void initializeOriginalView(View view) { |
| View summaryView = view.findViewById(android.R.id.summary); |
| if (summaryView == null) { |
| // We can do nothing. |
| return; |
| } |
| shrinkBottomMarginAndPadding(summaryView); |
| |
| ViewParent parent = summaryView.getParent(); |
| if (!(parent instanceof View)) { |
| return; |
| } |
| View parentView = View.class.cast(parent); |
| shrinkBottomMarginAndPadding(parentView); |
| |
| ViewParent rootViewParent = parentView.getParent(); |
| if (!(rootViewParent instanceof View)) { |
| return; |
| } |
| |
| View rootView = View.class.cast(rootViewParent); |
| rootView.setMinimumHeight(0); |
| |
| View widgetFrame = view.findViewById(android.R.id.widget_frame); |
| if (widgetFrame != null) { |
| widgetFrame.setVisibility(View.GONE); |
| } |
| } |
| |
| private void shrinkBottomMarginAndPadding(View view) { |
| LayoutParams params = view.getLayoutParams(); |
| if (params instanceof MarginLayoutParams) { |
| MarginLayoutParams.class.cast(params).bottomMargin = 0; |
| view.setLayoutParams(params); |
| } |
| view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), view.getPaddingRight(), 0); |
| } |
| |
| @Override |
| protected Object onGetDefaultValue(TypedArray a, int index) { |
| return a.getInt(index, 0); |
| } |
| |
| @Override |
| protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { |
| setValue(restoreValue ? getPersistedInt(value) : Integer.class.cast(defaultValue)); |
| } |
| |
| @Override |
| protected void onBindView(View view) { |
| super.onBindView(view); |
| |
| TextView valueView = |
| TextView.class.cast(view.findViewById(R.id.pref_seekbar_value)); |
| SeekBar seekBar = SeekBar.class.cast(view.findViewById(R.id.pref_seekbar_seekbar)); |
| if (seekBar != null) { |
| seekBar.setMax(max - offset); |
| seekBar.setProgress(value - offset); |
| seekBar.setOnSeekBarChangeListener(new SeekBarChangeListener(valueView)); |
| } |
| if (valueView != null) { |
| valueView.setText(String.valueOf(value)); |
| } |
| TextView unitView = TextView.class.cast(view.findViewById(R.id.pref_seekbar_unit)); |
| if (unitView != null) { |
| if (unit == null) { |
| unitView.setVisibility(View.GONE); |
| } else { |
| unitView.setVisibility(View.VISIBLE); |
| unitView.setText(unit); |
| } |
| } |
| |
| setTextView(lowText, view, R.id.pref_seekbar_low_text); |
| setTextView(middleText, view, R.id.pref_seekbar_middle_text); |
| setTextView(highText, view, R.id.pref_seekbar_high_text); |
| } |
| |
| private static void setTextView(String text, View parentView, int resourceId) { |
| if (text == null) { |
| return; |
| } |
| |
| TextView textView = TextView.class.cast(parentView.findViewById(resourceId)); |
| if (textView == null) { |
| return; |
| } |
| |
| textView.setText(text); |
| } |
| |
| void setValue(int value) { |
| this.value = value; |
| persistInt(value); |
| notifyDependencyChange(shouldDisableDependents()); |
| notifyChanged(); |
| } |
| } |