2012-06-28 11 views
17

Używam GridView, aby wyświetlić zestaw kategorii, które użytkownik może wybrać. Każda pozycja siatki składa się z ImageView i TextView, obydwu pobranych z serwera. Po dotknięciu elementu rozpoczyna się inna aktywność.Elementy wewnątrz GridView się powtarzają, gdy ekran przewija

Myślałem, że wszystko idzie dobrze, dopóki nie zauważyłem, że niektóre itens się powtarzają, gdy przewijam ekran. Ilekroć przewijam w dół przez siatkę, a potem z powrotem, itens zmienia swoją pozycję i ulega duplikacji. Ale nawet kiedy dotykam popsutych przedmiotów, odpowiednie wartości są wysyłane do następnej czynności.

Wyszukiwanie w programie LogCat powoduje pojawienie się kolejnych żądań do serwera. W rzeczywistości, mam to podczas przewijania:

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 

Wygląda spędzaj przewijania itens dostać przerysować ...

UPDATE: To tylko przerysować itens na pierwszy raz Przewiń GridView. Potem wszystkie przedmioty, w tym powtarzające się, pozostają na swoich miejscach.

Moja klasa 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; 
} 

klasa 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" 
/> 

Widziałem inne pytania dotyczące tego samego problemu, ale żaden z nich nie odpowiedział. Jakieś pomysły na to, co się dzieje?

+0

Użyj ViewHolder to dobra praktyka kodu –

Odpowiedz

82

To normalne, że można zobaczyć te same elementy, jak przewijać GridView ponieważ w metodzie getView ustawić kanału alfa dla ImageView tylko wtedy, gdy convertView jest null (na przykład do pierwszych elementów, które są widoczne, gdy GridView pojawiają na ekranie). Jeśli numer convertView nie jest null, co oznacza, że ​​masz widok z recyklowanego wiersza, nie ustawisz poprawnego obrazu i pozostaniesz z obrazem, który został wcześniej ustawiony w tym widoku z recyklingu. Spróbuj zmodyfikować metodę getView tak:

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; 
} 

Kliknięcie elementu pokazuje odpowiednie przedmioty, ponieważ użyć parametru position do pobierania danych.

+0

To zadziałało!Chociaż LogCat wyświetla te linie GC_EXTERNAL_ALLOC po pierwszym przewinięciu siatki ... –

+1

@LucasJota To jest garbage collector, myślę, że to normalne (jeśli nie powoduje opóźnienia 'GridView'). Pamiętaj, że pytasz o te obrazy, a także przechowujesz je w pamięci (nie wiem, ile masz). – Luksprog

+0

Idealnie sprawdziło się dzięki przyciskowi Button + Text View – KNU

0

Zmień tu i spróbować ponownie,

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; 
} 
+0

Po co dodawać dodatkową kontrolę, podczas gdy my już sprawdziliśmy dla convertview == null, wstawiłbym ostatni blok w bloku else. – Gripsoft

+0

tak, masz rację, ale nie działało to w "instrukcji else" dla mnie, jak, nie jestem pewien. – osayilgan

2

To jest mój kod GirdView z przycisku + 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; 
    } 
0

Send a gridview lub listview i W konstruktorze wdrożenia tej metody wdrożyć onscroll słuchacz

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"); 
     } 
    }); 
Powiązane problemy