Android:使用值列表创建自定义视图

时间:2018-03-11 13:59:17

标签: android android-custom-view android-databinding

我尝试使用值列表创建一个自定义视图的微调器。我已成功使用以下代码开始使用。

public class SelectionTextView extends TextInputEditText implements View.OnClickListener {

    private CharSequence[] entries, values;
    private CharSequence value;

    @Override
    public void onClick(View v) {
        new AlertDialog.Builder(v.getContext())
                .setTitle("Title")
                .setItems(entries, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        value = values[which];
                        SelectionTextView.super.setText(entries[which]);
                    }
                })
                .create()
                .show();
    }

    public SelectionTextView(final Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        super.setCursorVisible(false);
        super.setFocusable(false);
        super.setFocusableInTouchMode(false);
        super.setInputType(InputType.TYPE_NULL);
        super.setOnClickListener(this);
    }

    public void setEntries(CharSequence[] entries) {
        this.entries = entries;
        super.setOnClickListener(this);
    }

    public void setValues(CharSequence[] values) {
        this.values = values;
    }

    public void setValue(Object value) {
        this.value = value.toString();
    }

    public CharSequence getValue() {
        return value;
    }


}

但是,我想实现onValueChanged,onEntryChanged之类的东西。我该怎么做呢?另外,如何通过Android数据绑定使值属性可绑定。

感谢任何帮助。

更新日期:03/13/2018

发布我完整且有效的SelectionTextView.class。

package com.mycompany.myproject;

import android.content.Context;
import android.content.DialogInterface;
import android.content.res.TypedArray;
import android.support.annotation.Nullable;
import android.support.design.widget.TextInputEditText;
import android.support.v7.app.AlertDialog;
import android.text.InputType;
import android.util.AttributeSet;
import android.view.View;

public class SelectionTextView extends TextInputEditText implements View.OnClickListener {

    private CharSequence[] entries, values;
    private String value;
    private String prompt;

    private OnValueChangedListener listener;

    @Override
    public void onClick(View v) {
        new AlertDialog.Builder(v.getContext())
                .setTitle(prompt)
                .setItems(entries, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        setValue(values[which].toString());
                    }
                })
                .create()
                .show();
    }

    public SelectionTextView(final Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        super.setCursorVisible(false);
        super.setFocusable(false);
        super.setFocusableInTouchMode(false);
        super.setInputType(InputType.TYPE_NULL);
        super.setOnClickListener(this);

        TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SelectionTextView, 0, 0);
        try {
            entries = typedArray.getTextArray(R.styleable.SelectionTextView_entries);
            values = typedArray.getTextArray(R.styleable.SelectionTextView_values);
            value = typedArray.getString(R.styleable.SelectionTextView_value);
            prompt = typedArray.getString(R.styleable.SelectionTextView_prompt);
        } finally {
            typedArray.recycle();
        }
    }

    public void setOnValueChangeListener(OnValueChangedListener listener) {
        setValue(this.value);
    }

    public void setEntries(CharSequence[] entries) {
        this.entries = entries;
        invalidate();
    }

    public void setValues(CharSequence[] values) {
        this.values = values;
        invalidate();
    }

    public void setValue(String value) {
        this.value = value;
        if (value != null) {
            if (entries != null && values != null) {
                for (int i = 0; i < entries.length; i++) {
                    if (values[i].toString().equals(value)) {
                        super.setText(entries[i].toString());
                        invalidate();
                        break;
                    }
                }
            }
        }
    }

    public void setValue(Integer value) {
        if (value != null) {
            setValue(value.toString());
        }
    }

    public String getValue() {
        return value;
    }

    public interface OnValueChangedListener {
        void onValueChange(SelectionTextView view, String value);
    }
}

然后在我的实际项目中,我只创建一个具有所有必要绑定的类。

package com.mycompany.myproject;

import android.databinding.BaseObservable;
import android.databinding.BindingAdapter;
import android.databinding.InverseBindingAdapter;
import android.databinding.InverseBindingListener;
import android.databinding.InverseBindingMethod;
import android.databinding.InverseBindingMethods;
import android.widget.TextView;

import com.mycompany.views.SelectionTextView;

@InverseBindingMethods({
        @InverseBindingMethod(type = SelectionTextView.class, attribute = "value"),
})
public class BindingManager extends BaseObservable {


    @BindingAdapter("android:text")
    public static void setText(TextView view, Integer value) {
        if (value != null) {
            view.setText(Integer.toString(value));
        }
    }

    @InverseBindingAdapter(attribute = "android:text")
    public static Integer getText(TextView view) {
        if (view.getText().length() == 0)
            return null;
        else
            return Integer.parseInt(view.getText().toString());
    }

    @BindingAdapter(value = {"onValueChange", "valueAttrChanged"}, requireAll = false)
    public static void setValueChangedListener(SelectionTextView view,
                                               final SelectionTextView.OnValueChangedListener listener,
                                               final InverseBindingListener valueChange) {
        if (valueChange == null) {
            view.setOnValueChangeListener(listener);
        } else {
            view.setOnValueChangeListener(new SelectionTextView.OnValueChangedListener() {
                @Override
                public void onValueChange(SelectionTextView view, String value) {
                    if (listener != null) {
                        listener.onValueChange(view, value);
                    }
                    valueChange.onChange();
                }
            });
        }
    }

    @InverseBindingAdapter(attribute = "value")
    public static Integer getValue(SelectionTextView view) {
        if (view.getValue() == null) {
            return null;
        } else {
            return Integer.parseInt(view.getValue());
        }
    }

    @BindingAdapter("value")
    public static void setValue(SelectionTextView view, Integer value) {
        if (value != null) {
            view.setValue(value);
        } else {
            view.setValue("");
        }
    }

    @BindingAdapter("value")
    public static void setValue(SelectionTextView view, String value) {
        if (value != null) {
            view.setValue(value);
        } else {
            view.setValue("");
        }
    }

}

1 个答案:

答案 0 :(得分:1)

AttributeSet构造函数中,添加以下内容:

TypedArray a = context.getTheme().obtainStyledAttributes(
    attrs,
    R.styleable.SelectionTextView, 0, 0);
value = a.getString(R.styleable.SelectionTextView_value, "");

res\values文件夹中,添加包含以下内容的attrs.xml

<resources>
    <declare-styleable name="SelectionTextView">
        <attr name="value" format="string" />
    </declare-styleable>
</resources>

对于onValueChanged,只需定义一个具有onValueChanged方法的接口和一个以接口作为参数的“register”方法,并将其存储在数据成员中。然后,在setValue方法中,调用该接口。