简体   繁体   English

如何将“自定义”选项设置为“查看”

[英]How to set “custom” option to View

I'm trying to set the options in my class that extends LinearLayout , in public constructor with (Context , AttributeSet) I take attribute with TypedArray , having said that, I created a class with a method Builder and i'm setting the parameters to View with that class (in public constructor), all right if I call Builder before setContentView(..) , if I call it later I have NullPointerException . 我试图在我的类中设置扩展LinearLayout类中的选项,在带有(Context , AttributeSet)公共构造函数中,我使用TypedArray接受属性, TypedArray虽如此,我使用Builder方法创建了一个类,并将参数设置为使用该类View (在公共构造函数中),如果我在setContentView(..)之前调用Builder ,那么可以,如果以后再调用NullPointerException

Now the question is how can I change "attributes" to the View class after setting the layout to MainActivity ? 现在的问题是,在布局设置MainActivity之后,如何更改View类的“属性”?

In simple code works like this: 在简单的代码中,如下所示:

MainActivity into onCreate(..): MainActivity进入onCreate(..):

MyBuilder.set(new MyBuilder.Builder()
.setParam(...)
.setEtc(...)
.build());

setContentView(...);

MyObject obj = (MyObject) findViewById(R.id.myObject); 
//MyObject.java get param from MyBuilder.java and use it for setup MyObject

//Works!

Here is what I want: 这是我想要的:

setContentView(...);

//Do various op

MyBuilder.set(new MyBuilder.Builder()
.setParam(...)
.setEtc(...)
.build());

MyObject obj = (MyObject) findViewById(R.id.myObject);

//Params to MyObject is set after setContentView()

//With this flow I get NullPointerException in MyObject.java in reference to MyBuilder.java

Simple flow explaination as it works now: 现在可以进行简单的流程说明:

在此处输入图片说明

Here is what I want: 这是我想要的:

在此处输入图片说明

This is logcat: 这是logcat:

java.lang.RuntimeException: Unable to start activity ComponentInfo{it.michelelacorte.lib/it.michelelacorte.lib.MainActivity}: android.view.InflateException: Binary XML file line #56: Binary XML file line #56: Error inflating class it.michelelacorte.lib.MyObject
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2434)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2494)
        at android.app.ActivityThread.access$900(ActivityThread.java:157)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1356)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:5527)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
     Caused by: android.view.InflateException: Binary XML file line #56: Binary XML file line #56: Error inflating class it.michelelacorte.lib.MyObject
        at android.view.LayoutInflater.inflate(LayoutInflater.java:539)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
        at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:256)
        at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109)
        at it.michelelacorte.lib.MainActivity.onCreate(MainActivity.java:114)
        at android.app.Activity.performCreate(Activity.java:6272)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2387)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2494) 
        at android.app.ActivityThread.access$900(ActivityThread.java:157) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1356) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:148) 
        at android.app.ActivityThread.main(ActivityThread.java:5527) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620) 
     Caused by: android.view.InflateException: Binary XML file line #56: Error inflating class it.michelelacorte.lib.MyObject
        at android.view.LayoutInflater.createView(LayoutInflater.java:645)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:764)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:835)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:838)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:374) 
        at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:256) 
        at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109) 
        at it.michelelacorte.lib.MainActivity.onCreate(MainActivity.java:114) 
        at android.app.Activity.performCreate(Activity.java:6272) 
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108) 
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2387) 
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2494) 
        at android.app.ActivityThread.access$900(ActivityThread.java:157) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1356) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:148) 
        at android.app.ActivityThread.main(ActivityThread.java:5527) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620) 
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Constructor.newInstance(Native Method)
        at android.view.LayoutInflater.createView(LayoutInflater.java:619)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:764) 
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704) 
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:835) 
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) 
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:838) 
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:515) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:374) 
        at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:256) 
        at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109) 
        at it.michelelacorte.lib.MainActivity.onCreate(MainActivity.java:114) 
        at android.app.Activity.performCreate(Activity.java:6272) 
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108) 
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2387) 
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2494) 
        at android.app.ActivityThread.access$900(ActivityThread.java:157) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1356) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:148) 
        at android.app.ActivityThread.main(ActivityThread.java:5527) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620) 
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'float it.michelelacorte.lib.MyBuilder.getRadius()' on a null object reference
        at it.michelelacorte.lib.MyObject.<init>(MyObject.java:90)
        at java.lang.reflect.Constructor.newInstance(Native Method) 
        at android.view.LayoutInflater.createView(LayoutInflater.java:619) 
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:764) 
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704) 
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:835) 
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) 
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:838) 
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:515) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:374) 
        at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:256) 
        at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109) 
        at it.michelelacorte.lib.MainActivity.onCreate(MainActivity.java:114) 
        at android.app.Activity.performCreate(Activity.java:6272) 
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108) 
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2387) 
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2494) 
        at android.app.ActivityThread.access$900(ActivityThread.java:157) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1356) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:148) 
        at android.app.ActivityThread.main(ActivityThread.java:5527) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620) 

The XML resource you're setting with setContentView() contains a tag <it.michelelacorte.lib.MyObject .../> . 您使用setContentView()设置的XML资源包含标签<it.michelelacorte.lib.MyObject .../> In the constructor MyObject.<init>() you then get the instance of MyBuilder and use it to setup the layout. 然后,在构造函数MyObject.<init>() ,获取MyBuilder实例并使用它来设置布局。

But since you only initialize MyBuilder after setting the content view, you only get a null instance and thus a NullPointerException . 但是,由于仅在设置内容视图之后才初始化MyBuilder ,因此您只会得到一个null实例,从而得到一个NullPointerException

Instead create a setup method in MyObject 而是在MyObject创建设置方法

public void setup() {
    MyBuilder builder = MyBuilder.get();
    if (builder != null) {
        // setup view with builder
    } else {
        // setup view defaults
    }
}

handling this and call it as appropiate in onCreate() 处理这个并在onCreate()适当地调用它

MyObject obj = (MyObject) findViewById(R.id.myObject);
obj.setup();

and the constructor itself 和构造函数本身

public MyObject() {
    super(...);
    setup();
}

you can do it using LayoutInflater class, createView method. 您可以使用LayoutInflater类的createView方法来实现。

methods signature is createView(name, prefix, attrs) where attrs is instance of AttributeSet 方法签名是createView(name, prefix, attrs) ,其中attrsAttributeSet实例

here is some short documentation about this method, more about LinearLayout 这是有关此方法的一些简短文档, 有关LinearLayout的更多信息

  • Parameters : 参数

    • name The full name of the class to be instantiated. name要实例化的类的全名。
    • attrs The XML attributes supplied for this instance. attrs为此实例提供的XML属性。
    • prefix 字首
  • Returns : 返回值

    • View The newly instantiated view , or null. View新实例化的view ,或者为null。
  • Throws : 抛出

    • ClassNotFoundException ClassNotFoundException
    • InflateException InflateException

try to use it in this way 尝试以这种方式使用它

LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.createView(name, prefix, attrs);

you want to use it in MainActivity so i'm sure no problems occurs when you define LayoutInflater 您想在MainActivity使用它,所以我确定在定义LayoutInflater时不会发生任何问题

but if you had any problem about it, comment on this post and i'll guide you how to do that. 但是,如果您对此有任何疑问,请评论此帖子,我将指导您如何做到这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM