How to create an AttributeSet in Android?
Asked Answered
A

3

6

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 from MainActivity. I know how to do it using an XML 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 from MainActivity with an AttributeSet?

Argentiferous answered 11/5, 2014 at 11:46 Comment(1)
com.example.mycompoundbutton.MainActivity.onCreate(MainActivity.java:24) What is line 24 of MainActiivty.java?Freely
W
1

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.

Weakly answered 11/5, 2014 at 12:3 Comment(2)
No Friend getting error ... The method from(Context) in the type LayoutInflater is not applicable for the arguments (MainActivity, View, int)Argentiferous
sorry, LayoutInflater.from(this).inflate(R.layout.view_my_compound, container, true); But also consider the first amended line of this answer.Weakly
F
0

I suggest using a <com.example.mycompoundbutton.MyCompound> tag in activity_main.xml rather than trying to create an instance in your Java code. This will allow Android to inflate your view when you call setContentView() without playing with an inflator yourself. You can apply all the standard attributes to this tag, including android:id. Then you can just do findViewById() to get a reference to the MyCompound view, just like you do with any standard view.

Freely answered 22/4, 2017 at 23:29 Comment(0)
A
-1

Guy's i think your problem is hear

TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.MyCustomView, R.attr.xyz, 0);

" R.attr.xyz " is notFound. You can see this click Hear

Adolescence answered 11/5, 2014 at 12:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.