How to create an AttributeSet in Android?
Upon re-reading, one of your issues will lie in the fact that the xyz
attribute is declared outside of the CustomViewStyleable in attrs.xml
.
Instead of calling your custom view's constructor directly, you can let the system handle that by inflating your custom view from xml.
Create an xml layout file which contains only your custom view, e.g. view_my_compound.xml
:
<?xml version="1.0" encoding="utf-8"?>
<com.example.mycompoundbutton.MyCompound
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:xyz="2" />
Then in your Activity, you'll just inflate it:
// the view which will contain your MyCompoundButton
View container = findViewById(R.id.XXXXXXXX);
LayoutInflater inflater = getLayoutInflater();
MyCompound button = (MyCompound) inflater.inflate(R.layout.view_my_compound, container, true);
This way you don't need to consider the attribute set apart from inside your view class; Android will call the MyCompound(Context, AttributeSet)
constructor for you, with the values set in the XML layout file.
If you need to set XYZ parameter programmatically, expose a public method in MyCompound
which lets you set it.
MyProg
Updated on June 25, 2022Comments
-
MyProg about 2 years
I am trying to write some code in Android to set parameters in an
AttributeSet
from attrs.xml file. But I am getting a "Resource not Found" error.Java Code
MainActivity.java
package com.example.mycompoundbutton; import org.xmlpull.v1.XmlPullParser; import android.os.Bundle; import android.util.AttributeSet; import android.util.Xml; import android.app.Activity; import android.content.res.Resources; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Resources res = this.getResources(); XmlPullParser parser = res.getXml(R.attr.xyz); AttributeSet attrs = Xml.asAttributeSet(parser); MyCompound my = new MyCompound(this,attrs); my.MyTestFun(300,500); } }
MyCompound.java
package com.example.mycompoundbutton; import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; import android.widget.CompoundButton; public class MyCompound extends CompoundButton { public MyCompound(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.MyCustomView, R.attr.xyz, 0); a.recycle(); } public void MyTestFun(int x,int y) { // Some Code to Execute }}
attrs.xml
<resources> <declare-styleable name="MyCustomView"> <attr name="abc" format="integer"/> <attr name="pqr" format="integer" /> </declare-styleable> <attr name="xyz" format="integer"/> </resources>
Error :
05-11 07:29:27.345: E/AndroidRuntime(1919): FATAL EXCEPTION: main 05-11 07:29:27.345: E/AndroidRuntime(1919): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.mycompoundbutton/com.example.mycompoundbutton.MainActivity}: android.content.res.Resources$NotFoundException: Resource ID #0x7f010000 05-11 07:29:27.345: E/AndroidRuntime(1919): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211) 05-11 07:29:27.345: E/AndroidRuntime(1919): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261) 05-11 07:29:27.345: E/AndroidRuntime(1919): at android.app.ActivityThread.access$600(ActivityThread.java:141) 05-11 07:29:27.345: E/AndroidRuntime(1919): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256) 05-11 07:29:27.345: E/AndroidRuntime(1919): at android.os.Handler.dispatchMessage(Handler.java:99) 05-11 07:29:27.345: E/AndroidRuntime(1919): at android.os.Looper.loop(Looper.java:137) 05-11 07:29:27.345: E/AndroidRuntime(1919): at android.app.ActivityThread.main(ActivityThread.java:5103) 05-11 07:29:27.345: E/AndroidRuntime(1919): at java.lang.reflect.Method.invokeNative(Native Method) 05-11 07:29:27.345: E/AndroidRuntime(1919): at java.lang.reflect.Method.invoke(Method.java:525) 05-11 07:29:27.345: E/AndroidRuntime(1919): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 05-11 07:29:27.345: E/AndroidRuntime(1919): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 05-11 07:29:27.345: E/AndroidRuntime(1919): at dalvik.system.NativeStart.main(Native Method) 05-11 07:29:27.345: E/AndroidRuntime(1919): Caused by: android.content.res.Resources$NotFoundException: Resource ID #0x7f010000 05-11 07:29:27.345: E/AndroidRuntime(1919): at android.content.res.Resources.getValue(Resources.java:1118) 05-11 07:29:27.345: E/AndroidRuntime(1919): at android.content.res.Resources.loadXmlResourceParser(Resources.java:2304) 05-11 07:29:27.345: E/AndroidRuntime(1919): at android.content.res.Resources.getXml(Resources.java:983) 05-11 07:29:27.345: E/AndroidRuntime(1919): at com.example.mycompoundbutton.MainActivity.onCreate(MainActivity.java:24) 05-11 07:29:27.345: E/AndroidRuntime(1919): at android.app.Activity.performCreate(Activity.java:5133) 05-11 07:29:27.345: E/AndroidRuntime(1919): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) 05-11 07:29:27.345: E/AndroidRuntime(1919): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175) 05-11 07:29:27.345: E/AndroidRuntime(1919): ... 11 more
So , here is all the above Code and Error description. I want to call
MyCompound
class fromMainActivity
. I know how to do it using anXML
file such as<com.example.mycompoundbutton.MyCompound ... attributes here ... > </com.example.mycompoundbutton.MyCompound>
This above structure will help me to design a static custom layout but it won't help me to design a dynamic layout.
So, how can I call the
MyCompound
class fromMainActivity
with anAttributeSet
? -
MyProg about 10 yearsNo Friend getting error ... The method from(Context) in the type LayoutInflater is not applicable for the arguments (MainActivity, View, int)
-
ataulm about 10 yearssorry,
LayoutInflater.from(this).inflate(R.layout.view_my_compound, container, true);
But also consider the first amended line of this answer.