2012-12-29 62 views
3

我有一個自定義的row_item ListViews與圖像,一對TextViews和一個複選框。 從我所瞭解的情況來看,由於checkBox是一個可聚焦的元素,它會從listView中竊取焦點,所以OnListItemClicked永遠不會被觸發,除非我將每個row_item設置爲不可點擊,並阻止後代的可聚焦性。arrayAdapter中的監聽器getView方法

然後,爲了管理checkBoxes的變化,我在我的適配器getView方法中爲我的checkBoxes設置了一個「OnCheckedChangeListener」。

這是不是這樣做的壞方法? (因爲我每次調用getView時都會創建新的監聽器) 是否有其他方法來執行此操作?

我附上一些代碼,以便更容易理解我的意思。

getView方法:(內側arrayAdapter)

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

    /** recycling views */ 
    View row = convertView; 
    PregoHolder holder = null; 

    if(row == null) 
    { 
     LayoutInflater inflater = ((Activity)context).getLayoutInflater(); 
     row = inflater.inflate(layoutResourceId, parent, false); 

     holder = new PregoHolder(); 
     holder.imgIcon = (ImageView)row.findViewById(R.id.thumbnail); 
     holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle); 
     holder.txtNews = (TextView)row.findViewById(R.id.txtNews); 
     holder.chBox = (CheckBox) row.findViewById(R.id.checkBox); 

     row.setTag(holder); 
    } 
    else 
    { 
     holder = (PregoHolder)row.getTag(); 
    } 

    Prego Prego = data[position]; 
    holder.txtTitle.setText(Prego.title); 
    holder.imgIcon.setImageResource(Prego.icon); 
    holder.txtNews.setText(Prego.news); 
    holder.chBox.setChecked(Prego.checked); 

    /** wiring up Listeners... 
    * (works fine but we are creating new listener each time) 
    * (Done like this because of the custom list view focusable issue) 
    */ 

    holder.chBox.setOnCheckedChangeListener(new OnCheckedChangeListener(){ 

     @Override 
     public void onCheckedChanged(CompoundButton arg0, boolean checked) { 
      /** Getting the view position in the ListView */ 
      ListView parent = (ListView)(arg0.getParent()).getParent(); 
      int pos = parent.getPositionForView(arg0); 

      if (checked){ 
       checkedPregons[pos] = true; 
       pregonsChecked++; 
      } 
      else if (!checked){ 
       checkedPregons[pos] = false; 
       pregonsChecked--; 
      } 

      Toast.makeText(context, pregonsChecked+" is/are checked", Toast.LENGTH_SHORT).show(); 
     } 
    }); 

    row.setOnClickListener(new OnClickListener(){ 

     @Override 
     public void onClick(View v) { 
      //mMode = ((Activity)context).startActionMode(new PregonsActionModes()); 
      ListView parent = (ListView)v.getParent(); 
      int pos = parent.getPositionForView(v); 
      Toast.makeText(context, "getView should show prego "+pos,Toast.LENGTH_SHORT).show(); 

     } 
    }); 

    return row; 
} 

預先感謝。

+0

你需要使listview的其他元素可點擊嗎?你能鑽出來嗎?如果這兩者都是負面的,那麼在行點擊上切換選中的狀態可能會更好。 – dmon

+0

我需要使列表項可點擊,所以當您在複選框外按下時,但在一行內部它會打開另一個活動。 我也嘗試用行點擊來管理這個,但是當我只在複選框內按下時,沒有偵聽器被觸發。 (所以我不得不先切換複選框的狀態,然後點擊行...) 這就是爲什麼我決定這樣做... –

回答

3

我想可能有更好的辦法去做,但這不是我會失眠的事。你的方法被許多新老版本的android開發者瘋狂地實現,而這只是一種自然而然的方式。此外,請記住,ListView只有一次可以在屏幕上看到的行數(在滾動時不斷調用getView),因此您在任何給定時間都會討論8-12個製成的對象(顯然完全猜測),所以你的瓶頸不會在這裏。實際上,根據我需要修改的對象的位置,我甚至不考慮它。

ListView使用OnCheckedChangeListener東西我會嚴重警惕。就像我說的那樣,getView被每一行調用,因爲它正在滾動和製作。這檢查改變的監聽器正在被解僱,就像它正在製作,儘管絕對沒有保證getView被稱爲一次爲每一行,實際上我保證,否則。因此,這些代碼塊可能會在wazoo上被激發,儘管您可能只是在手動處理CheckBox box tick時纔打算這樣做。把一個相對更密集的命令,如notifyDataSetChanged(),你會看到你的ListView鎖定這種現象。

解決方案是簡單地使用複選框onClickListener,而不是檢查isChecked()裏面。

+0

很棒!感謝您的回答!我認爲在最壞的情況下,它只會像你說的那樣只是幾個對象而已,但我擔心如果我做了其他我從來沒有想過的錯誤。 (如onCheckedChangeListener) 再次感謝! –

相關問題