Android开发ListView中含有checkBox或者Button时会遇到的难题

来源:互联网 发布:淘宝分享好友链接代码 编辑:程序博客网 时间:2024/04/29 02:44

<iframe id="cproIframe_935282_2" width="300" height="250" src="http://cb.baidu.com/ecom?adn=3&amp;at=231&amp;aurl=&amp;cad=1&amp;ccd=32&amp;cec=UTF-8&amp;cfv=11&amp;ch=0&amp;col=zh-CN&amp;conOP=0&amp;cpa=1&amp;dai=2&amp;dis=0&amp;ltr=http%3A%2F%2Fwww.baidu.com%2Fs%3Fie%3Dutf-8%26f%3D8%26rsv_bp%3D1%26tn%3Dbaidu%26wd%3Dlistview%2520itemt%2520%25E5%2590%25AB%25E6%259C%2589checkbox%26rsv_pq%3D816eaee10010c332%26rsv_t%3D584cnTyNnwngxcvGlRWfW3dNxh7KPKcQudpqjMe9i77n9EF33fFRdPt7MTU%26rsv_enter%3D0%26inputT%3D6316%26sug%3Dlistview%26oq%3Dlistvie%26rsv_sug3%3D85%26rsv_sug1%3D14%26rsv_sug2%3D0%26rsv_sug4%3D12065%26rsv_sug%3D1&amp;ltu=http%3A%2F%2Fwww.bingfengsa.com%2Fa%2F20131207%2F1171.html&amp;lunum=6&amp;n=55025008_cpr&amp;pcs=1093x573&amp;pis=10000x10000&amp;ps=595x713&amp;psr=1366x768&amp;pss=1093x631&amp;qn=a5c784b3df77f5f6&amp;rad=&amp;rs=300&amp;rsi0=300&amp;rsi1=250&amp;rsi5=4&amp;rss0=%23FFFFFF&amp;rss1=%23FFFFFF&amp;rss2=%230000ff&amp;rss3=%23444444&amp;rss4=%23008000&amp;rss5=&amp;rss6=%23e10900&amp;rss7=&amp;scale=&amp;skin=&amp;td_id=9223372032564518175&amp;tn=text_default_300_250&amp;tpr=1428767310915&amp;ts=1&amp;xuanting=0&amp;dtm=BAIDU_DUP2_SETJSONADSLOT&amp;dc=2&amp;di=935282" align="center,center" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" allowtransparency="true" style="margin: 0px; padding: 0px; "></iframe>
   android开发经常会遇到ListView中含有checkBox和Button的情况,这里主要会有三个问题,下面分别论述:

       1.         ListView中含有checkBox或者Button时,listView的item无法响应点击事件,这主要是因为checkBox和Button等获取焦点的能力高于listView,此时应该让其子控件不能获取焦点,即在布局文件中设置子控件属性android:focusable="false"或者在listView的adapter的布局中加入android:descendantFocusability="blocksDescendants"属性,descendantFocusability表示子控件均失去焦点。

       2.      ListView中含有checkBox时,选中CheckBox时,滑动listView会发现有多个选中的checkBox,即发生了错位,这个主要是与adapter的getView方法的机制有关系,即listView的每个界面都显示固定的item数,当滑动时,只是将前一屏的item重新绘制了一遍,这个可以先去了解下自定义adpter的getView的刷新机制。对于这个问题的解决办法是记录下选中的checkBox的位置(这个方法是当点击ListView的item时选中checkBox的前提),在getView中根据选中位置进行设置checkBox的状态。


注意:主要是在adapter中保存一个hashset保存对象,然后checkbox的setcheck()方法要放在checkbox的onitemcheckedchang()监听方法之后,否是会先设置checkbox的状态而发生选中错位。


具体代码见下面:

   

public class ScheduleItemsAdapter extends BaseAdapter {

  private List<ScheduleItem> scheduleItems;
  private LayoutInflater inflater;
  private Context ctx;
  private Callback callBack ;
  private boolean onlineFlag = false ;


  private Set<ScheduleItem> checkeds = new HashSet<ScheduleItem>();


  boolean showAddressFlag = false;
  public interface Callback {
   public void callbackCheckbox(boolean isChecked , int position);
   public void callbackItems(int position);
   public void callbackOnOff(boolean isChecked , int position);
   public void callbackColor(int position);
   public void callackTimes(int position );
 }
  
  public ScheduleItemsAdapter(Context context, List<ScheduleItem> ScheduleItem , boolean onlineFlag) {
    this.ctx = context;
    this.onlineFlag = onlineFlag;
    this.scheduleItems = new ArrayList<ScheduleItem>();
    this.scheduleItems.clear();
    if (scheduleItems != null)
      this.scheduleItems.addAll(scheduleItems);
    inflater = LayoutInflater.from(context);
    
  }


  public void setCallBack(Callback callBack ){
 this.callBack = callBack ;
  }
  
  public void notificationLightListChange(List<ScheduleItem> ScheduleItem) {
    this.scheduleItems.clear();
    if (ScheduleItem != null) {
      this.scheduleItems.addAll(ScheduleItem);
    }
    checkeds.clear();
    notifyDataSetChanged();
  }


  public List<ScheduleItem> getCheckedList() {
 List<ScheduleItem> list = new ArrayList<ScheduleItem>();
 list.addAll(checkeds);
   return list;
  }


  @Override
  public int getCount() {
    // TODO Auto-generated method stub
    return scheduleItems.size();
  }


  @Override
  public Object getItem(int arg0) {
    // TODO Auto-generated method stub
    return scheduleItems.get(arg0);
  }


