繁体   English   中英

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

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

我试图在我的类中设置扩展LinearLayout类中的选项,在带有(Context , AttributeSet)公共构造函数中,我使用TypedArray接受属性, TypedArray虽如此,我使用Builder方法创建了一个类,并将参数设置为使用该类View (在公共构造函数中),如果我在setContentView(..)之前调用Builder ,那么可以,如果以后再调用NullPointerException

现在的问题是,在布局设置MainActivity之后,如何更改View类的“属性”?

在简单的代码中,如下所示:

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!

这是我想要的:

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

现在可以进行简单的流程说明:

在此处输入图片说明

这是我想要的:

在此处输入图片说明

这是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) 

您使用setContentView()设置的XML资源包含标签<it.michelelacorte.lib.MyObject .../> 然后,在构造函数MyObject.<init>() ,获取MyBuilder实例并使用它来设置布局。

但是,由于仅在设置内容视图之后才初始化MyBuilder ,因此您只会得到一个null实例,从而得到一个NullPointerException

而是在MyObject创建设置方法

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

处理这个并在onCreate()适当地调用它

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

和构造函数本身

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

您可以使用LayoutInflater类的createView方法来实现。

方法签名是createView(name, prefix, attrs) ,其中attrsAttributeSet实例

这是有关此方法的一些简短文档, 有关LinearLayout的更多信息

  • 参数

    • name要实例化的类的全名。
    • attrs为此实例提供的XML属性。
    • 字首
  • 返回值

    • View新实例化的view ,或者为null。
  • 抛出

    • ClassNotFoundException
    • InflateException

尝试以这种方式使用它

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

您想在MainActivity使用它,所以我确定在定义LayoutInflater时不会发生任何问题

但是,如果您对此有任何疑问,请评论此帖子,我将指导您如何做到这一点。

暂无
暂无

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

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