如何设置" custom"查看选项

时间:2016-01-25 21:10:26

标签: java android android-linearlayout android-view

我试图在我的类中设置扩展LinearLayout的选项,在公共构造函数中设置(Context , AttributeSet)我将属性设置为TypedArray,说完了,我创建了一个使用方法Builder的类,并且我将该参数设置为View与该类(在公共构造函数中),如果我在Builder之前调用setContentView(..),则可以,如果我稍后再打电话给我NullPointerException

现在的问题是如何改变"属性"在设置布局为View之后到MainActivity课程?

简单的代码就像这样:

将onAreate(..)的MainActivity:

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

简单的流程解释,因为它现在有效:

enter image description here

这就是我想要的:

enter image description here

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

2 个答案:

答案 0 :(得分:1)

您使用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();
}

答案 1 :(得分:0)

您可以使用LayoutInflatercreateView方法执行此操作。

方法签名为createView(name, prefix, attrs),其中attrsAttributeSet

的实例

这里有一些关于这种方法的简短文档, more about LinearLayout

  • <强>参数

    • name要实例化的类的全名。
    • attrs为此实例提供的XML属性。
    • 前缀
  • 退货

    • 查看新实例化的view或null。
  • <强>抛出

    • ClassNotFoundException的
    • InflateException

尝试以这种方式使用它

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

你想在MainActivity中使用它,所以我确定定义LayoutInflater

时不会出现问题

但如果您对此有任何疑问,请对此帖发表评论,我将指导您如何操作。