优化的实现步骤:
1. 判断convertView对象是否为null,如果为null,那么通过LayoutInflater对象进行初始化并且将convertView对象作为返回值返回值
此步骤实现了减少被返回的View对象的初始化次数
2. 创建一个类(通常此类名为ViewHolder),在该类中定义n条属性,
定义的属性取决于item的布局文件中有多少控件
3.在getView方法中声明一个ViewHolder对象,在convertView为null的时候,进行初始化,并初始化holder中所有的控件属性,
4. 初始化完成之后通过convertView的setTag方法将holder对象整体的存储起来
第2,3,4步骤的目的是减少item中控件的初始化次数
5.当convertView不为null时,通过getTag方法取出之前存储的ViewHolder对象
6. 通过holder调用属性设置控件的显示内容即可
优化的代码:
package com.example.administrator.myapplication; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; public class ItemTag { public ImageView imageView; public TextView textView; public Button button; }
package com.example.administrator.myapplication; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.ImageView; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.TextView; import android.widget.Toast; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class MainActivity extends AppCompatActivity { private ListView listView; private String[] titles={"狗狗","大象","猫咪","烧鸡","黑牛"}; private int[] images={R.drawable.dog,R.drawable.elephant,R.drawable.cat,R.drawable.chicken,R.drawable.cow}; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = (ListView) findViewById(R.id.lv_main_list); listView.setAdapter(new Mydapter()); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(MainActivity.this,"跳转到"+titles[position%titles.length]+"页面",Toast.LENGTH_SHORT).show(); } }); } class Mydapter extends BaseAdapter{ @Override public int getCount() { return 1000; } @Override public Object getItem(int position) { return titles[position%titles.length]; } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { if(convertView==null){ convertView=getLayoutInflater().inflate(R.layout.item_listview,null); ItemTag itemTag=new ItemTag(); itemTag.imageView= (ImageView) convertView.findViewById(R.id.iv_images_images); itemTag.textView= (TextView) convertView.findViewById(R.id.tv_textview_text); itemTag.button= (Button) convertView.findViewById(R.id.bt_button_button); convertView.setTag(itemTag); } ItemTag itemTag= (ItemTag) convertView.getTag(); itemTag.imageView.setImageResource(images[position% titles.length]); itemTag.textView.setText(titles[position%titles.length]+position); itemTag.button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this,"正在下载"+titles[position%titles.length],Toast.LENGTH_SHORT).show(); } }); return convertView; } } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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" > <ListView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/lv_main_list" ></ListView> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent" android:descendantFocusability="blocksDescendants" > <ImageView android:layout_width="50dp" android:layout_height="50dp" android:id="@+id/iv_images_images" android:src="@drawable/bird" /> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:id="@+id/tv_textview_text" android:text="XX" android:textSize="30sp" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="下载" android:id="@+id/bt_button_button" /> </LinearLayout>
1.2.ListView问题处理
ListView中常见bug
1.当item中包含checkbox或者button这些具备默认点击效果的控件时,易引发的bug:
造成ListView无法接收ItemClick事件,
原因:checkbox或者button这些具备默认点击效果的控件默认抢占页面焦点
解决方式:使item具备焦点的能力
解决方式一:找到对应抢占焦点的控件,给该控件的标签添加一条Android:focusable=“false”,让当前控件失去焦点
解决方式二:在item布局的根标签中添加属性:android:descendantFocusability="blocksDescendants" ,屏蔽根标签内所有子控件 的焦点
2.当item中包含CheckBox控件时,如果想要实现CheckBox本身单独的点击事件,那么
只需在getView方法中通过holder对象直接调用CheckBox对象进行设置即可
3.当item中包含CheckBox控件时,如果想要实现即使点击是CheckBox控件区域也算做listveiw的itemclick事件的话,
实现方式:在CheckBox标签中添加属性:android:clickable = false
4.当item中包含CheckBox控件并且列表比较长,多次上下滚动后,CheckBox的选中效果会乱串
产生原因: 由于convertView的复用带来,新滑动入屏幕的item的View对象复用了之前CheckBox选中那一行的View对象
解决方式:
在处理checkbox的选中事件时,同时将选中内容通过一个集合对象存储起来,在getView中,通过当前行的显示内容与选中集合进行判断,符合条件的,让当前行的checkbox选中,反之,设置checkbox非选中