android中的listview嵌入webview和button导致nullpointer的问题

glocalor 2015-04-08 11:17:55
我在编写一个listview中需要嵌入webview的activity时,发生了一个很奇怪的现象;首先,listview中每个子视图有两个控件,一个button和一个webview;
当不点击webview控件,点击button,能够正确响应,但是当点击webview控件后,再点击button控件,却会报出nullpointer的错误;具体的错误方式体现为,当更新数据后,调用notifyDataSetChanged(),从而重新调用getview方法,由于convertView已经存在,所以会执行else中的代码,而执行第一行代码convertView.getTag(),返回的结果却为null,从而导致了失败,不知道该如何解决这个问题。
我理解的是点击了webview之后,重新调用getView方法时,此时的convertView已经不再是listview的那个子视图了,求高手帮忙解决这个问题。
具体代码如下:
首先是xml文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="@+id/btn_count"
android:layout_width="65dp"
android:layout_height="30dp"
android:layout_marginLeft="10dp"
android:background="@color/purple"
android:text="@string/count"
android:textColor="#ffffff"
/>
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="15sp"
android:layout_marginLeft="10dp"
android:layout_below="@id/btn_count"/>

</RelativeLayout>


然后是listview对应的自定义adapter的getview方法:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
final MyLIstViewData mydata= myList.get(position);
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
final int listpos=position;
convertView = mInflater.inflate(R.layout.activity_display,null);
WebView webView = (WebView) convertView.findViewById(R.id.webView);
TextView dateauthorCtrl=(TextView)convertView.findViewById(R.id.tv_date_author);
String url ="http:baidu.com";
webView.loadUrl(url);
webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// TODO Auto-generated method stub
//返回值是true的时候控制去WebView打开,为false调用系统浏览器或第三方浏览器
view.loadUrl(url);
return true;
}
});

holder.count=(Button)convertView.findViewById(R.id.btn_count);
convertView.setTag(holder);

holder.count.setOnClickListener(new OnClickListener(){

@Override
public void onClick(View v) {
//改变MyLIstViewData数组的操作
}
});

}else {
holder = (ViewHolder) convertView.getTag();
holder.count.setText("counted");
}
}

...全文
516 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
glocalor 2015-04-20
  • 打赏
  • 举报
回复
@山鹰1985 373380580
glocalor 2015-04-19
  • 打赏
  • 举报
回复
@山鹰1985
glocalor 2015-04-19
  • 打赏
  • 举报
回复

这就是我想实现的样式,如果点击了webview,再点击button,就会报错;,不点击webview,只点击button就不会报错
山鹰1985 2015-04-19
  • 打赏
  • 举报
回复
我先洗衣服,呵呵。
山鹰1985 2015-04-19
  • 打赏
  • 举报
回复
你QQ多少,我加你。
山鹰1985 2015-04-17
  • 打赏
  • 举报
回复
把你想实现的效果,用张图描述下。
山鹰1985 2015-04-17
  • 打赏
  • 举报
回复
说下你的需求,想实现什么效果,按你上面说的,把webView放进Holder也会出错的话,那么出的错应该是不一样的,贴上来看看。
glocalor 2015-04-17
  • 打赏
  • 举报
回复
@山鹰1985 我不是太明白你说的意思,现在的现象是这样的,点击WebView时,没有触发getView方法,所以并不涉及走if路线;而当我在点击了WebView之后,再点击button,就会触发getView走else路线,此时执行holder = (ViewHolder) convertView.getTag();得到的holder = null;导致了报错;另外将webview放入holder中也没有用,还是报错,现象一样
山鹰1985 2015-04-16
  • 打赏
  • 举报
回复
补充:你点击WebView时,convertView == null,所以走if路线,而再点击button时,走else路线,而在if路线中没有convertView.getTag(),所以,系统给你报了空指针,简单的说,就是你的if里面没有再次给你创建一个button,因为button在ViewHolder里面,要用convertView.getTag()去获取。
山鹰1985 2015-04-16
  • 打赏
  • 举报
