// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. package org.chromium.chrome.browser.preferences; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; import android.preference.SwitchPreference; import android.support.v7.widget.SwitchCompat; import android.text.TextUtils; import android.util.AttributeSet; import android.view.View; import android.widget.TextView; import org.chromium.chrome.R; /** * A super-powered SwitchPreference designed especially for Chrome. Special features: * - Supports managed preferences * - Displays a material-styled switch, even on pre-L devices */ public class ChromeSwitchPreference extends SwitchPreference { private ManagedPreferenceDelegate mManagedPrefDelegate; private boolean mDontUseSummaryAsTitle; private boolean mDrawDivider; /** * Constructor for inflating from XML. */ public ChromeSwitchPreference(Context context, AttributeSet attrs) { super(context, attrs); setWidgetLayoutResource(R.layout.preference_switch); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ChromeSwitchPreference); mDontUseSummaryAsTitle = a.getBoolean(R.styleable.ChromeSwitchPreference_dontUseSummaryAsTitle, false); mDrawDivider = a.getBoolean(R.styleable.ChromeSwitchPreference_drawDivider, false); a.recycle(); } /** * Sets the ManagedPreferenceDelegate which will determine whether this preference is managed. */ public void setManagedPreferenceDelegate(ManagedPreferenceDelegate delegate) { mManagedPrefDelegate = delegate; if (mManagedPrefDelegate != null) mManagedPrefDelegate.initPreference(this); } /** * Sets whether a horizontal divider line should be drawn at the bottom of this preference. */ public void setDrawDivider(boolean drawDivider) { if (mDrawDivider != drawDivider) { mDrawDivider = drawDivider; notifyChanged(); } } @Override protected void onBindView(View view) { super.onBindView(view); if (mDrawDivider) { int left = view.getPaddingLeft(); int right = view.getPaddingRight(); int top = view.getPaddingTop(); int bottom = view.getPaddingBottom(); view.setBackground(DividerDrawable.create(getContext())); view.setPadding(left, top, right, bottom); } SwitchCompat switchView = (SwitchCompat) view.findViewById(R.id.switch_widget); // On BLU Life Play devices SwitchPreference.setWidgetLayoutResource() does nothing. As a // result, the user will see a non-material Switch and switchView will be null, hence the // null check below. http://crbug.com/451447 if (switchView != null) { switchView.setChecked(isChecked()); } TextView title = (TextView) view.findViewById(android.R.id.title); title.setSingleLine(false); if (!mDontUseSummaryAsTitle && TextUtils.isEmpty(getTitle())) { TextView summary = (TextView) view.findViewById(android.R.id.summary); title.setText(summary.getText()); title.setVisibility(View.VISIBLE); summary.setVisibility(View.GONE); } if (mManagedPrefDelegate != null) mManagedPrefDelegate.onBindViewToPreference(this, view); } @Override protected void onClick() { if (mManagedPrefDelegate != null && mManagedPrefDelegate.onClickPreference(this)) return; super.onClick(); } /** * Draws a horizontal list divider line at the bottom of its drawing area. * * Because ?android:attr/listDivider may be a 9-patch, there's no way to achieve this drawing * effect with the platform Drawable classes; hence this custom Drawable. */ private static class DividerDrawable extends LayerDrawable { static DividerDrawable create(Context context) { TypedArray a = context.obtainStyledAttributes(new int[] { android.R.attr.listDivider }); Drawable listDivider = a.getDrawable(0); a.recycle(); return new DividerDrawable(new Drawable[] { listDivider }); } private DividerDrawable(Drawable[] layers) { super(layers); } @Override protected void onBoundsChange(Rect bounds) { int listDividerHeight = getDrawable(0).getIntrinsicHeight(); setLayerInset(0, 0, bounds.height() - listDividerHeight, 0, 0); super.onBoundsChange(bounds); } } }