I want to implement a SeekBar that automatically updates a TextView, for the actual value, the maximum value and a minimum value. I derive from SeekBar and define 3 named attributes with the format
being reference
.
In the constructor, I get a TypedArray
by calling obtainStyledAttributes()
. TypedArray
contains a lot of getters for every kind of attribute types. What I am missing is some kind of Object getReference()
or int getReferenceId()
.
How do I obtain the value for a reference attribute?
Edit:
I have an attribute definition for a class MinMaxSlider
, that looks like this:
<?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>
a snipped out of the layout definition looks like this:
<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"/>
Here, the MinMaxSlider
should reference one of the TextViews above to display its current value there.
From within the constructor of MinMaxSlider
, I can lookup the min attributes value.
If I try to lookup the valueView attribute as an integer, I always get the default value (0), not R.id.min_connection_interval_slider
as I would expect.
Edit: the right function to lookup a reference
seems to be getResourceId
. The obtained integer id can be used to use findViewById
later, when the overall object hierarchy is constructed.
In my case, I register an OnSeekBarChangeListener()
and lookup the View in the callback, when the callback is fired.
First, declare an instance of the attribute you want to retrieve. Then, use the Attribute. GetCustomAttribute method to initialize the new attribute to the value of the attribute you want to retrieve. Once the new attribute is initialized, you can use its properties to get the values.
Attribute references are attributes that derive their primitive type, default value, immutable flag and attribute rules from another preexisting attribute definition.
You can't receive reference via findViewById in constructor. Because it is not attached to layout yet. Reference: https://developer.android.com/training/custom-views/create-view.html#applyattr
When a view is created from an XML layout, all of the attributes in the XML tag are read from the resource bundle and passed into the view's constructor as an AttributeSet. Although it's possible to read values from the AttributeSet directly, doing so has some disadvantages:
Resource references within attribute values are not resolved Styles are not applied Instead, pass the AttributeSet to obtainStyledAttributes(). This method passes back a TypedArray array of values that have already been dereferenced and styled.
You can receive in another methods. For example:
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;
}}
You can decide your scenario and modify this code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With