我有一个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)
答案 0 :(得分:2)
IndexOutOfBoundsException
由mProgress
引起,mTitles
为空,而ListView
则不是。处理getCount()
上的多个集合可能会非常棘手,因为您始终要确保所有集合的大小至少为 public class MyModel {
public String name;
public boolean isChecked
}
。这当然是可能的,但是容易出错。您可以做的是将所有信息包装在Model类中。例如。
List<String> mTitles
并从List<MyModel> mTitles
更改为shell_exec
。这样,您只能处理一个集合,并轻松检索和更改位置