2012-06-28 23 views
17

Tôi đang sử dụng GridView để hiển thị một tập hợp các Danh mục mà người dùng có thể chọn. Mỗi mục của lưới được bao gồm bởi một ImageView và một TextView, cả hai được lấy từ máy chủ. Khi một mục được chạm vào, một hoạt động khác được bắt đầu.Các mục trong GridView được lặp lại khi cuộn màn hình

Tôi nghĩ mọi thứ diễn ra đúng, cho đến khi tôi nhận thấy rằng một số itens đã được lặp đi lặp lại khi tôi cuộn màn hình. Bất cứ khi nào tôi di chuyển xuống máng lưới, và sau đó trở lại, itens thay đổi vị trí của nó và được nhân đôi. Nhưng ngay cả khi tôi chạm vào sự lộn xộn, các giá trị phù hợp sẽ được gửi đến hoạt động tiếp theo.

Tìm trong LogCat, mọi yêu cầu lặp lại đối với máy chủ đều xảy ra. Trong thực tế, tôi đã có này trong khi di chuyển:

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 

Hình như mỗi khi di chuyển, itens được vẽ lại ...

UPDATE: Nó chỉ vẽ lại itens trên lần đầu tiên tôi di chuyển xuống các GridView. Sau này, tất cả các itens, bao gồm cả những người lặp đi lặp lại, giữ trên vị trí của nó.

java My lớp:

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

lớp 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" 
/> 

Tôi đã thấy các câu hỏi khác về cùng một vấn đề này, nhưng không ai trong số họ trả lời. Bất kỳ ý tưởng về những gì đang xảy ra?

+0

Sử dụng ViewHolder là thực hành tốt về mã số –

Trả lời

82

Đó là bình thường mà bạn nhìn thấy các mặt hàng giống như bạn di chuyển xuống các GridView vì trong phương pháp getView bạn thiết lập drawables cho ImageView chỉ khi convertViewnull (ví dụ cho các yếu tố đầu tiên được nhìn thấy khi GridView xuất hiện trên màn hình). Nếu convertView không phải là null, có nghĩa là bạn có chế độ xem hàng được tái chế, bạn không đặt đúng hình ảnh và bạn vẫn còn với hình ảnh đã được đặt trước đó trên chế độ xem được tái chế này. Cố gắng thay đổi phương pháp getView như thế này:

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

Nhấp một yếu tố cho bạn thấy các mục đúng bởi vì bạn sử dụng tham số position để lấy dữ liệu.

+0

Đã hoạt động!Mặc dù LogCat tiếp tục hiển thị các dòng GC_EXTERNAL_ALLOC đó khi lần đầu tiên cuộn xuống lưới ... –

+1

@LucasJota Đó là bộ thu gom rác, tôi nghĩ nó bình thường (nếu nó không tạo ra độ trễ 'GridView'). Hãy nhớ rằng bạn đang truy vấn những hình ảnh đó và cũng giữ chúng trong bộ nhớ (Tôi không biết bạn có bao nhiêu). – Luksprog

+0

Làm việc hoàn hảo cho tôi với Button + Textview – KNU

0

Thay đổi ở đây và thử lại lần nữa,

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

Tại sao bạn sẽ thêm một kiểm tra bổ sung, trong khi chúng tôi đã kiểm tra cho convertview == null, tôi sẽ đặt khối cuối cùng trong khối khác. – Gripsoft

+0

vâng bạn đúng, nhưng nó không hoạt động trong "tuyên bố khác" đối với tôi một số cách, tôi không chắc chắn. – osayilgan

2

Những là mã của tôi cho GirdView với nút + 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

Gửi và GridView hoặc listview và Trong constructor thực hiện phương pháp này thực hiện OnScroll người nghe

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