原文出自:http://blog.csdn.net/u011889786/article/details/52143268
背景:以前遇到过,最近又碰到了,就总结一下吧
一.ListView
(1)出现原因
是因为listView的高度不确定,一般用的是wrap_content,导致系统需要不断地测量,也就是多测调用onMeasure方法,所以就多次调用getView,所以解决方法也挺简单,把宽高写死(精确给个数字,或者match_parent).
(2)解决方法
adapter.Java
[java] view plain copy
- package com.dx.text0808;
- import android.content.Context;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.BaseAdapter;
- import android.widget.TextView;
- import java.util.ArrayList;
- import java.util.List;
- /**
- * Created by xiongchao on 2016/7/18.
- */
- public class UpdateOtherGridAdapter extends BaseAdapter {
- private LayoutInflater inflater;
- private Context mContext;
- private List<String> contentList = new ArrayList<>();
- public UpdateOtherGridAdapter(Context context, ArrayList<String> list) {
- this.mContext = context;
- inflater = LayoutInflater.from(context);
- this.contentList = list;
- }
- public void setContentList(List<String> contentList) {
- this.contentList = contentList;
- }
- public void update() {
- this.notifyDataSetChanged();
- }
- @Override
- public int getCount() {
- return contentList.size();
- }
- @Override
- public Object getItem(int arg0) {
- return null;
- }
- @Override
- public long getItemId(int arg0) {
- return 0;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- System.out.println("xcqw getView ***position"+position);
- ViewHolder holder = null;
- if (convertView == null) {
- convertView = inflater.inflate(R.layout.item,
- parent, false);
- holder = new ViewHolder();
- holder.tvContent = (TextView) convertView.findViewById(R.id.tv_content);
- convertView.setTag(holder);
- } else {
- holder = (ViewHolder) convertView.getTag();
- }
- String content = contentList.get(position);
- holder.tvContent.setText(content);
- return convertView;
- }
- public class ViewHolder {
- public TextView tvContent;
- }
- }
<1>会出现多次调用getView的写法
activity_main.xml
[java] view plain copy
- <?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"
- android:orientation="vertical"
- >
- <Button
- android:id="@+id/bt_refresh"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="点我更新listView"/>
- <ListView
- android:id="@+id/gv"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
- </ListView>
- </LinearLayout>
注意看到 ListView的Layout_height中写的是wrap_content
实际打印如下:
08-07 16:39:18.604 25086-25086/com.dx.text0808 I/System.out: xcqw getView ***position0
08-07 16:39:18.609 25086-25086/com.dx.text0808 I/System.out: xcqw getView ***position1
08-07 16:39:18.609 25086-25086/com.dx.text0808 I/System.out: xcqw getView ***position2
08-07 16:39:18.668 25086-25086/com.dx.text0808 I/System.out: xcqw getView ***position0
08-07 16:39:18.669 25086-25086/com.dx.text0808 I/System.out: xcqw getView ***position1
08-07 16:39:18.679 25086-25086/com.dx.text0808 I/System.out: xcqw getView ***position2
08-07 16:39:18.691 25086-25086/com.dx.text0808 I/System.out: xcqw getView ***position0
08-07 16:39:18.693 25086-25086/com.dx.text0808 I/System.out: xcqw getView ***position1
08-07 16:39:18.707 25086-25086/com.dx.text0808 I/System.out: xcqw getView ***position2
08-07 16:39:18.784 25086-25086/com.dx.text0808 I/System.out: xcqw getView ***position0
08-07 16:39:18.785 25086-25086/com.dx.text0808 I/System.out: xcqw getView ***position1
08-07 16:39:18.786 25086-25086/com.dx.text0808 I/System.out: xcqw getView ***position2
<2>不会出现多次调用getView的写法
[java] view plain copy
- <?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"
- android:orientation="vertical"
- >
- <Button
- android:id="@+id/bt_refresh"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="点我更新listView"/>
- <ListView
- android:id="@+id/gv"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- </ListView>
- </LinearLayout>
注意看到现在ListView中的Layout_height 写的是Match_parent
实际打印如下:
[java] view plain copy
- 08-07 16:42:48.892 28432-28432/com.dx.text0808 I/System.out: xcqw getView ***position0
- 08-07 16:42:48.905 28432-28432/com.dx.text0808 I/System.out: xcqw getView ***position1
- 08-07 16:42:48.910 28432-28432/com.dx.text0808 I/System.out: xcqw getView ***position2
二.GridView
(1)出现原因
貌似不管长宽写不写死都是会多次调用getView,不知道为啥,日了狗了。。。原因待补充
(2)解决方法
<1>出现的情形
adapter.xml
[java] view plain copy
- package com.dx.text0807;
- import android.content.Context;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.BaseAdapter;
- import android.widget.TextView;
- import java.util.ArrayList;
- import java.util.List;
- /**
- * Created by xiongchao on 2016/7/18.
- */
- public class UpdateOtherGridAdapter extends BaseAdapter {
- private LayoutInflater inflater;
- private Context mContext;
- private List<String> contentList = new ArrayList<>();
- public UpdateOtherGridAdapter(Context context, ArrayList<String> list) {
- this.mContext = context;
- inflater = LayoutInflater.from(context);
- this.contentList = list;
- }
- public void update() {
- this.notifyDataSetChanged();
- }
- @Override
- public int getCount() {
- return contentList.size();
- }
- @Override
- public Object getItem(int arg0) {
- return null;
- }
- @Override
- public long getItemId(int arg0) {
- return 0;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- System.out.println("xcqw getView 1***position"+position);
- ViewHolder holder = null;
- if (convertView == null) {
- convertView = inflater.inflate(R.layout.item,
- parent, false);
- holder = new ViewHolder();
- holder.tvContent = (TextView) convertView.findViewById(R.id.tv_content);
- convertView.setTag(holder);
- } else {
- holder = (ViewHolder) convertView.getTag();
- }
- if(((MyGridView) parent).isOnMeasure){
- //如果是onMeasure调用的就立即返回
- return convertView;
- }
- System.out.println("xcqw getView 2***position"+position);
- String content = contentList.get(position);
- holder.tvContent.setText(content);
- //如果不是onMeasure调用的就可以正常操作了
- //赋值操作
- return convertView;
- }
- public class ViewHolder {
- public TextView tvContent;
- }
- }
activity_main.xml
[java] view plain copy
- <?xml version="1.0" encoding="utf-8"?>
- <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"
- tools:context="com.dx.text0807.MainActivity">
- <com.dx.text0807.MyGridView
- android:id="@+id/gv"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- >
- </com.dx.text0807.MyGridView>
- <!--android:layout_height="wrap_content"-->
- <!--android:layout_height="50dp"-->
- </RelativeLayout>
注意了!!!,不管你长宽怎么写都是会多次调用getView,不知道网上说写死就可以的人是怎么整的。。。
<2>解决方法
不让他多次调用getView是不可能了,所以只能说在他onMeasure调用getView的时候我们不要去对convertView做任务赋值的操作,只有当onLayout的时候我们再对ConvertView操作
首先我们要重写一个gridView
MyGridView.java
[java] view plain copy
- public class MyGridView extends GridView {
- public boolean isOnMeasure;
- public MyGridView(Context context) {
- super(context);
- }
- public MyGridView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
- public MyGridView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- isOnMeasure = true;
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- }
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- isOnMeasure = false;
- super.onLayout(changed, l, t, r, b);
- }
- }
getView中对ConvertView的处理
[java] view plain copy
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- System.out.println("xcqw getView 1***position"+position);
- ViewHolder holder = null;
- if (convertView == null) {
- convertView = inflater.inflate(R.layout.item,
- parent, false);
- holder = new ViewHolder();
- holder.tvContent = (TextView) convertView.findViewById(R.id.tv_content);
- convertView.setTag(holder);
- } else {
- holder = (ViewHolder) convertView.getTag();
- }
- if(((MyGridView) parent).isOnMeasure){
- //如果是onMeasure调用的就立即返回
- return convertView;
- }
- System.out.println("xcqw getView 2***position"+position);
- String content = contentList.get(position);
- holder.tvContent.setText(content);
- //如果不是onMeasure调用的就可以正常操作了
- //赋值操作
- return convertView;
- }
实际打印
08-07 17:11:37.119 17294-17294/com.dx.text0807 I/System.out: xcqw getView 1***position0
08-07 17:11:37.178 17294-17294/com.dx.text0807 I/System.out: xcqw getView 1***position0
08-07 17:11:37.268 17294-17294/com.dx.text0807 I/System.out: xcqw getView 1***position0
08-07 17:11:37.268 17294-17294/com.dx.text0807 I/System.out: xcqw getView 2***position0
08-07 17:11:37.269 17294-17294/com.dx.text0807 I/System.out: xcqw getView 1***position1
08-07 17:11:37.271 17294-17294/com.dx.text0807 I/System.out: xcqw getView 2***position1
08-07 17:11:37.272 17294-17294/com.dx.text0807 I/System.out: xcqw getView 1***position2
08-07 17:11:37.273 17294-17294/com.dx.text0807 I/System.out: xcqw getView 2***position2
08-07 17:11:37.274 17294-17294/com.dx.text0807 I/System.out: xcqw getView 1***position3
08-07 17:11:37.276 17294-17294/com.dx.text0807 I/System.out: xcqw getView 2***position3
08-07 17:11:37.279 17294-17294/com.dx.text0807 I/System.out: xcqw getView 1***position0
08-07 17:11:37.281 17294-17294/com.dx.text0807 I/System.out: xcqw getView 1***position0
08-07 17:11:37.373 17294-17294/com.dx.text0807 I/System.out: xcqw getView 1***position0
08-07 17:11:37.376 17294-17294/com.dx.text0807 I/System.out: xcqw getView 1***position0
可以看到 getView2*** 打印只有四次 ,效果达到了,哈哈