屏幕滚动时,GridView中的项目会重复

我正在使用GridView来显示一组用户可以select的类别。 网格中的每一项都由从服务器检索到的ImageView和TextView组成。 当一个项目被触摸,另一个活动开始。

我认为一切都是正确的,直到我注意到当我滚动屏幕时,有些itens正在重复。 每当我通过网格向下滚动,然后回来,它改变它的位置,并得到重复。 但是,即使当我触碰到这些乱七八糟的东西时,正确的值也会被发送到下一个活动。

查看LogCat,发生对服务器的任何重复请求。 事实上,滚动时我已经有了这个:

06-28 12:36:38.554: D/dalvikvm(358): GC_EXTERNAL_ALLOC freed 2061 objects / 156024 bytes in 51ms 06-28 12:36:42.915: D/dalvikvm(358): GC_FOR_MALLOC freed 6590 objects / 737528 bytes in 57ms 06-28 12:38:26.725: D/dalvikvm(358): GC_EXTERNAL_ALLOC freed 5426 objects / 468176 bytes in 71ms 06-28 12:38:26.875: D/dalvikvm(358): GC_EXTERNAL_ALLOC freed 409 objects / 17480 bytes in 68ms 

看起来每次我滚动,itens得到重绘…

更新:它只在我第一次向下滚动GridView时重绘itens。 在此之后,所有这些,包括重复的,都保持在它的位置上。

我的Java类:

 public void proccess(){ int qtdCategorias = json.length(); imagens = new Drawable[qtdCategorias]; categorias = new String[qtdCategorias]; for (int i=0; i<qtdCategorias; i++){ JSONArray c = json.optJSONArray(i); String urlAmigavel = null; String imagemSite = null; String nomeCategoria = null; try { urlAmigavel = c.getString(6); imagemSite = c.getString(3); nomeCategoria = c.getString(2); } catch (JSONException e) { Log.e("CategoriasJogarActivity", e.toString()); e.printStackTrace(); } categorias[i] = nomeCategoria; imagens[i] = getImagem(urlAmigavel, imagemSite); } gridview = (GridView) findViewById(R.id.include3); ImageAdapter imageAdapter = new ImageAdapter(ctx, imagens, categorias); gridview.setAdapter(imageAdapter); gridview.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View v, int position, long id) { String name = null; String idt = null; try { JSONArray c = json.optJSONArray(position); name = c.getString(2); idt = c.getString(0); } catch (JSONException e) { Log.e("CategoriasJogarActivity", "JSONException" + e.toString()); } Intent in = new Intent(getApplicationContext(), JogarActivity.class); in.putExtra(TAG_NAME, name); in.putExtra(TAG_ID, idt); in.putExtra(TAG_PRIMEIRAPERGUNTA, true); startActivity(in); } }); } public Drawable getImagem(String urlAmigavel, String img) { String url = "http://www.qranio.com/pergunta/" + urlAmigavel + "/"+ img; InputStream is = null; try { URL urlImagem = new URL(url); is = (InputStream) getObjeto(urlImagem); } catch (MalformedURLException e1) { Log.e("CategoriasJogarActivity", e1.toString()); e1.printStackTrace(); } Drawable d = Drawable.createFromStream(is, "src"); return d; } private Object getObjeto(URL url) { Object content = null; try { content = url.getContent(); } catch (IOException e) { Log.e("CategoriasJogarActivity", e.toString()); e.printStackTrace(); } return content; } 

