ListView和GridView重复调用getView的解决方法

场景:文件浏览器加载大容量磁盘过程中,列表浏览和平铺浏览点击进入下一级界面或者按遥控器快速移动光标,概率性会有卡顿现象。

分析原因:列表浏览使用的是ListView, 平铺浏览使用的是GridView, 可能是重复调用了getView或者getView方法里面做了耗时的操作。(加载大容量磁盘时,系统需要扫描媒体库,也可能会使CPU占用高而导致卡顿,这种情况暂不考虑)

一、ListView重复调用getView解决方法:

1、首先在getView方法中加上打印日志,代码如下:

@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		Log.d(TAG, "getView: position = " + position);
2、打印日志如下,标记为红框的地方为getView重复调用:


3、原因分析及解决方法:ListView布局时height和width都不是match_parent,导致不断计算高度,不断刷新。或者说它的父容器没有设置成match_parent. 我们只需要设置ListView为固定宽高即可。

listView布局xml文件修改前:

<ListView
            android:id="@+id/list"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"

修改后:

<ListView
            android:id="@+id/list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
修改后编译APK再次打印日志如下(ListView没有重复调用getView了):


二、GridView重复调用getView解决方法:

1、首先在getView方法中加上打印日志,代码如下:

@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		int childCount = parent.getChildCount();
		Log.d(TAG, "getView: position = " + position + ", childCount = " + childCount);
2、打印日志如下,标记为红框的地方为getView重复调用:


3、原因分析及解决方法:GridView宽高设置为match_parent, 仍会出现多次调用getView的问题。由上面日志可以看到,当position != childCount position = 0且时,此时为getView重复调用。虽然暂无好的方法禁止GridView重复调用getView, 但我们可以判断重复调用getView时,直接返回convertView即可。

代码修改前:

@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		int childCount = parent.getChildCount();
		Log.d(TAG, "getView: position = " + position + ", childCount = " + childCount);
		ViewHolder vh;
		if (convertView == null) {
			vh = new ViewHolder();

代码修改后:

@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		int childCount = parent.getChildCount();
		Log.d(TAG, "getView: position = " + position + ", childCount = " + childCount);
		ViewHolder vh;
		// 按方向键或者ImageLoader加载缩略图都会重复调用两次getView,导致卡顿。当判断为重复调用时直接返回convertView
		if (position != childCount && position == 0 && convertView != null) {
			Log.d(TAG, "getView duplicate, return");
			return convertView;
		}
		if (convertView == null) {
			vh = new ViewHolder();

修改后编译APK再次打印日志如下(当判断为重复调用getView时直接返回):


PS:以上代码中打印日志只是供调试,由于getView日志打印很频繁,正式提交代码时需要屏蔽掉该日志打印。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值