1. 程式人生 > >【Android疑難雜症】GridView動態設定Item的寬高導致第一個Item不響應或顯示不正常的問題

【Android疑難雜症】GridView動態設定Item的寬高導致第一個Item不響應或顯示不正常的問題

在使用Android的GridView控制元件時,很多人都會碰到這麼個奇怪的問題:整個GridView中,所有item的響應都沒問題,只有第一個item不響應,或是顯示不正常,或是點完第一個item後不響應但再點其他的item後其他item會響應、同時第一個item也響應了(超詭異的現象……),stackoverflow上有不少帖子,如下面的帖子:

至少就我所看到的,出現第一個item有問題的情況,一般都有使用BaseAdapter,而出問題的地方一般都是getView的書寫有問題,稍微整理歸納一下可能的解決方法,供大家參考:

  1. 檢查getView方法中是否有動態設定LayoutParams的操作,如果有,那麼 注意不能new 一個新的LayoutParams,而應該呼叫getLayoutParams獲取已有的LayoutParams 。參見該帖中的最佳答案:
    http://www.4byte.cn/question/337904/android-gridview-checkbox-of-the-first-item-not-work-when-i-recycled-convertview.html
       。如果getLayoutParams返回為空或是返回的LayoutParams不是AbsListView.LayoutParams,那就在getView之前用setLayoutParams方法設定一下。
  2. listener響應有問題:嘗試使用GridView的onItemClickListener,如果是onItemClickListener響應有問題,檢查setOnItemClickListener是否在setAdapter之後。儘量不要採用給每個item的View加onClickListener的方式,如果必須使用該方式,並且採用了ViewHolder的寫法複用View,那麼需要注意加onClickListener的位置,是加在convertVew==null的地方還是外面我就記不清了,我沒試過,只看到有一個帖子說過這個。
  3. 如果還有問題,我看到的可能的解決方法有(沒試過,不確定是否可行,但有人在相關帖子裡提到的各種方法):(1)不用ViewHolder寫法,每次getView都重新建立新的View    (2)GriView設定背景色為透明

但就我感覺,想要動態設定GridView的item寬、高,但直接new LayoutParams導致出問題的出現次數比較多,大家注意一下,具體為啥會這樣就沒細究了,有興趣的童鞋歡迎討論一下。

本人最終解決方法:把動態設定GridView的item寬、高的程式碼放在第一次訪問;

    @Override
public View getView(int position, View convertView, ViewGroup parent) {


if (convertView == null) {
            convertView = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_feed_grid_item, parent, false);
            convertView.findViewById(R.id.avatar).setOnClickListener(new View.OnClickListener() {
                @Override
publicvoid onClick(View v) {
//startActivity                }
            });
        }

convertView.setLayoutParams(new GridView.LayoutParams(mWindowWidth / 3, mWidowWidth / 3));

//其他程式碼return convertView;
    }

  @Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
            convertView = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_feed_grid_item, parent, false);
convertView.setLayoutParams(new GridView.LayoutParams(mWindowWidth / 3, mWindowWidth / 3));
            convertView.findViewById(R.id.user_avatar).setOnClickListener(new View.OnClickListener() {
                @Override
publicvoid onClick(View v) {
//startActivity                }
            });
        }

//其他程式碼return convertView;
    }