带有自定义适配器的ListView - 当列表为空时,IndexOutOfBoundsException

时间:2016-02-08 11:44:08

标签: android listview custom-adapter

我有一个List,其中我存储了一些从服务器获取的字符串。我有ListView的自定义适配器。每个项目都有一个TextView和一个Switch。

在onCreate方法中,列表将为空,在从服务器收到数据后,我在适配器上调用notifyDataSetChanged。

我的查询特定于Switch(或类似情况下的Checkbox)。请看下面的代码。我会尽力用引号解释它。

public class DetailDOMActivity extends AppCompatActivity {

   ListView listview;
   DealofTheMonthAdapter mDealofTheMonthAdapter;
   List<String> mTitles = new ArrayList<String>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_detail_dom);
      ....
      ....

      // Clearing the List before getting values from server
      mTitles.clear();

      listview = (ListView) findViewById(R.id.listView);

      // If i remove the below 2 lines, 
      // and add them after getting the data from server,
      // everything works fine.

      // My query here is, when the list is empty,
      // and when getCount() in adapter returns 0,
      // why is getView() being called? 
      // Is this the normal behaviour?
      mDealofTheMonthAdapter = new DealofTheMonthAdapter(this);
      listview.setAdapter(mDealofTheMonthAdapter);

      // Gets Values from server and
      // stores them in mTitles List.  
      // At the end notifyDataSetChanged() 
      // is called on the adapter 
      getDataFromServer();
    }   

   private class DealofTheMonthAdapter extends BaseAdapter {

    final Context context;

    List<Boolean> mProgress = new ArrayList<Boolean>();

    public DealofTheMonthAdapter(Context context) {
        this.context = context;
        mProgress.clear();
    }


    @Override
    public int getCount() {
        return mTitles.size();
    }


    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

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

        final ViewHolder holder;


        if (convertView == null) {
            convertView = LayoutInflater.from(context).inflate(R.layout.item_detail_dom, null);

            holder = new ViewHolder();
            holder.mTextView = (TextView) convertView.findViewById(R.id.textView);
            holder.mImageView = (ImageView) convertView.findViewById(R.id.imageView);
            holder.mSwitch = (SwitchCompat) convertView.findViewById(R.id.switch_dom);

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.mTextView.setText(mTitles.get(position));
        holder.mSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

                if (isChecked)
                    mProgress.set(position, true);
                else
                    mProgress.set(position, false);
            }
        });

        // IndexOutOfBoundsException at the below line
        holder.mSwitch.setChecked(mProgress.get(position));

        return convertView;
    }
}

public static class ViewHolder {

    TextView mTextView;
    ImageView mImageView;
    SwitchCompat mSwitch;
}

}

据我所知,将根据getCount()返回的计数调用getView()。因此,当列表为空时,它应该返回0,因此不应该调用getView()。

有人可以解释一下这种行为吗?如果您还有其他需要,请告诉我。

logcat的:

java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
                                                                         at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
                                                                         at java.util.ArrayList.get(ArrayList.java:308)
                                                                         at com.xxx.xx.DetailDOMActivity$DealofTheMonthAdapter.getView(DetailDOMActivity.java:285)
                                                                         at android.widget.AbsListView.obtainView(AbsListView.java:2346)
                                                                         at android.widget.ListView.measureHeightOfChildren(ListView.java:1281)

1 个答案:

答案 0 :(得分:2)

IndexOutOfBoundsExceptionmProgress引起,mTitles为空,而ListView则不是。处理getCount()上的多个集合可能会非常棘手,因为您始终要确保所有集合的大小至少为 public class MyModel { public String name; public boolean isChecked } 。这当然是可能的,但是容易出错。您可以做的是将所有信息包装在Model类中。例如。

List<String> mTitles

并从List<MyModel> mTitles更改为shell_exec。这样,您只能处理一个集合,并轻松检索和更改位置

项目的属性