imageAdapter类

 public class ImageAdapter extends BaseAdapter{ private Context mContext; private final Drawable[] mThumbIds; private final String[] mTextIds; public ImageAdapter(Context c, Drawable[] d, String[] s) { mContext = c; mThumbIds = d; mTextIds = s; } public int getCount() { return mThumbIds.length; } public Object getItem(int position) { return null; } public long getItemId(int position) { return 0; } //create a new ImageView for each item referenced by the Adapter public View getView(int position, View convertView, ViewGroup parent) { //ImageView imageView; View v; if (convertView == null) { // if it's not recycled, initialize some attributes LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( Context.LAYOUT_INFLATER_SERVICE ); v = inflater.inflate(R.layout.gridview_item_layout, null); TextView text = (TextView)v.findViewById(R.id.grid_item_text); text.setText(mTextIds[position]); ImageView image = (ImageView)v.findViewById(R.id.grid_item_image); image.setImageDrawable(mThumbIds[position]); } else { v = (View) convertView; } return v; } } 

gridview_item_layout xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/gridview_item_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:gravity="center_horizontal" > <ImageView android:id="@+id/grid_item_image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="fitCenter" android:minHeight="100dip" android:minWidth="100dip" > </ImageView> <TextView android:id="@+id/grid_item_text" android:layout_width="match_parent" android:layout_height="match_parent" android:text="TextView" android:gravity="center" android:textColor="#F9A512" android:textStyle="bold" android:textSize="18dp" > </TextView> </LinearLayout> 

gridview xml

 <?xml version="1.0" encoding="utf-8"?> <GridView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/gridview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:numColumns="auto_fit" android:verticalSpacing="10dip" android:horizontalSpacing="10dip" android:stretchMode="columnWidth" android:gravity="center" android:background="#FFFFFF" android:padding="5dip" /> 

我看到有关这个问题的其他问题,但没有一个回答。 任何想法发生了什么?

Solutions Collecting From Web of "屏幕滚动时,GridView中的项目会重复"

在向下滚动GridView看到相同的项目是正常的,因为在getView方法中,只有当convertViewnull (例如在GridView出现在屏幕上时看到的第一个元素),才会为ImageView设置drawable, 。 如果convertView不为null ,意味着您有一个循环的行视图,则不会设置正确的图像,而是保留之前在此循环视图中设置的图像。 尝试修改getView方法,如下所示:

 public View getView(int position, View convertView, ViewGroup parent) { View v; if (convertView == null) { // if it's not recycled, initialize some attributes LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( Context.LAYOUT_INFLATER_SERVICE ); v = inflater.inflate(R.layout.gridview_item_layout, parent, false); } else { v = (View) convertView; } TextView text = (TextView)v.findViewById(R.id.grid_item_text); text.setText(mTextIds[position]); ImageView image = (ImageView)v.findViewById(R.id.grid_item_image); image.setImageDrawable(mThumbIds[position]); return v; } 

单击元素将显示正确的项目,因为您使用position参数来检索数据。

这些是我的代码为GirdView与Button + Textview

 public View getView(final int position, View convertView, ViewGroup parent) { LayoutInflater mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); if (convertView == null) { convertView = mInflater.inflate(R.layout.grid_item, null); } else { holder = (ViewHolder) convertView.getTag(); } TextView text = (TextView)convertView.findViewById(R.id.texto_grid); text.setText(app_listaActiva_NOMBRES[position]); Button image = (Button)convertView.findViewById(R.id.miniatura_grid); image.setBackgroundResource(R.drawable.custom_button); image.setOnClickListener(new MyOnClickListener2(position,app_listaActiva_SONIDOS)); return convertView; } 

改变这里,再试一次,

  View v; if (convertView == null) { // if it's not recycled, initialize some attributes LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( Context.LAYOUT_INFLATER_SERVICE ); v = inflater.inflate(R.layout.gridview_item_layout, null); TextView text = (TextView)v.findViewById(R.id.grid_item_text); text.setText(mTextIds[position]); } else { v = (View) convertView; } if(view!=null) { ImageView image = (ImageView)v.findViewById(R.id.grid_item_image); image.setImageDrawable(mThumbIds[position]); notifyDataSetChanged(); //Calling this helped to solve the problem. } return v; } 

发送和gridview或listview和在构造函数中实现此方法实现onscroll侦听器

  this.mGridView = mGridView; this.mGridView.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { Log.v("onScrollStateChanged", "onScrollStateChanged"); if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) { isScrollStop = true; notifyDataSetChanged(); } else { isScrollStop = false; } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { Log.v("onScroll", "onScroll"); } });