I'm trying to learn how to use custom attributes in Android Studio. I follow a couple of tutorials on the subject and despite my efforts nothing seems to work. I created a code that illustrates the problem.
I've created simple custom view, which doesnt represent anything but only obtains styled attributes. This is my customView code:
package com.example.mytestattributes;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import androidx.annotation.Nullable;
public class customView extends View {
public customView(Context context) {
super(context);
init(null);
}
public customView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
private void init(@Nullable AttributeSet attrs){
if(attrs!=null){
Log.d("INIT", "attribute set found");
TypedArray ta = getContext().obtainStyledAttributes(R.styleable.customView);
Log.d("LENGHT OF TA: ", ta.length()+"");
Log.d("testString has value", ta.hasValue(R.styleable.customView_testString)+"");
Log.d("testInteger has value", ta.hasValue(R.styleable.customView_testInteger)+"");
Log.d("testBoolean has value", ta.hasValue(R.styleable.customView_testBoolean)+"");
Log.d("testColor has value", ta.hasValue(R.styleable.customView_testColor)+"");
Log.d("testDimension has value", ta.hasValue(R.styleable.customView_testDimension)+"");
Log.d("testEnum has value", ta.hasValue(R.styleable.customView_testEnum)+"");
Log.d("Return testDimension: ", ""+ta.getDimensionPixelSize(R.styleable.customView_testDimension,0));
Log.d("Return testDimension: ", ""+ta.getDimension(R.styleable.customView_testDimension,0));
}else{
Log.d("INIT", "no attribute set found");
}
}
}
The code compiles and the output is:
D/INIT: attribute set found
D/LENGHT OF TA:: 6
D/testString has value: false
D/testInteger has value: false
D/testBoolean has value: false
D/testColor has value: false
D/testDimension has value: false
D/testEnum has value: false
D/Return testDimension:: 0
D/Return testDimension:: 0.0
The lenght of typed array is correct, meaning that the program sees the attributes but when I ask it to check if the attributes have value the outcome is false. As a consequence any attempt to read this attibutes always returns default value. In the example code I included just getDimension but the same holds for all other get methods.
This is my attrs.xml, where I defined the attibutes:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="customView">
<attr name="testString" format="string|reference"/>
<attr name="testInteger" format="integer"/>
<attr name="testBoolean" format="boolean"/>
<attr name="testColor" format="color|reference"/>
<attr name="testDimension" format="dimension"/>
<attr name="testEnum" format="enum">
<enum name="var1" value="1"/>
<enum name="var2" value="2"/>
</attr>
</declare-styleable>
</resources>
I try to pass values in Activity_Main.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.example.mytestattributes.customView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:testBoolean="true"
app:testDimension="200dp"
app:testColor="@color/colorAccent"
app:testEnum="var1"
app:testInteger="15"
app:testString="@string/app_name"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
The MainActivity.java is unmodified empty activity class. I am aware that some people had the similiar problems a couple of years ago but no valid answers were ever posted. Is anyone aware what is wrong with this code? Im using API 17.
referenceas one of your attribute formats when you're passing resources?<attr name="testString" format="string|reference"/>for strings and<attr name="testColor" format="color|reference"/>for colors.