使用多个自定义首选项可显示,布局,首选项标题和共享的首选项值

时间:2018-12-03 09:52:39

标签: android android-layout sharedpreferences android-preferences preferenceactivity

我创建了一个自定义首选项视图,当在我的首选项屏幕中使用单个实例时,它可以完美地工作,但是当插入多个实例时,一切都变得一团糟。有些实例带有其他实例的标题,单击时说view1,然后改为view2聚焦,等等。我认为我的OnCreateView函数或布局文件{ {1}}属性。

请认识到我的pref_plates.xml(“首选项”屏幕)中的首选项标题与屏幕快照图像中的首选项标题之间的区别,以便更好地理解我的问题。

limited_editextpreference_view.xml(布局文件):

android:id

limited_edittextpreference_attrib.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 >

pref_plates.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>

LimitedEditTextPreference.java:

<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>

首选项屏幕截图:

Preference Screen Screenshot

1 个答案:

答案 0 :(得分:0)

我通过将内部视图findViewByIdonCreateView移到onBindView来解决了这个问题,如下所示:

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, -1, -1);
}

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(attrs, 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);

    LayoutInflater li = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View v = li.inflate(R.layout.limited_edittextpreference_view, parent, false);

    return v;
}

@Override
public void notifyDependencyChange(boolean disableDependents) {
    super.notifyDependencyChange(disableDependents);
    notifyChanged();

}


@Override
protected void onBindView(View view) {
    super.onBindView(view);

    SharedPreferences sharedPref = context_.getSharedPreferences("Configs", Context.MODE_PRIVATE);


    editText = (EditText) view.findViewById(R.id.txt_lep_edit);
    txt_title = (TextView) view.findViewById(R.id.txt_lep_title);
    txt_summary = (TextView) view.findViewById(R.id.txt_lep_summary);
    txt_unit = (TextView) view.findViewById(R.id.txt_lep_unit);

    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));

            }
        }
    });


    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("Configs", 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 "";
}