回复
你把WebView放进ViewHolder里面试试。
glocalor 2015-04-15
  • 打赏
  • 举报
回复
@山鹰1985 如果点击webview,然后点击button,会报错,不点击webview,点击button就不会报错
glocalor 2015-04-15
  • 打赏
  • 举报
回复
@山鹰1985
glocalor 2015-04-15
  • 打赏
  • 举报
回复
引用 1 楼 u012137924 的回复:
http://download.csdn.net/detail/u012137924/8412899 这是我以前回答问题时写的小DEMO,你可以去看看,你的问题出在软引用上面,简单的说,你的Button和你的WebView不一样,因为你的Button是ViewHolder类的成员变量,而当适配器中的getView方法调用时,首先判断convertView是否为空,如果为空,那么holder = new ViewHolder();这一行会new一个ViewHolder也就是说会给他在堆空间中分配一块内存,当这块内存没有使用的时候,系统并不会马上回收这块内存,所以,当再次调用ViewHolder中的Button时,系统会根据tag来找这块内存,然后使用,所以,你的Button没有报空指针,而WebView却报了空指针,因为你的WebView使用的内存被回收了,他没有使用软引用的方式,而是使用的栈中的空间,再简单点说,你在if中声明的WebView第一次调用完后,就会被系统销毁,所以,再次调用的时候就会报空指针了,因为他已经被销毁,再也找不到了。
不好意思,这个问题的现象是如果我点击了WebView,从debug来看,此时并未报空指针,而是在我点击了button,重新回到了getView方法中,此时由于convertView已存在,调用else中的方法,发生了convertView.getTag()返回的结果却为null的现象,报空指针的应该是ViewHolder的对象,因为它为null,但我还在使用它
budworm 2015-04-10
  • 打赏
  • 举报
回复
简单的说,你的Button和你的WebView不一样,因为你的Button是ViewHolder类的成员变量,而当适配器中的getView方法调用时,首先判断convertView是否为空,如果为空,那么holder = new ViewHolder();这一行会new一个ViewHolder也就是说会给他在堆空间中分配一块内存,当这块内存没有使用的时候,系统并不会马上回收这块内存,所以,当再次调用ViewHolder中的Button时,系统会根据tag来找这块内存,然后使用,所以,你的Button没有报空指针,而WebView却报了空指针,因为你的WebView使用的内存被回收了,他没有使用软引用的方式,而是使用的栈中的空间,再简单点说,你在if中声明的WebView第一次调用完后,就会被系统销毁,所以,再次调用的时候就会报空指针了,因为他已经被销毁,再也找不到了。
雪月弦歌 2015-04-10
  • 打赏
  • 举报
回复
你把ViewHolder放到全局变量,webview没有方法ViewHolder里面吗?你在getview方法里面改成holder.webview=......再试试
山鹰1985 2015-04-10
  • 打赏
  • 举报
回复
楼上的真会偷懒和偷巧,呵呵。
山鹰1985 2015-04-09
  • 打赏
  • 举报
回复
http://download.csdn.net/detail/u012137924/8412899 这是我以前回答问题时写的小DEMO,你可以去看看,你的问题出在软引用上面,简单的说,你的Button和你的WebView不一样,因为你的Button是ViewHolder类的成员变量,而当适配器中的getView方法调用时,首先判断convertView是否为空,如果为空,那么holder = new ViewHolder();这一行会new一个ViewHolder也就是说会给他在堆空间中分配一块内存,当这块内存没有使用的时候,系统并不会马上回收这块内存,所以,当再次调用ViewHolder中的Button时,系统会根据tag来找这块内存,然后使用,所以,你的Button没有报空指针,而WebView却报了空指针,因为你的WebView使用的内存被回收了,他没有使用软引用的方式,而是使用的栈中的空间,再简单点说,你在if中声明的WebView第一次调用完后,就会被系统销毁,所以,再次调用的时候就会报空指针了,因为他已经被销毁,再也找不到了。

80,349

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