摘要:

加载Android布局文件时出现错误:
java.lang.NullPointerException: Attempt to invoke virtual method '........' on a null object reference
出错原因可能是未能在正确的View环境下使用findViewById()方法。


Android新手,啥都不懂。

做了一个ListView,想实现功能:点击Item,弹出一个对话框,对话框中包含一个ImageView,代码如下:


ImageView photo;Bitmap bitmap = BitmapFactory.decodeStream(        getContext().getContentResolver().openInputStream(uri));ImageView photo = getView().findViewById(R.id.photo);photo.setImageBitmap(bitmap);AlertDialog.Builder builder = new AlertDialog.Builder(getContext());builder.setView(R.id.dialog);/*定义其他按键*/AlertDialog dialog = builder.create();dialog.show();

为对话框新建了一个Layout布局文件,这个R.id.photo就放在这个文件中。

然而运行时老是报错:

java.lang.NullPointerException: Attempt to invoke virtual method '........' on a null object reference

问题的原因是photo没有正确初始化。

想了一下,明明我都关联好了,编译也没问题,应该能正确初始化的。

然后想到了findViewById()的原理,之前都是乱拿来用的。通过这个错误我意识到可能是findViewById()设置不当。

一般用findViewById()都是在Activity的OnCreate()方法里面,例如:


button = (Button)findViewById(R.id.button);

其中(Button)可以省略。

这里的findViewById()函数来自于Activity类:

public  T findViewById(@IdRes int id) {        return getWindow().findViewById(id);    }
我们在Fragment中使用findViewById()时候,需要创建Fragment的View对象,然后调用View对象的findViewById()方法。

View v = inflater.inflate(R.layout.fragment, container, false);listView = v.findViewById(R.id.list_view);

其中View类中findViewById()方法如下:

@Nullable    public final  T findViewById(@IdRes int id) {        if (id == NO_ID) {            return null;        }        return findViewTraversal(id);    }
具体我就不研究了,(反正我的水平也搞不懂)

我出现上面错误的原因就是没有搞清楚该用哪一个findViewById()。因为调用getView()得到的应该是当前显示的View,而我这里要显示的是一个Dialog对话框专用的新的布局文件,因此不能用当前的View对象来初始化ImageView。

解决办法就是新建一个类继承Dialog类,在该类中定义要显示的元素,并且重新OnCreate()方法:

protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        LayoutInflater inflater = (LayoutInflater) mContext                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);        View layout = inflater.inflate(R.layout.photo_dialog, null);        photo = layout.findViewById(R.id.photo);        try{            Bitmap bitmap = BitmapFactory.decodeStream(                    getContext().getContentResolver().openInputStream(uri));            photo.setImageBitmap(bitmap);        }catch (Exception e){            e.printStackTrace();        }        this.setContentView(layout);    }}

原来的Fragment中只需要简单的两句:

MyDialog myDialog = new MyDialog(getContext());myDialog.show();

总之就是要创建一个复杂的Dialog,最好重写Dialog方法,别把乱七八糟的东西都挤到原来的类里。

作为一个初学者,有时候吧,想把代码写得OOP一点,但是看到别人的优秀代码,感觉其实要不要解耦不取决于代码的长短,而取决于具体的功能实现是否需要,这个还是需要经验的积累吧。

这么简单的问题搞了一下午,真的是被自己蠢哭了。


更多相关文章

  1. Android一键锁屏代码
  2. 【Android】adapter has changed解决方法
  3. android中控件点击两次才响应onclick方法
  4. android彻底结束进程的两种方法
  5. Android截屏实现——亲测有效代码
  6. android和html交互--动态注入方法
  7. [置顶] Android SDK中的例子的源代码

随机推荐

  1. Android ApiDemos示例解析(140):Views->L
  2. Android 小的知识片
  3. 取消自动获取焦点(默认进来焦点到edittex
  4. android设置textview限制字数以省略号显
  5. android ListView嵌套checkbox并取代chec
  6. CheckBox组件的熟悉
  7. Android架构分析之Android开发环境搭建
  8. android 默认应用安装在sd卡中 (>2.2)
  9. android 5.0 默认水波纹背景属性,可设置
  10. android中gallery的使用