  @Override
  public long getItemId(int position) {
    // TODO Auto-generated method stub
    return position;
  }


  @Override
  public View getView(final int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub


    ContainerView listItemView = null;
    final ScheduleItem item = scheduleItems.get(position);


    if (convertView == null) {
      convertView = inflater.inflate(R.layout.schedule_mode_item_listview, null);
      listItemView = new ContainerView();
      listItemView.checkbox = (CheckBox) convertView.findViewById(R.id.schedule_mode_listview_checkbox);
      listItemView.sequence = (TextView) convertView.findViewById(R.id.schedule_mode_listview_sequence_number);
      listItemView.itemName = (TextView)convertView.findViewById(R.id.schedule_mode_listview_item_name);
      listItemView.interval = (TextView) convertView.findViewById(R.id.schedule_mode_listview_interval);
      listItemView.changedata = (TextView) convertView.findViewById(R.id.schedule_mode_listview_changedata);
      listItemView.color = (TextView) convertView.findViewById(R.id.schedule_mode_listview_color);
      listItemView.action = (ToggleButton) convertView.findViewById(R.id.schedule_mode_listview_onoff);
      convertView.setTag(listItemView);
      
    } else {
      listItemView = (ContainerView) convertView.getTag();
    }
   
    if(! onlineFlag)
    {
        listItemView.itemName .setVisibility(View.GONE);
    }
    if(item.getScheduleItemId() != -1){
    switch (item.getscheduleItemType() ){
    case ScheduleItem.scheduleItemType_Light:
    listItemView.color .setVisibility(View.VISIBLE);
    listItemView.itemName .setText(LightDAO.getDAO(ctx).findById(item.getScheduleItemId()).getName());
    break;
    case ScheduleItem.scheduleItemType_GROUP:
    listItemView.color .setVisibility(View.VISIBLE);
    listItemView.itemName .setText(GroupDAO.getDAO(ctx).findById(item.getScheduleItemId()).getName());
    break;
    case ScheduleItem.scheduleItemType_SCENE:
    listItemView.color .setVisibility(View.INVISIBLE);
    listItemView.itemName .setText(SceneDAO.getDAO(ctx).findById(item.getScheduleItemId()).getName());
    break;


    default:
    break;
    }
    }else{
    listItemView.itemName .setText("null");
    }
   
    listItemView.sequence.setText(position+1+"");
  
    listItemView.color.setBackgroundColor(Color.rgb((item.getPwmR() & 0xff) *(item.getPwm() & 0xff) /255 , (item.getPwmG() & 0xff) *(item.getPwm() & 0xff) /255, (item.getPwmB() & 0xff) *(item.getPwm() & 0xff) /255));
    if((int)item.getChangeData() < 10){
    listItemView.changedata.setText("0."+(item.getChangeData() & 0xff ));
    }else{
    listItemView.changedata.setText((item.getChangeData() & 0xff )/10 + "");
    }
    
    if((int)item.getintervalTime() < 10){
    listItemView.interval.setText("0."+(item.getintervalTime() & 0xff ));
    }else{
    listItemView.interval.setText(((item.getintervalTime() & 0xff ) )/10 + "");
    }
      
    listItemView.checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
 if (callBack != null) {
         callBack.callbackCheckbox(isChecked, position);
       }
 if (isChecked) {
         checkeds.add(item);
       } else {
        checkeds.remove(item);
       }
}
});


    listItemView.interval.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (callBack != null) {
         callBack.callackTimes(position);
       }
}
});
    
  listItemView.changedata.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (callBack != null) {
callBack.callackTimes(position);
       }
}
});
    listItemView.action.setOnCheckedChangeListener(new OnCheckedChangeListener() {

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
if (callBack != null) {
         callBack.callbackOnOff(isChecked ,position);
}
}
});
    //ToggleButton和checkbox等类的setchecked()方法要放在监听后面,避免误触发
    listItemView.action.setChecked( item.getAction() ==ScheduleItem.ACTION_OFF ? false :true);
    listItemView.color.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (callBack != null) {
         callBack.callbackColor(position);
}
}
});
    listItemView.itemName.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (callBack != null) {
         callBack.callbackItems(position);
}
}
});


    return convertView;
  }


  static class ContainerView {
public CheckBox checkbox ;
    public TextView sequence;
    public TextView itemName;
    public TextView interval;
    public TextView changedata;
    public ToggleButton action;
    public TextView color;


  }


}

3.      ListView中含有Button时,我们有时需要知道点击button位于listView的哪个position下,即要获取item的数据,由于button的click事件是异步的,无法得到点击的位置,这个原因与上面的checkBox类似,这时有一个办法是给button设置Tag,点击时获取tag来判断位置,实现代码如下:

   @Override

    public View getView(int position, ViewconvertView, ViewGroup parent) {

        ListHolderholder;

        if (convertView == null) {

            holder =new ListHolder();

            convertView= mInflater.inflate(R.layout.homework_list_itemnull);

            holder.homeworkUpload =              (Button)convertView.findViewById(R.id.homework_list_btn_uploadhomework);

            convertView.setTag(holder);

        }else {

            holder =(ListHolder) convertView.getTag();

        }

 

            holder.homeworkUpload.setTag(position);

            holder.homeworkUpload.setOnClickListener(new OnClickListener(){

 

                @Override

                publicvoid onClick(View v) {

                 /**

                  上传家庭作业功能暂时屏蔽

                  */

                    Log.i("hubei""click position:"+v.getTag());

Object homework = list.get(Integer.parseInt(""+v.getTag()));

                   

                   

                }

            });

 

        }

        return convertView;

   }

0 0
原创粉丝点击