android配适器Listview的ViewHolder和ConvertView的用法和原理

这两天一直在查listview 和ViewHolder和ConvertView,网上好多都是一篇文章转载n次,现今终于大致的明白一点,写下,待以后补充。

更新:今儿个我去请教了老师,哎呀,不得不说老师就是老师,就是厉害,想了两天也没怎么想明白的东西一下子就明白了,所以说啊,趁着上学,赶紧把不会的问了,希望这个老师不是下一个被我问烦了的人。我都问走了好几个老师了。。。。。唉。。。。。
在这里插入图片描述
这个是网上转载次数最多的那篇文章的配的原理图。

下面这个是老师给我画的:
在这里插入图片描述
独家原创,此图一出,谁与争锋!之前看了那么多的博客啊,网上的解释说一大堆什么view, convertview,出去的view,进来的view,其实呢,原理相当的简单了!太简单了,我说怎么谷歌的头脑也不至于逆天啊,整的那么复杂,原来是我自己想复杂了。
这是现在的解释:
每向上向下滑动一下,就会有出去的和进来的。你设置了几行信息(item)如果都能显示在屏幕上就正好,如果没有显示在屏幕上就会在你没有看见的那块继续创建,只不过创建的你没有看见而已,。当你往上滑动的时候显示的都是创建的,如果没创建下一条view就不需要创建了,只要复用被划出去的那个view就行,把之前view的值换成新的值。

代码如下:
activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true" >
    </ListView>

</RelativeLayout>

item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="50dp"
        android:text="TextView"
        android:textColor="#ff0000"
        android:textSize="20sp" />

</LinearLayout>

MainActivity.java

package com.example.baseadaptertest;

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ListView  listView=(ListView) findViewById(R.id.listView1);
        listView.setAdapter(new myAdapter());
    }

  class myAdapter extends BaseAdapter{
	   int  count=0;
       String[] books=new String[]{"jsp","asp","c#","Embed","English","Math","Chiness"};
		@Override
		public int getCount() {
			return books.length;
		}
	
		@Override
		public Object getItem(int position) {
			// TODO Auto-generated method stub
			return books[position];
		}
	
		@Override
		public long getItemId(int position) {
			// TODO Auto-generated method stub
			return position;
		}
	
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
//        第一种方法  每次都重新创建View,每创建一个view都很消耗资源

//			View  view=View.inflate(getApplicationContext(), R.layout.item,null);
//			TextView  bookname=(TextView) view.findViewById(R.id.textView1);
//			bookname.setText(getItem(position).toString());
//			Log.i("getView","create view :"+getItemId(position));
//			return  view;
	
			
			//第二种方法 ,只会创建比手机界面种最多能显示的记录的个数多1个的view
			//上下滑动之后显示的其它的view都可以复用之前滑出去的那些View,不需要重新创建
			if(convertView==null){
				View  view=View.inflate(getApplicationContext(), R.layout.item,null);
				TextView  bookname=(TextView) view.findViewById(R.id.textView1);
				bookname.setText(getItem(position).toString());
				count++;
				Log.i("getView","创建第"+count+" 个view :"+getItem(position));
				view.setTag(count);//给view一个编号
				return view;
			}else {
				
				TextView bookname=(TextView) convertView.findViewById(R.id.textView1);
				bookname.setText(getItem(position).toString());
	    		Log.i("getView","复用第"+convertView.getTag()+"个 view :"+getItem(position));
				return convertView;
			}
			
		}
    } 
}

这个是结果图,动图我不会传,直接传截图。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
可以看到复用的和所在的条数的位置是一样的,很显然,这是编译器在开的一个玩笑,其实复用那个view是随机的,这个是碰巧。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这是之前的解释:
现在来解释一下:一个手机屏幕上有第一列那1-7,只要你往上滑一下,1就没了,没了去哪了呢?就去了安卓给的recycle这个回收里了。这个回收是在ConvertView里的。也就是说Item1这个视图(View)已经变成旧的了,就如新袜子一样,穿过了隔一天就是旧的了,view就是新的,隔一天就变成ConvertView(这个旧的了),当然通过回收进行重新纺织还是能变成新的,这是后话 。
ConvertView:android SDK中这样讲参数 convertview :
the old view to reuse, if possible. Note: You should check that this view is non-null and of an appropriate type before using.
If it is not possible to convert this view to display the correct data, this method can create a new view.
翻译:
如果可以的话,这是旧View(视图)的重用。 建议:在用之前,你应该检查这个View是
不是非空,是不是一个合适的类型。
如果不可能让这个VIew去显示一个恰当的数据,这个方法会创建一个新的View。

也就是说这个ConvertView是一个能用就用的旧视图,我们通过往旧视图里添加item(信息)来实现不重复新建新视图。
后来的item8就是用的item1这个旧视图来填充新的数据进行显示的。
这涉及到ViewHolder
ViewHolder:是一个持有者的类,里面没有方法,只有属性,作用就是一个临时的储存器,把每次getView中每次返回的view储存起来,下次再用,不用再每次去布局文件中拿,从而提高了效率。也就是说ViewHolder是一个数据存储器,里面存的是要显示的数据,为的是listview滚动的时候快速设置值,而不必每次都重新创建很多对象,从而提升性能。
通过ConvertView.setTag(ViewHolder)=为视图绑定一个数据,来显示出来。

以上就是我这两天所学到的,可能有的地方理解有误,以后会进行更正和补充。
第一次解释的其实也没啥不对,不过理解不够到位,十分糊涂罢了,getView 返回的是一个view,这个十分的重要。
很感谢能在大学遇到这么好的老师,感谢上苍!

参考:
Android ViewHolder的作用与用法:https://zhidao.baidu.com/question/544207312.html
ListView中convertView和ViewHolder的工作原理:https://blog.csdn.net/Bill_Ming/article/details/8817172
Android ViewHolder的作用与用法 详解:https://blog.csdn.net/sky1466181491/article/details/48846985
android adapter中到converView机:https://hunankeda110.iteye.com/blog/1827691
[Android] ListView中getView的原理+如何在ListView中放置多个item:http://www.cnblogs.com/xiaowenji/archive/2010/12/08/1900579.html
convertView.setTag()这个api是不是使得viewholder与convertView同生命周期?:https://www.imooc.com/qadetail/74255
View.setTag()与View.getTag()的作用:http://www.cnblogs.com/qingblog/archive/2012/05/30/2526239.html
Android:ListView之ViewHolder:https://www.cnblogs.com/luoaz/p/3734999.html
Android必学之数据适配器BaseAdapter:https://www.cnblogs.com/caobotao/p/5061627.html

发布了32 篇原创文章 · 获赞 7 · 访问量 4016

猜你喜欢

转载自blog.csdn.net/qq_43026792/article/details/90374669
今日推荐