[英]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)
,其中attrs
是AttributeSet
实例
这是有关此方法的一些简短文档, 有关LinearLayout的更多信息
参数 :
返回值 :
view
,或者为null。 抛出 :
尝试以这种方式使用它
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.createView(name, prefix, attrs);
您想在MainActivity
使用它,所以我确定在定义LayoutInflater
时不会发生任何问题
但是,如果您对此有任何疑问,请评论此帖子,我将指导您如何做到这一点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.