2012-12-29 63 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) 再次感谢! –

相关问题