在使用ListView显示数据的时候,定义一个适配器,而后重写getView()方法,这时经过LOG日志分析会发现getView()方法会被执行屡次。经过上网查询资料得出ide
缘由在于View在Draw的时候分为两个阶段,measure和layout,在measure阶段得时候,主要是为了计算两个参数,height和width,这是一个递归的过程,DecorView开始依次调用本身元素的measure,计算完成两个参数就开始layout,而后调用draw,对于ListView,每个Item都会调用measure(),而在这个过程当中getView()和getCont()会被调用,并且根据用户的需求,可能有屡次调用url
多组调用的缘由:spa
这是因为layout中定义的ListView或者其父元素的height和width的属性决定了,fill_parent,计算会简单一点,可是Wrap_content的计算会多一点,至于自适应会一直考量Item的宽和高,根据内容,计算高度,这个measure可能会反复执行。日志
解决方法,就是listview的大小要肯定,例如使用match_parent。
方法一:
在listview外面套一层RelativeLayout,将listview高度设置为match_parent。
code
方法二:
在listview外面套一层 LinearLayout,将listview高度设置为0dip。
weight设为1。xml
这样简单的listview是有效的,可是item若是是复杂的xml,很难实现,或者说没法实现。若是是scrollview嵌套listview和gridview也不会成功。递归
究其缘由,无非是listview要动态计算有多少个view显示在里面,因此须要屡次onMeasure,最后才onLayout,而onMeasure可能须要执行屡次。这不就好了,咱们在adapt里面的getview中,判断是否在onmeasure里,若是在。(在adapter的getView()方法中,对isOnMeasure()的值进行判断,若是为ture,提早return convertView;)ip
首先重写 listviewget
public class NoScrollListview extends ListView{ //设置判断来防止重复执行getView(); public boolean isOnMeasure = false; public NoScrollListview(Context context) { super(context); } public NoScrollListview(Context context, AttributeSet attrs) { super(context, attrs); } /** * 设置不滚动 */ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { isOnMeasure = true; int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { isOnMeasure = false; super.onLayout(changed, l, t, r, b); } }
而后在Adapter中判断it
public View getView(int position, View convertView, ViewGroup parent) { ViewHolder vh; if (convertView == null) { convertView = inflater.inflate(R.layout.inflate_griditem_mainpage_wall_and_lock, null); vh = new ViewHolder(); vh.iv = (ImageView) convertView.findViewById(R.id.image_griditem2); convertView.setTag(vh); }else { vh = (ViewHolder) convertView.getTag(); } //关键代码 if (parent instanceof MyGridView) { if (((MyGridView)parent).isOnMeasure) { return convertView; } } String url = (String)getItem(position); HttpUtil.loadImage(context, Stringutil.get208x312(url), vh.iv); vh.iv.setOnClickListener(new MyClickListener(Stringutil.get480x800(url))); num++; Log.i("Cat", "getView() : Main = "+num+""); return convertView; }
这样就能完全解决屡次调用问题