listview自己制造bug分析如何解决
2017-07-28 11:06
316 查看
网上很多listview加载不同的布局 采用getItemViewType 方式行不通 也不知道他们怎么写的blog.能先自己用一下在发表吗 复制粘贴的东西 不自己分析对错,就这么用吗?
采用所有类型整合到一个item中控制布局显示隐藏的方式,虽然维护不方便,但至少不会出错。
我为了测试,使用了pulltorefreshlistview ,我的blog有讲。
错误源代码:
当然 熟悉的同学一眼就看出问题所在,如果你忘了那么办呢?
报错处
我们一看 空指针 果断debug,debug是遇到任何问题都首先想到的。
进入了else{
viewHolder_one = (ViewHolder_One) view.getTag();
}
然后执行
对应type
报的空指针
那么至此问题定位就明确了
viewHolder_one 出问题了
我们在看viewholder代码发现没有setTag.添上再运行 很流畅。
那么没有tag为什么会报错呢 第一屏为什么没有报错呢?
涉及到listview复用机制
listview 为了达到优化目的 使用了复用机制 其实第一屏都是 执行view == null 判断 都是重新加载布局 第二屏开始慢慢移除旧的 此时 view不再为空 所以会重用tag中的内容,类似于日历表 可以上下滑动 但是 中间显示就一个 也就是容量有限 不用的就回收。
采用所有类型整合到一个item中控制布局显示隐藏的方式,虽然维护不方便,但至少不会出错。
我为了测试,使用了pulltorefreshlistview ,我的blog有讲。
错误源代码:
public class MainActivity extends AppCompatActivity { PullToRefreshListView listView; ImageView imageView; MyAdapter mAdapter; List<MDTO> list = new ArrayList<>(); protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageView = (ImageView) findViewById(R.id.iv); imageView.setImageResource(R.drawable.proxyimg); //控件 listView = (PullToRefreshListView) findViewById(R.id.listview); for (int i = 0; i < 50; i++) { MDTO mdto = new MDTO(); mdto.setId(R.drawable.ic_launcher); mdto.setText("text" + i); mdto.setType(i % 3); list.add(mdto); } mAdapter = new MyAdapter(list); listView.setAdapter(mAdapter); //控件模式 listView.setMode(PullToRefreshBase.Mode.PULL_FROM_START); //控件滚动行为 listView.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView absListView, int i) { } @Override public void onScroll(AbsListView absListView, int i, int i1, int i2) { } }); //控件刷新行为 listView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener<ListView>() { @Override public void onRefresh(PullToRefreshBase<ListView> refreshView) { } }); } class MyAdapter extends BaseAdapter { List<MDTO> mList = new ArrayList<>(); MyAdapter(List<MDTO> mdtoList) { mList.clear(); this.mList.addAll(mdtoList); for (int i = 0; i < mList.size(); i++) { Log.i("id", mList.get(i).getId() + ""); Log.i("type", mList.get(i).getType() + ""); } notifyDataSetChanged(); } @Override public int getCount() { return mList.size(); } @Override public Object getItem(int i) { return mList.get(i); } @Override public long getItemId(int i) { return i; } @Override public View getView(int i, View view, ViewGroup viewGroup) { int type = mList.get(i).getType(); ViewHolder_One viewHolder_one; if (view == null) { view = LayoutInflater.from(MainActivity.this).inflate(R.layout.item_one, null); viewHolder_one = new ViewHolder_One(); viewHolder_one.iv = (ImageView) view.findViewById(R.id.one_iv); viewHolder_one.tv = (TextView) view.findViewById(R.id.one_tv); } else { viewHolder_one = (ViewHolder_One) view.getTag(); } if (type == 0) { viewHolder_one.iv.setVisibility(View.VISIBLE); viewHolder_one.tv.setVisibility(View.VISIBLE); viewHolder_one.iv.setImageResource(mList.get(i).getId()); viewHolder_one.tv.setText(mList.get(i).getText()); view.setBackgroundColor(Color.RED); } else if (type == 1) { viewHolder_one.tv.setVisibility(View.VISIBLE); viewHolder_one.iv.setVisibility(View.GONE); viewHolder_one.tv.setText(mList.get(i).getText()); view.setBackgroundColor(Color.BLUE); } else { viewHolder_one.iv.setVisibility(View.VISIBLE); viewHolder_one.tv.setVisibility(View.GONE); viewHolder_one.iv.setImageResource(mList.get(i).getId()); view.setBackgroundColor(Color.WHITE); } return view; } class ViewHolder_One { TextView tv; ImageView iv; } } }
当然 熟悉的同学一眼就看出问题所在,如果你忘了那么办呢?
报错处
java.lang.NullPointerException: Attempt to read from field 'android.widget.TextView com.lcldream.www.MainActivity$MyAdapter$ViewHolder_One.tv' on a null object reference at com.lcldream.www.MainActivity$MyAdapter.getView(MainActivity.java:141) at android.widget.HeaderViewListAdapter.getView(HeaderViewListAdapter.java:220) at android.widget.AbsListView.obtainView(AbsListView.java:2575) at android.widget.ListView.makeAndAddView(ListView.java:1956) at android.widget.ListView.fillDown(ListView.java:757) at android.widget.ListView.fillGap(ListView.java:721) at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5733) at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3780) at android.widget.AbsListView.onTouchMove(AbsListView.java:4277) at android.widget.AbsListView.onTouchEvent(AbsListView.java:4052) at android.widget.ListView.onTouchEvent(ListView.java:4287) at android.view.View.dispatchTouchEvent(View.java:8677) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2517) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2161) at com.handmark.pulltorefresh.library.PullToRefreshListView$InternalListView.dispatchTouchEvent(PullToRefreshListView.java:312) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2523) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2175) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2523) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2175) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2523) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2175) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2523) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2175) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2523) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2175) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2523) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2175) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2523) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2175) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2523) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2175) at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2539) at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1807) at android.app.Activity.dispatchTouchEvent(Activity.java:2823) at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:71) at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2496) at android.view.View.dispatchPointerEvent(View.java:8883) at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4779) at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4611) at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4087) at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4140) at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4106) at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4243) at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4114) at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4300) at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4087) at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4140) at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4106) at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4114) at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4087) at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6598) at a
我们一看 空指针 果断debug,debug是遇到任何问题都首先想到的。
进入了else{
viewHolder_one = (ViewHolder_One) view.getTag();
}
然后执行
对应type
报的空指针
那么至此问题定位就明确了
viewHolder_one 出问题了
我们在看viewholder代码发现没有setTag.添上再运行 很流畅。
那么没有tag为什么会报错呢 第一屏为什么没有报错呢?
涉及到listview复用机制
listview 为了达到优化目的 使用了复用机制 其实第一屏都是 执行view == null 判断 都是重新加载布局 第二屏开始慢慢移除旧的 此时 view不再为空 所以会重用tag中的内容,类似于日历表 可以上下滑动 但是 中间显示就一个 也就是容量有限 不用的就回收。
相关文章推荐
- 如何搜索到能解决自己的bug的方法
- 如何解决asp.net 在vs2010(.net framework 4.0)中listview控件用jquery,javascript为模版中的服务端控件注入事件的方法?因为vs2010在这个方面有存在的bug!
- 制造企业如何控制库存的分析
- [置顶] 从一个bug教你如何分析Android系统代码
- Android的ListView异步加载图片时,错位、重复、闪烁问题的分析及解决方法
- 如何分析解决COM接口IFileOperation的hook去支持vista、win7、win8、win10 x86 x64系统
- 如何分析解决Android ANR
- 从ffmpeg源代码分析如何解决ffmpeg编码的延迟问题
- ListView嵌套卡顿问题分析及解决
- 如何分析解决Android ANR
- 如何分析解决Android ANR
- Heritrix源码分析(十一) Heritrix中的URL--CandidateURI和CrawlURI以及如何增加自己的属性(转)
- 如何分析解决Android ANR .
- 浅谈ANR及如何分析解决ANR(2)
- oracle 10g 数据如何导入到oracle 9i时BUG解决方法
- android listview 连续调用 getview问题分析及解决。
- 如何解决ScrollView嵌套ListView的冲突(一)
- jQuery源码分析:如何解决jQuery、$关键字与其它脚本框架的冲突问题?
- ztree获取选中节点时不能进入可视区域出现BUG如何解决
- 如何解决(避免)ScrollView中嵌套ListView?