2015-01-07 33 views
0

我已經創建了具有自定義行的ListView,並且在每個自定義行內,我希望特定的TextView可點擊。在我的自定義適配器的getView方法中,我已經爲我的TextView設置了onClickListener,並根據需要實現了onClick(View v)。這是問題出現的地方。自定義ListView行中的可點擊元素

在onClick(View v)中,我需要關於適配器數據(與getView()的位置參數不同)所點擊的TextView行的位置。閱讀周圍堆棧溢出,這article尤其後,所需的魔碼,以獲得被點擊的TextView中的行的位置是:

final int position = listView.getPositionForView(v); 

此代碼的偉大工程,每次我點擊一個TextView特定行,返回正確的位置。但是,當我旋轉手機以更改配置,然後單擊TextView的任意時,返回的位置始終爲-1。將手機旋轉回原來的配置也保持了在任何TextView被按下時返回-1的行爲。

查看getPositionForView的文檔,如果視圖「不對應於列表項目(或當前不可見)」,則返回-1(INVALID_POSITION)。這是爲什麼發生?顯然,對於我來說,即使能夠點擊TextView,視圖也必須在屏幕上可見。

如果很重要,我使用convertView和ViewHolder模式來優化ListView。

我錯過了什麼?

更新: 只是爲了幫助更好的可視化,這裏是我的getView大致樣子

getView(int position, View convertView, ViewGroup parent) { 
     final CustomViewHolder holder; 
     View = rowView; 
     if (convertView == null) { 
      rowView = inflater.inflate(R.layout.listitem, parent, false); 
      holder = new CustomViewHolder(rowView); 

      holder.textview.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        final int position = listView.getPositionForView(v); 
        //position is always -1 after configuration change 
        Log.d(TAG, "Like button pushed at position: " + position); 

       } 
      }); 
      rowView.setTag(postHolder); 
     } else { 
      rowView = convertView; 
      postHolder = (PostListUserPostHolder) convertView.getTag(); 
     } 

     //fill list item with data 
    } 
    return rowView; 
} 

更新#2 我似乎已經走到了一個解決方案。我沒有將片段引用傳遞給適配器,而是將對片段本身的引用傳遞給適配器。然後我在獲得的ListView片段提供一個getter方法,然後使用該行:

final int position = fragment.getListView().getPositionForView(v); 

我會一直認爲這是基本相同的,因爲我是做什麼,但現在看來,這是不案件。如果任何人都可以闡明可能發生的事情,我們將不勝感激。否則,我很高興代碼現在能夠按預期工作!

回答

0
getView(int position, View convertView, ViewGroup parent) { 
     final CustomViewHolder holder; 

    if (convertView == null) { 
     rowView = inflater.inflate(R.layout.listitem, parent, false); 
     holder = new CustomViewHolder(); 
     convertView .setTag(holder); 
    } 
    else { 

     holder= (CustomViewHolder) convertView.getTag(); 
    } 

     holder.textview.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       final int position = listView.getPositionForView(v); 
       //position is always -1 after configuration change 
       Log.d(TAG, "Like button pushed at position: " + position); 

      } 
     }); 

    } 

    //fill list item with data 
} 
return convertView; 

}

0

你getView()是有點怪。持有人的字段textview從未初始化?

持有人的用處是限制方法findViewById的使用。

這裏是骷髏,我會用:

static class ViewHolder { 
    public TextView textview; 
} 

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

    // reuse views 
    if (rowView == null) { 
     LayoutInflater inflater = context.getLayoutInflater(); 
     rowView = inflater.inflate(R.layout.listitem, null); 
     // configure view holder 
     ViewHolder viewHolder = new ViewHolder(); 
     viewHolder.textview= (TextView) rowView.findViewById(R.id.textview); 
     rowView.setTag(viewHolder); 
    } 
    else { 

     ViewHolder holder = (ViewHolder) rowView.getTag(); 
    } 

    // fill data 
    holder.textview.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      final int position = listView.getPositionForView(v); 
      //position is always -1 after configuration change 
      Log.d(TAG, "Like button pushed at position: " + position); 

     } 
    }); 

    return rowView; 
} 
} 

希望它解決您的問題!

祝您有個美好的一天!

+0

是的,ViewHolder的所有findViewById都在一個單獨的類中,因此它們不是用getView()編寫的。我似乎找到了解決方案,所以我會更新OP。 – coldbuffet

相關問題