【问题标题】:How to instantiate and add a view object programmatically如何以编程方式实例化和添加视图对象
【发布时间】:2016-01-01 18:20:18
【问题描述】:

我正在尝试以编程方式实例化和添加视图对象

RelativeLayout activityMain = (RelativeLayout)findViewById(R.id.activity_main);
View playControlsPanelMinimized = new View(this);
activityMain.addView(playControlsPanelMinimized);

我在 log cat 中得到这个错误

Attempt to invoke virtual method 
'void android.widget.RelativeLayout.addView(android.view.View)' 
on a null object reference
at com.example.michael.musicplayer.PlayPanel.onBackPressed(PlayPanel.java:50)

这是 onBackPressed() 方法和第 50 行

@Override
public void onBackPressed() {
    super.onBackPressed();

    // some code
    );

RelativeLayout activityMain = (RelativeLayout)findViewById(R.id.activity_main);
View playControlsPanelMinimized = new View(this);
activityMain.addView(playControlsPanelMinimized); // Line # 50

}

这是activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="0dp"
    android:paddingRight="0dp"
    android:paddingTop="0dp"
    android:paddingBottom="0dp"
    tools:context=".MainActivity"
    android:id="@+id/activity_main">

    <ListView
        android:id="@+id/listView1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        />

    <RelativeLayout
        android:id="@+id/hidden_panel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/listView1">

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/app_name" />

    </RelativeLayout>

</RelativeLayout>

【问题讨论】:

  • R.id.activity_main 是布局,而不是视图,因此您的 findViewById(R.id.activity_main); 将返回 null。您必须改用布局膨胀。
  • @the_pole 好吧,我的错。如果我们膨胀了布局,那么我们可以使用 findViewById 来获取它。
  • 如果你的布局被夸大了,那么你应该没问题。您是否尝试将 mainActivity 声明为类私有变量并在您的 onCreate() 方法中而不是在 onBackPressed 事件中实例化它?
  • 我猜不是。我已经创建了一个测试项目,并且可以随时向其中添加新元素。
  • 我发布的代码没有出错。新视图已成功添加到主要活动中

标签: android


【解决方案1】:

请记住,在使用 findViewById() 之前,您要引用的视图必须已经充气...使用 setContentView() 或使用 Inflater 手动充气。否则你只会得到一个空返回,这就是 NPE 的原因

【讨论】:

  • 你能给我一个具体的链接,我从那里了解为什么要这样做?我真的不明白膨胀和它的需要
  • udacity 解释得很好......你必须膨胀它们以在你的活动的视图层次结构中注册你的视图和视图容器。如果你还没有膨胀你的 activityMain 布局(顺便说一句坏名),那么这个方法就不会简单地说。所以需要膨胀来从 xml 创建一个对象并获取对它的引用......或者只是在代码中创建你的对象,但是你必须手动处理它的初始化而不是依赖于 xml 属性......这意味着更多的代码和更多的手工......
【解决方案2】:

'void android.widget.RelativeLayout.addView(android.view.View)' 在空对象引用上

检查activityMain 是否为空

有点像

RelativeLayout activityMain = (RelativeLayout)findViewById(R.id.activity_main);
View playControlsPanelMinimized = new View(this);
if(activityMain != null)
    activityMain.addView(playControlsPanelMinimized); // Line # 50

如果activityMain 为空,可能你忘了给视图充气。

你可以在片段中做

@Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    final View rootView = inflater.inflate(R.layout.name_of_your_fragment, container, false);

    //Some code like
    //rootView.findViewById(...);

    return rootView;
}

【讨论】:

  • 所以你没有膨胀视图。用一个例子检查编辑。
  • 是的,但是您仍然会得到空指针,并且它不会按照您的意愿执行,请查看我的答案和评论部分。从 xml 理解通货膨胀和构建视图对于 android 开发者来说是必不可少的
猜你喜欢
  • 1970-01-01
  • 2022-12-23
  • 1970-01-01
  • 2011-02-26
  • 2014-01-26
  • 1970-01-01
  • 2016-09-19
  • 1970-01-01
相关资源
最近更新 更多