listView中的Item有时候会添加其他的内容,例如有一块儿隐藏的区域,点击后展开,再次点击则隐藏。这时如果Item超过一屏,那么直接在Adapter中的getView方法加入判空操作,即
if(convertView == null){ convertView = new DownloadItem_CachedView(context); }
解决办法,有三种。
1. 首先,各位想到的可能是直接把判空操作去掉,那么就不会复用,也就不会出现混乱了。这确实是一种方法,但是生成的View没有复用,那么会造成资源的浪费,而且有时候如果程序复杂,会出现各种异常的情况,这就是无意中造就的Bug,而且解的时候很难发现,本人就深深受过这种坑害。
2. 本地点击状态记录。传过去list的时候,加入一个字段表示是否已经展开,在原数据上加字段,该方法最好。举个例子:假如之前list传的是1-20的数字,每一个都显示在Item上,之前的 数据是list<Integer>,那么现在改成list<Map<Integer,Boolean>>,用来记录是否应该被展开,然后每次getView的时候判断是否该显示出来。
代码如下:
MainActivity.java
public class MainActivity extends Activity implements OnItemClickListener{ private ListView lv; private Map<Integer,Boolean> ItemString; private ListViewAdapter myAdapter ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv= (ListView) findViewById(R.id.listview); initItemNum(); myAdapter = new ListViewAdapter(MainActivity.this,ItemString); lv.setAdapter(myAdapter); lv.setOnItemClickListener(this); } private void initItemNum() { // TODO Auto-generated method stub ItemString = new HashMap<Integer,Boolean>(); for(int i =0;i<20;i++){ ItemString.put(i,false); } } @Override public void onItemClick(AdapterView<?> arg0, View arg1, final int arg2, long arg3) { View view = arg1.findViewById(R.id.bottom); if(view.getVisibility() == View.VISIBLE){ view.setVisibility(View.GONE); ItemString.put(arg2, false); } else{ view.setVisibility(View.VISIBLE); ItemString.put(arg2, true); } Toast.makeText(MainActivity.this, "你点击的是:"+arg2, Toast.LENGTH_SHORT).show(); } }listViewAdapter.java
public class ListViewAdapter extends BaseAdapter { private Context context; private Map<Integer,Boolean> ItemNumString; private LayoutInflater inflater; public ListViewAdapter(Context context,Map<Integer,Boolean> ItemNumString) { this.context = context; this.ItemNumString = ItemNumString; inflater = LayoutInflater.from(context); } @Override public int getCount() { // TODO Auto-generated method stub return ItemNumString.size(); } @Override public Object getItem(int arg0) { // TODO Auto-generated method stub return ItemNumString.get(arg0); } @Override public long getItemId(int arg0) { // TODO Auto-generated method stub return arg0; } @Override public View getView(final int arg0, View arg1, ViewGroup arg2) { // TODO Auto-generated method stub if(arg1 == null){ arg1 = inflater.inflate(R.layout.listview_item, null); } else{ boolean flag = ItemNumString.get(arg0); if(flag){ arg1.findViewById(R.id.bottom).setVisibility(View.VISIBLE); } <span style="background-color: rgb(51, 255, 51);">else{ arg1.findViewById(R.id.bottom).setVisibility(View.GONE); }//重点,虽然默认为Gone,但复用的时候要加上,否则会混乱。</span> } return arg1; } }注意:可以将view想象成白板,每次重用需要将白板檫干净再用,否则在写了字的白板上再写字,那么就乱掉啦。
3.用全局map来记录点击状态。初始化Adapter的时候,初始化map,点击状态改变时,再次记录map中,getView的时候加入判断即可。这样做省事,但是浪费资源,而且有时候回有危险,就是刷新状态的时候,需要重新初始化map。
好了,就记录到这。
listview中Item记录点击状态的方法--(点击显示、隐藏的状态保存)
原文地址:http://blog.csdn.net/adayabetter/article/details/44453623