2013-01-07 59 views
3

我設計了一個帶有自定義項目佈局的GridView,左上角有一個ImageView,右上角有另一個ImageView,主要ImageView和文本在中心。GridView中第一項的imageView onClick事件無法工作或延遲

我需要爲拐角處的兩個ImageView和適配器的OnItemClickListener設置OnClickListener。

一切正常,但只有GridView中的第一項無法觸發OnClickListener。有誰能解決這個問題嗎?

P.S.我發現,當我做下一個動作的第一個項目的ImageView OnClickListener會觸發(例如,點擊其他項目)

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    View v = convertView; 
    TagView tag; 
    if (convertView == null) { 
     v = m_LayoutInflater.inflate(R.layout.mydoc_grid_item, null); 
     tag = new TagView(
       (ImageView) v.findViewById(R.id.myDoc_GridItem_IV), 
       (TextView) v.findViewById(R.id.myDoc_GridItem_TV), 
       (ImageView) v.findViewById(R.id.iViewAdd2Category), 
       (ImageView) v.findViewById(R.id.iViewDelete)); 
     v.setTag(tag); 
    } else { 
     tag = (TagView) v.getTag(); 
    } 

    v.setLayoutParams(new GridView.LayoutParams((int) (180 * v 
      .getResources().getDisplayMetrics().density), (int) (180 * v 
      .getResources().getDisplayMetrics().density))); 


    tag.image.setScaleType(ImageView.ScaleType.CENTER_CROP); 
    tag.image.setImageDrawable(new BitmapDrawable(BitmapFactory.decodeFile(m_DisplayItems.get(position) 
        .get("image").toString()))); 
    tag.text.setText(m_DisplayItems.get(position).get("text").toString()); 
    tag.iAdd2Category.setVisibility((m_IsEdit) ? View.VISIBLE : View.GONE); 
    tag.iDelete.setVisibility((m_IsEdit) ? View.VISIBLE : View.GONE); 
    if (m_IsEdit) { 
     tag.iAdd2Category.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       Log.i(LOG_TAG, "Click on image add 2 category"); 
      } 
     }); 

     tag.iDelete.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       Log.i(LOG_TAG, "Click on image delete"); 
      } 
     }); 
    } 

    return v; 
} 
+0

我發現它也發生時,該項目只包含圖像和按鈕。 GridView的第一項無法觸發按鈕的onClickListener。 – CheAn

回答

1

我終於在這篇文章中找到了答案。

OnClickListener not working for first item in GridView

在我的情況:

if (convertView == null) { 
    v = m_LayoutInflater.inflate(R.layout.mydoc_grid_item, null); 
    tag = new TagView(
      (ImageView) v.findViewById(R.id.myDoc_GridItem_IV), 
      (TextView) v.findViewById(R.id.myDoc_GridItem_TV), 
      (ImageView) v.findViewById(R.id.iViewAdd2Category), 
      (ImageView) v.findViewById(R.id.iViewDelete)); 
    v.setTag(tag); 
} else { 
    tag = (TagView) v.getTag(); 
} 

只是刪除的if else語句和 「標籤」 每次都會被實例化。

+0

該解決方案有許多性能問題,因爲每次調用getView()時都會調用4次findViewById。 –

1

混合OnClickListenersOnItemClickListeners對列表的項目不能很好地工作。

在你的情況下,你可能應該在你的物品的不同部分使用多個OnClickListeners,根本不使用OnItemClickListener

+0

嗨小提琴手,我只是評論'setOnItemClickListener',但'setOnClickListener'的第一個項目的imageView仍然無法正常工作。 – CheAn

0

選擇文件

<selector xmlns:android="http://schemas.android.com/apk/res/android" > 
    <item android:state_pressed="true" android:drawable="@drawable/gridview_item_shape"></item> 
    <item android:state_pressed="false" android:drawable="@android:color/transparent"></item> 
</selector> 

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    > 

    <ImageView 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:id="@+id/griditem" 
     android:padding="2dp" 
     android:src="@drawable/grid_photo" 
     android:layout_centerInParent="true" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:background="@drawable/gridview_item_select" 
     /> 
</RelativeLayout> 
1

的原因的問題是,Android的第一個項目調用getView()繪製視圖不僅在項目佈局文件,但也適用於佈局測量!在度量調用和繪製調用之間,getView()中沒有任何區別。所以當你第一次有一個平局的時候,在稍後的一個小節中你會調用你覆蓋onClickListener。 其實這似乎是對的 - 因爲你每次都這樣做,但我觀察到了這種行爲。也許你設置了clickListener,並且系統在getView調用之後釋放它,因爲這個視圖不會被繪製...我沒有足夠深入地追蹤這個視圖。

不過,每次重新創建視圖是一個壞主意,因爲它非常耗時 - 您的網格可能不會平滑滾動。

解決的辦法是寫自己的GridView如下:

public class MyGridView extends GridView{ 
private GridAdapter adapter; 


public MyGridView(Context context) { 
    super(context); 
} 

public MyGridView(Context context, AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 
} 

public MyGridView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
} 

public void setAdapter(GridAdapter adapter) { 
    this.adapter = adapter; 
    super.setAdapter(adapter); 
} 

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    if(adapter!=null) 
     adapter.setIsMeasureCall(); 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
}} 

和實施方法setIsMeasureCall()在你的GridAdapter。該方法只在被調用時纔將標誌設置爲true。 然後在你的getView()方法中,檢查它是否是一個度量調用,如果這是真的 - 你不設置監聽器。

確保在getView()方法的末尾將isMeasure設置爲false。

我希望一切都清楚了:)

因爲你可以看看我的首頁,在這裏我提供一個完整的Android項目,解決了此問題的詳細信息。 http://simon.osim.at/projects/gridadapter/#TheSolution