Allow appending static preferences to RadioButtonPickerFragment

This makes it so that static preferences can also be added after
the candidates so they can show up on the bottom of the screen.
This is done via a new xml tag for the preference screen that
is usually mostly empty that RaiodButtonPickerFragments use

Test: robotests
Bug: 111450127
Change-Id: I0fe2f480f0ff59b9bf9269e94b33ab4b008b47b8
This commit is contained in:
Salvador Martinez
2018-12-04 14:13:10 -08:00
parent bccad4abd8
commit 42e9d26635
9 changed files with 163 additions and 7 deletions

View File

@@ -55,6 +55,8 @@ public class PreferenceXmlParserUtils {
private static final List<String> SUPPORTED_PREF_TYPES = Arrays.asList(
"Preference", "PreferenceCategory", "PreferenceScreen",
"com.android.settings.widget.WorkOnlyCategory");
public static final int PREPEND_VALUE = 0;
public static final int APPEND_VALUE = 1;
/**
* Flag definition to indicate which metadata should be extracted when
@@ -84,6 +86,7 @@ public class PreferenceXmlParserUtils {
int FLAG_NEED_KEYWORDS = 1 << 8;
int FLAG_NEED_SEARCHABLE = 1 << 9;
int FLAG_ALLOW_DYNAMIC_SUMMARY_IN_SLICE = 1 << 10;
int FLAG_NEED_PREF_APPEND = 1 << 11;
}
public static final String METADATA_PREF_TYPE = "type";
@@ -97,6 +100,7 @@ public class PreferenceXmlParserUtils {
public static final String METADATA_SEARCHABLE = "searchable";
public static final String METADATA_ALLOW_DYNAMIC_SUMMARY_IN_SLICE =
"allow_dynamic_summary_in_slice";
public static final String METADATA_APPEND = "staticPreferenceLocation";
private static final String ENTRIES_SEPARATOR = "|";
@@ -184,14 +188,13 @@ public class PreferenceXmlParserUtils {
// Parse next until start tag is found
}
final int outerDepth = parser.getDepth();
final boolean hasPrefScreenFlag = hasFlag(flags, MetadataFlag.FLAG_INCLUDE_PREF_SCREEN);
do {
if (type != XmlPullParser.START_TAG) {
continue;
}
final String nodeName = parser.getName();
if (!hasFlag(flags, MetadataFlag.FLAG_INCLUDE_PREF_SCREEN)
&& TextUtils.equals(PREF_SCREEN_TAG, nodeName)) {
if (!hasPrefScreenFlag && TextUtils.equals(PREF_SCREEN_TAG, nodeName)) {
continue;
}
if (!SUPPORTED_PREF_TYPES.contains(nodeName) && !nodeName.endsWith("Preference")) {
@@ -199,8 +202,14 @@ public class PreferenceXmlParserUtils {
}
final Bundle preferenceMetadata = new Bundle();
final AttributeSet attrs = Xml.asAttributeSet(parser);
final TypedArray preferenceAttributes = context.obtainStyledAttributes(attrs,
R.styleable.Preference);
TypedArray preferenceScreenAttributes = null;
if (hasPrefScreenFlag) {
preferenceScreenAttributes = context.obtainStyledAttributes(
attrs, R.styleable.PreferenceScreen);
}
if (hasFlag(flags, MetadataFlag.FLAG_NEED_PREF_TYPE)) {
preferenceMetadata.putString(METADATA_PREF_TYPE, nodeName);
@@ -236,6 +245,10 @@ public class PreferenceXmlParserUtils {
preferenceMetadata.putBoolean(METADATA_ALLOW_DYNAMIC_SUMMARY_IN_SLICE,
isDynamicSummaryAllowed(preferenceAttributes));
}
if (hasFlag(flags, MetadataFlag.FLAG_NEED_PREF_APPEND) && hasPrefScreenFlag) {
preferenceMetadata.putBoolean(METADATA_APPEND,
isAppended(preferenceScreenAttributes));
}
metadata.add(preferenceMetadata);
preferenceAttributes.recycle();
@@ -325,7 +338,12 @@ public class PreferenceXmlParserUtils {
false /* default */);
}
private static String getKeywords(TypedArray styleAttributes) {
return styleAttributes.getString(R.styleable.Preference_keywords);
private static String getKeywords(TypedArray styledAttributes) {
return styledAttributes.getString(R.styleable.Preference_keywords);
}
private static boolean isAppended(TypedArray styledAttributes) {
return styledAttributes.getInt(R.styleable.PreferenceScreen_staticPreferenceLocation,
PREPEND_VALUE) == APPEND_VALUE;
}
}

View File

@@ -22,10 +22,12 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.LayoutRes;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
@@ -34,16 +36,23 @@ import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.core.PreferenceXmlParserUtils;
import com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag;
import com.android.settingslib.widget.CandidateInfo;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import org.xmlpull.v1.XmlPullParserException;
public abstract class RadioButtonPickerFragment extends InstrumentedPreferenceFragment implements
RadioButtonPreference.OnClickListener {
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
@VisibleForTesting
static final String EXTRA_FOR_WORK = "for_work";
private static final String TAG = "RadioButtonPckrFrgmt";
@VisibleForTesting
boolean mAppendStaticPreferences = false;
private final Map<String, CandidateInfo> mCandidates = new ArrayMap<>();
@@ -69,6 +78,19 @@ public abstract class RadioButtonPickerFragment extends InstrumentedPreferenceFr
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
super.onCreatePreferences(savedInstanceState, rootKey);
try {
// Check if the xml specifies if static preferences should go on the top or bottom
final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(getContext(),
getPreferenceScreenResId(),
MetadataFlag.FLAG_INCLUDE_PREF_SCREEN |
MetadataFlag.FLAG_NEED_PREF_APPEND);
mAppendStaticPreferences = metadata.get(0)
.getBoolean(PreferenceXmlParserUtils.METADATA_APPEND);
} catch (IOException e) {
Log.e(TAG, "Error trying to open xml file", e);
} catch (XmlPullParserException e) {
Log.e(TAG, "Error parsing xml", e);
}
updateCandidates();
}
@@ -142,7 +164,9 @@ public abstract class RadioButtonPickerFragment extends InstrumentedPreferenceFr
final String systemDefaultKey = getSystemDefaultKey();
final PreferenceScreen screen = getPreferenceScreen();
screen.removeAll();
addStaticPreferences(screen);
if (!mAppendStaticPreferences) {
addStaticPreferences(screen);
}
final int customLayoutResId = getRadioButtonPreferenceCustomLayoutResId();
if (shouldShowItemNone()) {
@@ -168,6 +192,9 @@ public abstract class RadioButtonPickerFragment extends InstrumentedPreferenceFr
}
}
mayCheckOnlyRadioButton();
if (mAppendStaticPreferences) {
addStaticPreferences(screen);
}
}
@VisibleForTesting