Я создал настраиваемое представление предпочтений, которое отлично работает при использовании одного его экземпляра на моем экране предпочтений, однако при вставке нескольких экземпляров все становится беспорядочным.Некоторые экземпляры берут название других, когда нажимаем, скажем, view1
, затем view2
фокусируется вместо этого и т. Д. Я думаю, что у меня проблема в моей функции OnCreateView
или в моем атрибуте файла макета android:id
.
Пожалуйста, признайте разницу между названиями предпочтений в моем pref_plates.xml (экране настроек) относительно их заголовков на снимке экрана, чтобы лучше понять мою проблему.
limited_editextpreference_view.xml (файл макета):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/widget_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="@+id/lep_sub_rl"
android:layout_width="wrap_content"
android:layout_height="60dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="26dp"
android:minHeight="40dp">
<TextView
android:id="@+id/txt_lep_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_above="@+id/txt_lep_summary"
android:layout_toLeftOf="@id/txt_lep_edit"
android:text="General Ammount"
android:ellipsize="end"
android:gravity="bottom"
android:textColor="#302f2f"
android:textSize="16sp" />
<TextView
android:id="@+id/txt_lep_summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:ellipsize="end"
android:layout_toLeftOf="@id/txt_lep_edit"
android:text="General Ammount Summary"
android:maxLines="1"
android:layout_alignBottom="@+id/txt_lep_edit"
android:textSize="12sp" />
<EditText
android:id="@+id/txt_lep_edit"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:layout_toLeftOf="@id/txt_lep_unit"
android:background="@null"
android:textColor="@color/colorAccent"
android:layout_centerInParent="true"
android:textAlignment="textEnd" />
<TextView
android:id="@+id/txt_lep_unit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:maxLength="3"
android:text="%"
android:paddingBottom="2dp"
android:textColor="@color/colorAccent"
android:textAlignment="textEnd"
android:textSize="22sp" />
</RelativeLayout>
</LinearLayout >
limited_edittextpreference_attrib.xml (файл пользовательских атрибутов):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="LimitedEditTextPreference">
<attr name="lep_type" format="enum">
<enum name="integerOnly" value="0"/>
<enum name="doubleOnly" value="1"/>
</attr>
<attr name="lep_minValue" format="float"/>
<attr name="lep_maxValue" format="float"/>
<attr name="lep_unit" format="string"/>
</declare-styleable>
</resources>
pref_plates.xml (экран настроек):
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto">
<PreferenceCategory android:title="Contour Filtering">
<SwitchPreference
android:id="@+id/id_enableContourFiltering"
android:defaultValue="true"
android:key="enableContourFiltering"
android:title="@string/contour_filtering" />
<ListPreference
android:id="@+id/id_maxPlateNumber"
android:defaultValue="2"
android:dependency="enableContourFiltering"
android:entries="@array/maxPlateNumber_array"
android:entryValues="@array/maxPlateNumber_array_values"
android:key="maxPlateNumber"
android:negativeButtonText="@null"
android:positiveButtonText="@null"
android:title="@string/maxPlateNumber" />
<bi.anpr.layouts.LimitedEditTextPreference
android:id="@+id/id_rRecMinArea"
android:defaultValue="1000"
android:dependency="enableContourFiltering"
android:key="rRecMinArea"
android:title="Rotated Rectangle Min Area"
custom:lep_maxValue="1000000"
custom:lep_minValue="1"
custom:lep_type="integerOnly" />
<bi.anpr.layouts.LimitedEditTextPreference
android:id="@+id/id_rRecMaxArea"
android:defaultValue="8799"
android:dependency="enableContourFiltering"
android:key="rRecMaxArea"
android:title="Rotated Rectangle Max Area"
custom:lep_maxValue="1000000"
custom:lep_minValue="1"
custom:lep_type="integerOnly" />
<bi.anpr.layouts.LimitedEditTextPreference
android:id="@+id/id_rRectMinRatio"
android:defaultValue="0.19"
android:dependency="enableContourFiltering"
android:key="rRectMinRatio"
android:title="Rotated Rectangle Min Ratio"
custom:lep_maxValue="1"
custom:lep_minValue="0.1"
custom:lep_type="doubleOnly" />
<bi.anpr.layouts.LimitedEditTextPreference
android:id="@+id/id_rRectMaxRatio"
android:defaultValue="0.83"
android:dependency="enableContourFiltering"
android:key="rRectMaxRatio"
android:title="Rotated Rectangle Max Ratio"
custom:lep_maxValue="1"
custom:lep_minValue="0.1"
custom:lep_type="doubleOnly" />
<bi.anpr.layouts.LimitedEditTextPreference
android:id="@+id/id_bBoxMinRatio"
android:defaultValue="0.17"
android:dependency="enableContourFiltering"
android:key="bBoxMinRatio"
android:title="Bounding Box Min Ratio"
custom:lep_maxValue="1"
custom:lep_minValue="0.1"
custom:lep_type="doubleOnly" />
<bi.anpr.layouts.LimitedEditTextPreference
android:id="@+id/id_bBoxMaxRatio"
android:defaultValue="0.86"
android:dependency="enableContourFiltering"
android:key="bBoxMaxRatio"
android:title="Bounding Box Max Ratio"
custom:lep_maxValue="1"
custom:lep_minValue="0.1"
custom:lep_type="doubleOnly" />
<bi.anpr.layouts.LimitedEditTextPreference
android:id="@+id/id_extent"
android:defaultValue="0.6"
android:dependency="enableContourFiltering"
android:key="extent"
android:title="Extent"
custom:lep_maxValue="1"
custom:lep_minValue="0.1"
custom:lep_type="doubleOnly" />
<bi.anpr.layouts.LimitedEditTextPreference
android:id="@+id/id_zrPlate"
android:defaultValue="0.4"
android:dependency="enableContourFiltering"
android:key="zrPlate"
android:title="Zr Plate"
custom:lep_maxValue="1"
custom:lep_minValue="0.1"
custom:lep_type="doubleOnly" />
</PreferenceCategory>
<PreferenceCategory android:title="Plate Aspects">
<SwitchPreference
android:id="@+id/id_isAllNewPlate"
android:defaultValue="true"
android:disableDependentsState="true"
android:key="isAllNewPlate"
android:summary="@string/isAllNewPlateSummary"
android:title="@string/isAllNewPlate" />
<bi.anpr.layouts.LimitedEditTextPreference
android:id="@+id/id_hightWidePlate"
android:defaultValue="50"
android:dependency="isAllNewPlate"
android:key="hightWidePlate"
android:title="Wide Plate Height"
custom:lep_maxValue="10000"
custom:lep_minValue="1"
custom:lep_type="integerOnly" />
<bi.anpr.layouts.LimitedEditTextPreference
android:id="@+id/id_widthWidePlate"
android:defaultValue="200"
android:dependency="isAllNewPlate"
android:key="widthWidePlate"
android:title="Wide Plate Width"
custom:lep_maxValue="10000"
custom:lep_minValue="1"
custom:lep_type="integerOnly" />
<bi.anpr.layouts.LimitedEditTextPreference
android:id="@+id/id_widthSmallPlate"
android:defaultValue="100"
android:dependency="isAllNewPlate"
android:key="widthSmallPlate"
android:title="Small Plate Width"
custom:lep_maxValue="10000"
custom:lep_minValue="1"
custom:lep_type="integerOnly" />
</PreferenceCategory>
</PreferenceScreen>
LimitedEditTextPreference.java:
package bi.anpr.layouts;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.preference.EditTextPreference;
import android.preference.Preference;
import android.text.InputFilter;
import android.text.Spanned;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.sxx.vlctest.R;
public class LimitedEditTextPreference extends Preference implements InputFilter {
private enum InputType {
integerOnly, decimalOnly;
}
private int lastSavedIntValue = -1;
private float min = 0, max = 100, dv = min, lastSavedDoubleValue = -1;
private String unit = "";
private InputType inputType = InputType.integerOnly;
private EditText editText;
private TextView txt_title, txt_summary, txt_unit;
private Context context_;
public LimitedEditTextPreference(Context context, AttributeSet attrs) {
super(context, attrs);
context_ = context;
readAttributes(context, attrs, 0, 0);
}
public LimitedEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
context_ = context;
readAttributes(context, attrs, defStyleAttr, defStyleRes);
}
public void readAttributes(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
TypedArray attr = null;
if (defStyleAttr == -1)
attr = context.obtainStyledAttributes(R.styleable.LimitedEditTextPreference);
else
attr = context.obtainStyledAttributes(attrs, R.styleable.LimitedEditTextPreference, defStyleAttr, defStyleRes);
int type = attr.getInt(R.styleable.LimitedEditTextPreference_lep_type, 0);
if (type == 1)
inputType = InputType.decimalOnly;
min = attr.getFloat(R.styleable.LimitedEditTextPreference_lep_minValue, 0);
max = attr.getFloat(R.styleable.LimitedEditTextPreference_lep_maxValue, 100);
unit = attr.getString(R.styleable.LimitedEditTextPreference_lep_unit);
TypedArray defaltValAttr = context.obtainStyledAttributes(attrs, new int[]{android.R.attr.defaultValue});
dv = defaltValAttr.getFloat(0, min);
attr.recycle();
defaltValAttr.recycle();
}
@Override
protected synchronized View onCreateView(ViewGroup parent) {
super.onCreateView(parent);
SharedPreferences sharedPref = context_.getSharedPreferences(getKey(), Context.MODE_PRIVATE);
View v = initViews(parent);
txt_title.setText(getTitle());
txt_unit.setText(unit);
if (getSummary() != null && getSummary().toString().trim().length() > 1)
txt_summary.setText(getSummary());
else {
txt_summary.setText("");
txt_summary.setTextSize(0);
}
if (inputType == InputType.integerOnly) {
lastSavedIntValue = sharedPref.getInt(getKey(), (int) dv);
editText.setText(String.valueOf(lastSavedIntValue));
} else if (inputType == InputType.decimalOnly) {
lastSavedDoubleValue = sharedPref.getFloat(getKey(), dv);
editText.setText(String.valueOf(lastSavedDoubleValue));
}
editText.setFilters(new InputFilter[]{this});
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
String val = editText.getText().toString();
if (!TextUtils.isEmpty(val)) {
if (inputType == InputType.integerOnly) {
if (Integer.valueOf(val) < min) {
Toast.makeText(context_, getTitle() + ": Accepted input Range = [" + min + ", " + max + "]", Toast.LENGTH_SHORT).show();
editText.setText(String.valueOf(lastSavedIntValue));
editText.clearFocus();
return;
} else
savePref(Integer.valueOf(val));
} else if (inputType == InputType.decimalOnly)
if (Float.valueOf(val) < min) {
Toast.makeText(context_, getTitle() + ": Accepted input Range = [" + min + ", " + max + "]", Toast.LENGTH_SHORT).show();
editText.setText(String.valueOf(lastSavedDoubleValue));
editText.clearFocus();
return;
} else
savePref(Float.valueOf(val));
}
}
});
return v;
}
@Override
public void notifyDependencyChange(boolean disableDependents) {
super.notifyDependencyChange(disableDependents);
notifyChanged();
}
private View initViews(ViewGroup parent) {
LayoutInflater li = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = li.inflate(R.layout.limited_edittextpreference_view, parent, false);
if (editText != null)
return v;
editText = v.findViewById(R.id.txt_lep_edit);
txt_title = v.findViewById(R.id.txt_lep_title);
txt_summary = v.findViewById(R.id.txt_lep_summary);
txt_unit = v.findViewById(R.id.txt_lep_unit);
return v;
}
@Override
protected void onBindView(View view) {
super.onBindView(view);
view.setClickable(true);
view.setFocusable(false);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
editText.requestFocus();
InputMethodManager imm = (InputMethodManager) context_.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
}
});
}
public void savePref(Number number) {
SharedPreferences sharedPref = context_.getSharedPreferences(getKey(), Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
if (inputType == InputType.integerOnly) {
editor.putInt(getKey(), number.intValue());
lastSavedIntValue = number.intValue();
} else if (inputType == InputType.decimalOnly) {
editor.putFloat(getKey(), number.floatValue());
lastSavedDoubleValue = number.floatValue();
}
editor.commit();
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
try {
String replacement = source.subSequence(start, end).toString();
String newVal = dest.toString().substring(0, dstart) + replacement + dest.toString().substring(dend, dest.toString().length());
if (newVal.equalsIgnoreCase("-")) return null;
if (inputType == InputType.integerOnly) {
int input = Integer.parseInt(newVal);
if (input <= max)
return null;
} else if (inputType == InputType.decimalOnly) {
double input = Float.parseFloat(newVal);
if (input <= max)
return null;
}
} catch (NumberFormatException nfe) {
}
return "";
}
}
Снимок экрана настроек: