如何获取引用属性

时间:2016-01-18 17:15:20

标签: android android-custom-view

我想实现一个自动更新TextView的SeekBar,用于实际值,最大值和最小值。我派生自SeekBar并定义3个命名属性,formatreference

在构造函数中,我通过调用TypedArray得到obtainStyledAttributes()TypedArray包含针对各种属性类型的大量getter。我缺少的是某种Object getReference()int getReferenceId()

如何获取参考属性的值?

编辑:

我有一个类MinMaxSlider的属性定义,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MinMaxSlider">
        <attr name="min" format="integer" />
        <attr name="valueView" format="reference" />
    </declare-styleable>
</resources>

剪裁出的布局定义如下所示:

    <LinearLayout
        style="@style/ParameterLabelLayout"
        android:orientation="horizontal">
        <TextView
            style="@style/ParameterSliderLabel"
            android:text="min. Interval" />
        <TextView
            android:id="@+id/min_connection_interval_slider_value"
            style="@style/ParameterSliderValue"/>
    </LinearLayout>

    <com.roche.rcpclient.MinMaxSlider
        style="@style/ParameterSlider"
        android:id="@+id/min_connection_interval_slider"
        android:max="3200"
        custom:valueView="@id/min_connection_interval_slider_value"
        custom:min="1"/>

在这里,MinMaxSlider应该引用上面的一个TextViews来显示它的当前值。

MinMaxSlider的构造函数中,我可以查找min属性值。

如果我尝试将valueView属性作为整数查找,我总是得到默认值(0),而不是我期望的R.id.min_connection_interval_slider

编辑:查找reference的正确功能似乎是getResourceId。当构造整个对象层次结构时,获得的整数id可用于稍后使用findViewById

在我的情况下,我会在回调被触发时注册OnSeekBarChangeListener()并在回调中查找View。

1 个答案:

答案 0 :(得分:7)

您无法在构造函数中通过findViewById接收引用。因为它尚未附加到布局。 参考:https://developer.android.com/training/custom-views/create-view.html#applyattr

  

从XML布局创建视图时,其中包含所有属性   XML标记从资源包中读取并传递给   将构造函数视为AttributeSet。虽然可以阅读   来自AttributeSet的值,这样做有一些   缺点:

     

属性值中的资源引用未解析样式   未应用相反,将AttributeSet传递给   obtainStyledAttributes()。此方法传回TypedArray数组   已被解除引用和设置样式的值。

您可以通过其他方式接收。 例如:

attrs.xml

 <declare-styleable name="CustomTextView">
    <attr name="viewPart" format="reference"></attr>
 </declare-styleable>

yourLayout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:baselineAligned="false"
    android:gravity="center_vertical"
    android:orientation="horizontal">

  <tr.com.ui.utils.CustomTextView
                        android:id="@+id/chat_msg"                           
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="right|bottom"
                        android:focusableInTouchMode="false"
                        android:gravity="left"                          
                        android:text="test"
                        app:viewPart="@id/date_view" />



                    <TextView
                        android:id="@+id/date_view"                         
                        android:layout_alignParentBottom="true"
                        android:layout_alignParentRight="true"                          
                        android:gravity="right" />

</LinearLayout>

CustomTextView.java

   public class CustomTextView extends TextView {
    private View viewPart;
    private int viewPartRef;

    public CustomTextView(Context context) {
        super(context);
    }

    public CustomTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomTextView, 0, 0);

        try {
            viewPartRef = a.getResourceId(R.styleable.CustomTextView_viewPart, -1);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        viewPart = ((View) this.getParent()).findViewById(viewPartRef);
    }    

    public View getViewPart() {
        return viewPart;
    }

    public void setViewPart(View viewPart) {
        this.viewPart = viewPart;
    }}

您可以决定您的方案并修改此代码。