【问题标题】:Null Pointer Exception for LayoutInflater inflater and ViewGroup containerLayoutInflater inflater 和 ViewGroup 容器的空指针异常
【发布时间】:2016-08-27 21:23:58
【问题描述】:

我正在制作一个应用程序,每次用户执行某个操作时都会创建一个 ImageButton。所以我的按钮创建是动态的。

我在 FRAGMENT 类中有一个方法 (createButton),它传递了一个图像(用作我的 ImageButton 的背景)。

我的问题是我似乎需要使用“LayoutInflater inflate”和“ViewGroup container”来打开我的相对布局视图并为其添加一个动态按钮,但我也在传递一个图像这个方法,所以我的方法迫使我初始化充气和容器。

我无法将它们初始化为 null,因为当我运行我的应用程序时会收到 NullPointerException。我也尝试从 onCreateView 传递它们(如下面的代码),但我仍然得到 NullPointerException。 如何使用 LayoutInflater inflate 和 ViewGroup 容器(不将它们初始化为 null),同时仍将其他变量传递给我的方法。我在打印“tag-name: rLayout”之前抛出异常。

public class HomeFragment extends Fragment {

ViewGroup rootContainer;
LayoutInflater rootInflater;




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

}

// onCreateView
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.home_fragment, container, false);


    rootContainer = container;

    rootInflater = inflater;

    return view;
}



// Create button from icon and image name

public void createButton (BitmapDrawable bitmapdrawable, String applicationName){

    Log.d("tag_name", "createButton");

    //LayoutInflater inflater = (LayoutInflater)getContext().getSystemService
            //(Context.LAYOUT_INFLATER_SERVICE);

    try {


        Log.d("tag_name", "Try_2");

        // Get Layout home_fragment
        View rootView = rootInflater.inflate(R.layout.home_fragment, rootContainer, false);
        RelativeLayout rLayout = (RelativeLayout) rootView.findViewById(R.id.home_fragment);
        Log.d("tag_name", "rLayout");

        // create image button with background as bitmapdrawable
        ImageButton btn = new ImageButton(getActivity());
        btn.setImageDrawable(bitmapdrawable);
        int id = 1;
        btn.setId(id);
        Log.d("tag_name", "set the ID of the btn");

        // create textview with applicationName
        //TextView appName = new TextView(getActivity());
        //appName.setText(applicationName);

        // place new button next to existing button
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.WRAP_CONTENT,
                RelativeLayout.LayoutParams.WRAP_CONTENT);


        params.addRule(RelativeLayout.RIGHT_OF, id);
        btn.setLayoutParams(params);

        // place text under newly created button


        // Put button and text in layout
        rLayout.addView(btn);
        //rLayout.addView(appName);
    }

    catch (Exception e){

        System.out.println("Exception is "+e.toString());
    }

}

}

这是我的堆栈跟踪:

05-03 14:33:42.468 7197-7223/it.anddev.bradipao.janus D/tag_name: createButton
05-03 14:33:42.468 7197-7223/it.anddev.bradipao.janus D/tag_name: Try_2
05-03 14:33:42.468 7197-7223/it.anddev.bradipao.janus I/System.out: Exception is java.lang.NullPointerException
05-03 14:33:42.468 7197-7223/it.anddev.bradipao.janus W/System.err: java.lang.NullPointerException
05-03 14:33:42.468 7197-7223/it.anddev.bradipao.janus W/System.err:     at it.anddev.bradipao.janus.HomeFragment.createButton(HomeFragment.java:118)
05-03 14:33:42.468 7197-7223/it.anddev.bradipao.janus W/System.err:     at it.anddev.bradipao.janus.MainActivity$1.run(MainActivity.java:155)

HomeFragment 中的第 118 行就是这一行:

View rootView = rootInflater.inflate(R.layout.home_fragment, rootContainer, false);

mainActivity 中的第 155 行是我将变量传递给 HomeFragment 的第二行:

HomeFragment createbutton = new HomeFragment();
createbutton.createButton(bitmapdrawable, applicationName);

【问题讨论】:

  • 我不明白为什么还要通过充气机和容器?您的方法接受 BitmapDrawable,不需要传递其他两个变量,您已经在 createButton 中声明了充气机。也不需要contdainer,可以使用null。
  • @varunkr 当我将容器设为空时(就像我在发布的代码中所做的那样),我得到一个异常抛出“NullPointerException”。
  • 我认为不应抛出空指针,尽管在容器中传递空值并不总是一件好事。由于所有这些都发生在片段内,您可以尝试将片段的根作为容器传递。应该工作!
  • @varunkr 将片段的根作为容器传递是什么意思?
  • 您必须在片段中覆盖 onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) ,对吗?只需使用此处的容器值,此容器定义片段的根。看看这是否有效,我不是 100% 确定,但我认为它应该有效

标签: java android variables initialization parameter-passing


【解决方案1】:

问题在于您创建片段并在其上调用 createButton 方法的方式

HomeFragment createbutton = new HomeFragment();
createbutton.createButton(bitmapdrawable, applicationName);

你不能这样做。 Android 中的所有活动、片段和服务都必须经历各自的生命周期,以便它们具有附加的有效上下文。

通过将它们视为普通的 Java 类,您最终会得到一个空上下文。由于 Activity、Fragment 或服务中的大多数方法都是在其 Context 上调用的,因此您会收到空指针异常,这就是您的应用崩溃的原因。

你需要什么!!

FragmentTransaction fragmentTransaction = getSupportFragmentManager()
        .beginTransaction();
Fragment profileFragment = new HomeFragment();//the fragment you want to show
fragmentTransaction
        .add(R.id.parent, profileFragment);//R.id.content_frame is the layout you want to replace
fragmentTransaction.commit();

这就是您创建片段的方式。

为了调用它的 createButton 方法,你需要一个接口。

您需要在 Fragment 中创建一个这样的界面

public interface ButtonCreator{
    void buttonCreator(BitmapDrawable bitmapDrawable, String string);
}

在您的活动中,您将需要实现此方法。像这样:

@Override
public void buttonCreator(BitmapDrawable bitmap,String a) {
    HomeFragment homeFragment = (HomeFragment)getSupportFragmentManager().getFragments().get(1);
    homeFragment.createButton(bitmap,a);
}

别忘了实现这样的接口

public class MainActivity extends FragmentActivity implements MenuFragment.OnMenufragListener, HomeFragment.ButtonCreator {

同样在你的片段中,你必须在你的 onAttach 方法中得到它

private ButtonCreator bc;

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    bc = (ButtonCreator) activity;
}

你会打电话的

buttonCreator(bitmapdrawable, applicationName);

代替

createbutton.createButton(bitmapdrawable, applicationName);

这会奏效。但是,我在您的按钮实现中也看到了一个错误。

你必须调查一下。

  btn.setId(id);

上面的行需要像 R.id.something 这样的 id,而不是整数。我相信你会解决这个问题的。

【讨论】:

  • 我真的希望这能奏效,因为当我浏览互联网时,我已经看到它对其他人有用,但我仍然收到 NullPointerException。我已经更新了我的问题以显示我的所有代码。
  • 您能否也发布您的堆栈跟踪,这会很有帮助,现在如何抛出空指针很奇怪!
  • RRRRGGG,现在我在 createButton 方法中的 rLayout.addView(btn) 处收到 NullPointerException...
猜你喜欢
  • 1970-01-01
  • 2013-12-19
  • 1970-01-01
  • 1970-01-01
  • 2011-08-07
  • 1970-01-01
  • 2015-07-12
相关资源
最近更新 更多