Merge "Build a new FooterPreference UI."

This commit is contained in:
TreeHugger Robot
2016-12-15 17:56:27 +00:00
committed by Android (Google) Code Review
16 changed files with 454 additions and 94 deletions

View File

@@ -48,6 +48,7 @@ import com.android.settings.applications.LayoutPreference;
import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.core.instrumentation.Instrumentable;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.widget.FooterPreferenceMixin;
import com.android.settingslib.HelpUtils;
import java.util.UUID;
@@ -70,6 +71,9 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF
private static final String SAVE_HIGHLIGHTED_KEY = "android:preference_highlighted";
protected final FooterPreferenceMixin mFooterPreferenceMixin =
new FooterPreferenceMixin(this, getLifecycle());
private SettingsDialogFragment mDialogFragment;
private String mHelpUri;
@@ -123,7 +127,6 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF
private LayoutPreference mHeader;
private LayoutPreference mFooter;
private View mEmptyView;
private LinearLayoutManager mLayoutManager;
private HighlightablePreferenceGroupAdapter mAdapter;
@@ -277,10 +280,6 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF
return mHeader;
}
public LayoutPreference getFooterView() {
return mFooter;
}
protected void setHeaderView(int resource) {
mHeader = new LayoutPreference(getPrefContext(), resource);
addPreferenceToTop(mHeader);
@@ -298,29 +297,6 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF
}
}
protected void setFooterView(int resource) {
setFooterView(resource != 0 ? new LayoutPreference(getPrefContext(), resource) : null);
}
protected void setFooterView(View v) {
setFooterView(v != null ? new LayoutPreference(getPrefContext(), v) : null);
}
private void setFooterView(LayoutPreference footer) {
if (getPreferenceScreen() != null && mFooter != null) {
getPreferenceScreen().removePreference(mFooter);
}
if (footer != null) {
mFooter = footer;
mFooter.setOrder(ORDER_LAST);
if (getPreferenceScreen() != null) {
getPreferenceScreen().addPreference(mFooter);
}
} else {
mFooter = null;
}
}
@Override
public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
if (preferenceScreen != null && !preferenceScreen.isAttached()) {
@@ -332,9 +308,6 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF
if (mHeader != null) {
preferenceScreen.addPreference(mHeader);
}
if (mFooter != null) {
preferenceScreen.addPreference(mFooter);
}
}
}
@@ -343,7 +316,7 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF
if (getPreferenceScreen() != null) {
boolean show = (getPreferenceScreen().getPreferenceCount()
- (mHeader != null ? 1 : 0)
- (mFooter != null ? 1 : 0)) <= 0;
- (mFooterPreferenceMixin.hasFooter() ? 1 : 0)) <= 0;
mEmptyView.setVisibility(show ? View.VISIBLE : View.GONE);
} else {
mEmptyView.setVisibility(View.VISIBLE);

View File

@@ -35,7 +35,7 @@ public interface ApplicationFeatureProvider {
/**
* Callback that receives the total number of packages installed on the device.
*/
public interface NumberOfInstalledAppsCallback {
interface NumberOfInstalledAppsCallback {
void onNumberOfInstalledAppsResult(int num);
}
}

View File

@@ -50,6 +50,7 @@ import com.android.settings.location.ScanningSettings;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw;
import com.android.settings.widget.FooterPreference;
import com.android.settings.widget.SwitchBar;
import com.android.settingslib.bluetooth.BluetoothCallback;
import com.android.settingslib.bluetooth.BluetoothDeviceFilter;
@@ -97,7 +98,7 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem
// accessed from inner class (not private to avoid thunks)
Preference mMyDevicePreference;
FooterPreference mMyDevicePreference;
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
@@ -120,7 +121,7 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem
final Resources res = context.getResources();
final Locale locale = res.getConfiguration().getLocales().get(0);
final BidiFormatter bidiFormatter = BidiFormatter.getInstance(locale);
mMyDevicePreference.setSummary(res.getString(
mMyDevicePreference.setTitle(res.getString(
R.string.bluetooth_is_visible_message,
bidiFormatter.unicodeWrap(mLocalAdapter.getName())));
}
@@ -171,10 +172,8 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem
mAvailableDevicesCategory.setOrder(2);
getPreferenceScreen().addPreference(mAvailableDevicesCategory);
mMyDevicePreference = new Preference(getPrefContext());
mMyDevicePreference = mFooterPreferenceMixin.createFooterPreference();
mMyDevicePreference.setSelectable(false);
mMyDevicePreference.setOrder(3);
getPreferenceScreen().addPreference(mMyDevicePreference);
setHasOptionsMenu(true);
}
@@ -356,7 +355,7 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem
final Resources res = getResources();
final Locale locale = res.getConfiguration().getLocales().get(0);
final BidiFormatter bidiFormatter = BidiFormatter.getInstance(locale);
mMyDevicePreference.setSummary(res.getString(
mMyDevicePreference.setTitle(res.getString(
R.string.bluetooth_is_visible_message,
bidiFormatter.unicodeWrap(mLocalAdapter.getName())));

View File

@@ -18,6 +18,7 @@ package com.android.settings.core.lifecycle;
import android.annotation.UiThread;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.preference.PreferenceScreen;
import com.android.settings.core.lifecycle.events.OnAttach;
import com.android.settings.core.lifecycle.events.OnCreate;
@@ -27,6 +28,7 @@ import com.android.settings.core.lifecycle.events.OnResume;
import com.android.settings.core.lifecycle.events.OnSaveInstanceState;
import com.android.settings.core.lifecycle.events.OnStart;
import com.android.settings.core.lifecycle.events.OnStop;
import com.android.settings.core.lifecycle.events.SetPreferenceScreen;
import com.android.settings.utils.ThreadUtils;
import java.util.ArrayList;
@@ -73,6 +75,14 @@ public class Lifecycle {
}
}
public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
for (LifecycleObserver observer : mObservers) {
if (observer instanceof SetPreferenceScreen) {
((SetPreferenceScreen) observer).setPreferenceScreen(preferenceScreen);
}
}
}
public void onResume() {
for (LifecycleObserver observer : mObservers) {
if (observer instanceof OnResume) {

View File

@@ -20,6 +20,7 @@ import android.annotation.CallSuper;
import android.content.Context;
import android.os.Bundle;
import android.support.v14.preference.PreferenceFragment;
import android.support.v7.preference.PreferenceScreen;
/**
* {@link PreferenceFragment} that has hooks to observe fragment lifecycle events.
@@ -46,6 +47,12 @@ public abstract class ObservablePreferenceFragment extends PreferenceFragment {
super.onCreate(savedInstanceState);
}
@Override
public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
mLifecycle.setPreferenceScreen(preferenceScreen);
super.setPreferenceScreen(preferenceScreen);
}
@CallSuper
@Override
public void onSaveInstanceState(Bundle outState) {

View File

@@ -0,0 +1,24 @@
/*
* Copyright (C) 2016 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.settings.core.lifecycle.events;
import android.support.v7.preference.PreferenceScreen;
public interface SetPreferenceScreen {
void setPreferenceScreen(PreferenceScreen preferenceScreen);
}

View File

@@ -17,7 +17,6 @@
package com.android.settings.fingerprint;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
@@ -26,7 +25,6 @@ import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.hardware.fingerprint.Fingerprint;
@@ -49,15 +47,12 @@ import android.text.Annotation;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.TextPaint;
import android.text.method.LinkMovementMethod;
import android.text.style.URLSpan;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -68,6 +63,8 @@ import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.SubSettings;
import com.android.settings.Utils;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.widget.FooterPreference;
import com.android.settings.widget.FooterPreferenceMixin;
import com.android.settingslib.HelpUtils;
import com.android.settingslib.RestrictedLockUtils;
@@ -298,21 +295,14 @@ public class FingerprintSettings extends SubSettings {
mLaunchedConfirm = true;
launchChooseOrConfirmLock();
}
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
TextView v = (TextView) LayoutInflater.from(view.getContext()).inflate(
R.layout.fingerprint_settings_footer, null);
EnforcedAdmin admin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(
getActivity(), DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT, mUserId);
v.setText(LearnMoreSpan.linkify(getText(admin != null
final FooterPreference pref = mFooterPreferenceMixin.createFooterPreference();
final EnforcedAdmin admin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(
activity, DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT, mUserId);
pref.setTitle(LearnMoreSpan.linkify(getText(admin != null
? R.string.security_settings_fingerprint_enroll_disclaimer_lockscreen_disabled
: R.string.security_settings_fingerprint_enroll_disclaimer),
getString(getHelpResource()), admin));
v.setMovementMethod(new LinkMovementMethod());
setFooterView(v);
}
protected void removeFingerprintPreference(int fingerprintId) {

View File

@@ -0,0 +1,71 @@
/*
* Copyright (C) 2016 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.settings.widget;
import android.content.Context;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceViewHolder;
import android.text.method.LinkMovementMethod;
import android.util.AttributeSet;
import android.widget.TextView;
import com.android.settings.R;
/**
* A custom preference acting as "footer" of a page. It has a field for icon and text. It is added
* to screen as the last preference.
*/
public class FooterPreference extends Preference {
static final int ORDER_FOOTER = Integer.MAX_VALUE - 1;
static final String KEY_FOOTER = "footer_preference";
public FooterPreference(Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
public FooterPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public FooterPreference(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public FooterPreference(Context context) {
super(context);
init();
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
TextView title = (TextView) holder.itemView.findViewById(android.R.id.title);
title.setMovementMethod(new LinkMovementMethod());
}
private void init() {
setLayoutResource(R.layout.preference_footer);
setIcon(R.drawable.ic_info_outline_24dp);
setKey(KEY_FOOTER);
setOrder(ORDER_FOOTER);
}
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright (C) 2016 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.settings.widget;
import android.content.Context;
import android.support.v14.preference.PreferenceFragment;
import android.support.v7.preference.PreferenceScreen;
import com.android.settings.core.lifecycle.Lifecycle;
import com.android.settings.core.lifecycle.LifecycleObserver;
import com.android.settings.core.lifecycle.events.SetPreferenceScreen;
public class FooterPreferenceMixin implements LifecycleObserver, SetPreferenceScreen {
private final PreferenceFragment mFragment;
private FooterPreference mFooterPreference;
public FooterPreferenceMixin(PreferenceFragment fragment, Lifecycle lifecycle) {
mFragment = fragment;
lifecycle.addObserver(this);
}
@Override
public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
if (mFooterPreference != null) {
preferenceScreen.addPreference(mFooterPreference);
}
}
/**
* Creates a new {@link FooterPreference}.
*/
public FooterPreference createFooterPreference() {
final PreferenceScreen screen = mFragment.getPreferenceScreen();
if (mFooterPreference != null && screen != null) {
screen.removePreference(mFooterPreference);
}
mFooterPreference = new FooterPreference(getPrefContext());
if (screen != null) {
screen.addPreference(mFooterPreference);
}
return mFooterPreference;
}
/**
* Returns an UI context with theme properly set for new Preference objects.
*/
private Context getPrefContext() {
return mFragment.getPreferenceManager().getContext();
}
public boolean hasFooter() {
return mFooterPreference != null;
}
}