Пользовательские предпочтения, targetSdkVersion = "11": отсутствует отступ?
У меня есть пара пользовательских реализаций DialogPreference
, плавающих вокруг, например этот:
package apt.tutorial;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.preference.DialogPreference;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.TimePicker;
public class TimePreference extends DialogPreference {
private int lastHour=0;
private int lastMinute=0;
private TimePicker picker=null;
public static int getHour(String time) {
String[] pieces=time.split(":");
return(Integer.parseInt(pieces[0]));
}
public static int getMinute(String time) {
String[] pieces=time.split(":");
return(Integer.parseInt(pieces[1]));
}
public TimePreference(Context ctxt) {
this(ctxt, null);
}
public TimePreference(Context ctxt, AttributeSet attrs) {
this(ctxt, attrs, 0);
}
public TimePreference(Context ctxt, AttributeSet attrs, int defStyle) {
super(ctxt, attrs, defStyle);
setPositiveButtonText("Set");
setNegativeButtonText("Cancel");
}
@Override
protected View onCreateDialogView() {
picker=new TimePicker(getContext());
return(picker);
}
@Override
protected void onBindDialogView(View v) {
super.onBindDialogView(v);
picker.setCurrentHour(lastHour);
picker.setCurrentMinute(lastMinute);
}
@Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if (positiveResult) {
lastHour=picker.getCurrentHour();
lastMinute=picker.getCurrentMinute();
String time=String.valueOf(lastHour)+":"+String.valueOf(lastMinute);
if (callChangeListener(time)) {
persistString(time);
}
}
}
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return(a.getString(index));
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
String time=null;
if (restoreValue) {
if (defaultValue==null) {
time=getPersistedString("00:00");
}
else {
time=getPersistedString(defaultValue.toString());
}
}
else {
time=defaultValue.toString();
}
lastHour=getHour(time);
lastMinute=getMinute(time);
}
}
Они работают отлично. Однако в приложении с android:targetSdkVersion="11"
, определенном, на XOOM они обнаруживают отсутствие отступа, когда в PreferenceActivity
:
![PreferenceActivity with messed-up custom DialogPreference]()
Кроме того, размер шрифта становится более сильным, по крайней мере, для заголовка.
Нет ничего в DialogPreference
, где я действительно переопределяю любое поведение форматирования для этого материала, AFAIK. XML предпочтения не примечателен, кроме ссылки на вышеуказанный класс:
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<ListPreference
android:key="sort_order"
android:title="Sort Order"
android:summary="Choose the order the list uses"
android:entries="@array/sort_names"
android:entryValues="@array/sort_clauses"
android:dialogTitle="Choose a sort order" />
<CheckBoxPreference
android:key="alarm"
android:title="Sound a Lunch Alarm"
android:summary="Check if you want to know when it is time for lunch" />
<apt.tutorial.TimePreference
android:key="alarm_time"
android:title="Lunch Alarm Time"
android:defaultValue="12:00"
android:summary="Set your desired time for the lunch alarm"
android:dependency="alarm" />
<CheckBoxPreference
android:key="use_notification"
android:title="Use a Notification"
android:defaultValue="true"
android:summary="Check if you want a status bar icon at lunchtime, or uncheck for a full-screen notice"
android:dependency="alarm" />
</PreferenceScreen>
Кто-нибудь знает, где я ошибаюсь?
Спасибо!
UPDATE
Вот ссылка на проект, который содержит эту настраиваемую настройку и простой XML файл предпочтений, который демонстрирует проблему. Даже с двумя классами Java, предпочтением XML и файлом arrays.xml
, я получаю это явление. Вот скомпилированный APK из этого проекта.
Ответы
Ответ 1
(перекрестная отправка из связанного потока андроидов-разработчиков)
ОК, я понял это.
В предпочтении есть три возможных конструктора:
MyPreference(Context ctxt)
MyPreference(Context ctxt, AttributeSet attrs)
MyPreference(Context ctxt, AttributeSet attrs, int defStyle)
Где-то вдоль линии я взял образец
однопараметрическая цепочка конструктора к двухпараметрическому конструктору
(передача null
для второго параметра) и наличие двухпараметрического
цепочку конструкторов к трехпараметровому конструктору (передавая 0 для
3-й параметр).
И это не правильный ответ.
Я надеюсь, что правильным ответом будет только реализация второго
конструктор, потому что правильный стиль по умолчанию является внутренним для Android
(com.android.internal.R.attr.dialogPreferenceStyle
). Второй
конструктор - тот, который используется с раздуванием XML-предпочтений.
Спасибо всем за помощь!
Ответ 2
Вы можете танцевать с помощью метода void Preference.setWidgetLayoutResource(int widgetLayoutResId)
, хотя я предпочитаю переопределять метод View Preference.onCreateView(ViewGroup parent)
в моем настраиваемом классе предпочтений и взламывать его, добавляя пользовательские представления чуть ниже @android:id/summary
(для получения более подробной информации используйте утилиту hierarchyviewer).
Полный метод:
@Override
protected View onCreateView(ViewGroup parent)
{
View ret = super.onCreateView(parent);
View summary = ret.findViewById(android.R.id.summary);
if (summary != null)
{
ViewParent summaryParent = summary.getParent();
if (summaryParent instanceof ViewGroup)
{
final LayoutInflater layoutInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup summaryParent2 = (ViewGroup) summaryParent;
layoutInflater.inflate(R.layout.seek_bar_preference, summaryParent2);
seekBar = (SeekBar) summaryParent2.findViewById(R.id.seekBar);
seekBar.setMax(maxValue - minValue);
seekBar.setOnSeekBarChangeListener(this);
statusText = (TextView) summaryParent2.findViewById(R.id.seekBarPrefValue);
unitsRightView = (TextView) summaryParent2.findViewById(R.id.seekBarPrefUnitsRight);
unitsLeftView = (TextView) summaryParent2.findViewById(R.id.seekBarPrefUnitsLeft);
}
}
return ret;
}
Исходный код моего класса SeekBarPreference на основе кода http://robobunny.com можно загрузить здесь
![image1]()
![image2]()
Ответ 3
Я попробовал свой код на эмуляторе. Нет проблем с кодом, который вы указали, и все строки имеют одинаковое форматирование; но все они более похожи (в формате) на третье предпочтение (Lunch Alarm Time
), чем другие.
Похоже, что остальные три параметра получают отступы больше, чем требуется. Таким образом, может быть, у вас есть какой-то глобальный стиль форматирования, который используется, но не подхвачен предпочтением TimePreference
.
ИЗМЕНИТЬ: ОК. Итак, вышесказанное не является (полностью) истинным. Существует определенная проблема, когда я попытался установить целевой параметр sdk на HoneyComb
. Но при установке темы для класса PreferenceActivity
в качестве android:theme="@android:style/Theme.Black"
существует последовательность во взглядах всех настроек, как показано ниже.
![enter image description here]()
Этот стиль похож на Froyo
, но не на HoneyComb
; в последнем, шрифт названия меньше, и есть больше отступов. Вероятно, тема по умолчанию не присваивается Custom Preferences
- просто предположение:) Обходным решением было бы явно назначить тему по умолчанию для вашей активности предпочтений, но я не знаю, какая тема по умолчанию в HoneyComb (и независимо от того, его можно установить).
Ответ 4
Решение, которое помогло мне:
Я заменил
public TimePreference(Context ctxt, AttributeSet attrs) {
this(ctxt, attrs, 0);
}
с
public TimePreference(Context ctxt, AttributeSet attrs) {
this(ctxt, attrs, ctxt.getResources().getSystem().getIdentifier("dialogPreferenceStyle", "attr", "android"));
}
Как вы можете видеть, я заменил третий аргумент 0 на ctxt.getResources(). getSystem(). getIdentifier ( "dialogPreferenceStyle", "attr", "android" ) во втором конструкторе пользовательского класса предпочтений.
Ответ 5
Чтобы сделать принятый ответ более ясным. Вам нужен только этот конструктор:
public TimePreference(Context ctxt, AttributeSet attrs) {
// this(ctxt, attrs, 0); // wrong
super(ctxt, attrs);
}