以编程方式向布局添加按钮

34

我在将按钮添加到我在XML中创建的布局时遇到了问题。这是我的目标:

//some class
else {
        startActivity(new Intent(StatisticsScreen.this, ScreenTemperature.class));
}
////

//ScreenTemperatureClass
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //this is where I call another class that
    //displays a nice graph
    setContentView(new GraphTemperature(getApplicationContext()));

}
我想在这个新屏幕上添加一个按钮,以便它出现在图形下方。 我尝试创建一个 LinearLayout 视图,然后创建一个按钮并将其添加到此视图中,但我只收到 NullPointerException。 任何帮助将不胜感激。谢谢。
EDIT#1 以下是我尝试过的可能导致 NullPointerException 和“强制关闭”的代码:
Button buybutton;
LinearLayout layout;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(new GraphTemperature(getApplicationContext()));

    layout = (LinearLayout) findViewById(R.id.statsviewlayout);
    Button buyButton = new Button(this);
    buyButton.setText(R.string.button_back);
    buyButton.setLayoutParams(new LayoutParams(
        ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT));
    layout.addView(buyButton);

}

这里是logcat错误信息:

ERROR/AndroidRuntime(293): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.weatherapp/com.weatherapp.ScreenTemperature}: java.lang.NullPointerException
ERROR/AndroidRuntime(293):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
ERROR/AndroidRuntime(293):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
ERROR/AndroidRuntime(293):     at android.app.ActivityThread.access$2300(ActivityThread.java:125)
ERROR/AndroidRuntime(293):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)

显然在logcat中还有更多与此错误相关的行,不知道您是否需要这些内容?

编辑#2

所以我尝试了bhups的方法:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    GraphTemperature GT = new GraphTemperature(getApplicationContext());             
    layout = (LinearLayout) findViewById(R.id.statsviewlayout);
    Button buyButton = new Button(this);
    buyButton.setText(R.string.button_back);
    buyButton.setLayoutParams(new LayoutParams(
        ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT));
    layout.addView(GT); // line 27
    layout.addView(buyButton);       
    setContentView(layout);           
}

使用这种方法时,产生了与上面相同的logcat错误NullPointerException,表明问题与第27行代码有关,即layout.addView代码行。 有什么想法吗?再次感谢


1
展示你尝试过的内容和运行时获取的logcat,这样我们可以找出为什么会出现npe。无论如何,请考虑创建一个screen_temperature.xml布局并在setContentView()中使用它。你可以在xml中通过指定整个包而不仅仅是名称来添加自定义视图(例如:<my.package.MyCustomView android:id.../>)。 - bigstones
创建一个线性布局(ll),并将GraphTemp视图对象和按钮对象添加到ll中。然后将活动的内容视图设置为ll。即setContentView(ll); - bhups
2个回答

34

如果你只是在setContentView中的onCreate()方法开头包含了一个布局文件,并且想要在编程时添加新元素到这个布局文件中,那么可以尝试以下方法:

ViewGroup linearLayout = (ViewGroup) findViewById(R.id.linearLayoutID);

然后您可以创建一个新的Button,并将其添加:

Button bt = new Button(this);
bt.setText("A Button");
bt.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, 
                                    LayoutParams.WRAP_CONTENT));
linerLayout.addView(bt);

4
FILL_PARENT 已经过时,从API Level 8开始被重命名为MATCH_PARENT。请注意更新使用。 - GregD

32

这一行:

layout = (LinearLayout) findViewById(R.id.statsviewlayout);

在您当前的“contentview”中查找“statsviewlayout”id。现在您已经在这里设置了它:

setContentView(new GraphTemperature(getApplicationContext()));

我猜测新的"graphTemperature"并没有为该id设置任何内容。

认为你可以使用findViewById找到任何视图是一个常见的错误。你只能找到在XML中(或者由代码指定并给予id)的视图。

空指针异常将被抛出,因为你正在查找的布局未被找到,所以...

layout.addView(buyButton);

抛出该异常。

补充: 现在如果你想从XML中获取该视图,应该使用一个inflater:

layout = (LinearLayout) View.inflate(this, R.layout.yourXMLYouWantToLoad, null);

假设你有一个名为"yourXMLYouWantToLoad.xml"的文件中包含了LinearLayout布局


你能看一下我的第二次编辑吗?我几乎是在你发布这个答案的同时发布的。我不太确定我是否理解了。如果你问的是那个布局“statsviewlayout”是否在xml中声明,那么是的。 - mmmbaileys
你似乎仍在这样做:layout = (LinearLayout) findViewById(R.id.statsviewlayout); 只要你当前屏幕上的视图(你在 setcontentview 中设置的东西)不包含此 ID,你就不能这样做。只要包含“statsviewlayout”的 XML 没有使用 setcontentview 设置,'findviewbyid就会返回null`。 - Nanne
哈哈,看起来我们在彼此的修订/添加之间进行评论/阅读 ;) - Nanne
你可以用ScrollView将整个部分包围起来。但是为了检查你的按钮是否存在,也许可以使用层次结构查看器进行检查和测试?http://developer.android.com/guide/developing/tools/hierarchy-viewer.html - Nanne
如果您认为我的回答有帮助,请毫不犹豫地点击漂亮、绿色的“接受”复选框,没有任何问题。 - Nanne
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接