我正在关注此事 http://velosmobile.com/2013/04/03/enhanced-sectioned-grid-with-varying-columns/ 在我的示例中的教程,但我有每个列表项的复选框。我想检查项目,然后将所有选中的项目发送到另一个活动。
问题是当我滚动listview时,调用自定义适配器的getview()并更改列表项的位置。 用简单的话来说就是
mCheckBox.setOnCheckedChangeListener()
滚动列表视图时会调用,我不想调用它。 以下是我的代码。任何帮助将不胜感激
@Override
public View getView(int position, View convertView, ViewGroup parent) {
int realPosition = 0;
int viewsToDraw = 0;
int rows = 0;
int totalCount = 0;
for (int i = 0; i < sectionsCount; ++i)
{
int sectionCount = getCountInSection(i);
totalCount += sectionCount;
if (sectionCount > 0 && position <= rows + (sectionCount - 1) / colCount)
{
realPosition += (position - rows) * colCount;
viewsToDraw = (int)(totalCount - realPosition);
break;
}
else
{
if (sectionCount > 0)
{
rows += (int)((sectionCount - 1) / colCount + 1);
}
realPosition += sectionCount;
}
}
if (convertView == null)
{
convertView = inflater.inflate(rowResID, parent, false);
if (measuredRow == null && resizeMode == MODE_VARY_COUNT)
{
measuredRow = (ViewGroup)convertView;
// In this mode, we need to learn how wide our row will be, so we can calculate
// the number of columns to show.
// This listener will notify us once the layout pass is done and we have our
// measurements.
measuredRow.getViewTreeObserver().addOnGlobalLayoutListener(layoutObserver);
}
}
int lastType = -1;
if (realPosition > 0)
lastType = getTypeFor(realPosition-1);
if (getDataCount() > 0)
{
TextView header = (TextView)convertView.findViewById(headerID);
int newType = getTypeFor(realPosition);
if (newType != lastType)
{
header.setVisibility(View.VISIBLE);
header.setText(getHeaderForSection(newType));
}
else
{
header.setVisibility(View.GONE);
}
}
customizeRow(position, convertView);
ViewGroup itemHolder = (ViewGroup)convertView.findViewById(itemHolderID);
for (int i = 0; i < itemHolder.getChildCount(); ++i)
{
View child = itemHolder.getChildAt(i);
if (i < colCount && i < viewsToDraw && child != null)
{
bindView(child, realPosition + i);
child.setVisibility(View.VISIBLE);
}
else if (child != null)
{
child.setVisibility(View.INVISIBLE);
}
}
return convertView;
}
bindView()函数的代码如下
@Override
protected void bindView(View convertView, int position) {
String title;
ConfiguredItem myDevice = (ConfiguredItem) getItem(position);
myDevices.add(myDevice);
title = myDevice.getTitle();
TextView label = (TextView) convertView.findViewById(R.id.bookItem_title);
CheckBox mCheckBox = (CheckBox) convertView.findViewById(R.id.checkBox);
mCheckBox.setTag(position);
mCheckBox.setChecked(mSparseBooleanArray.get(position));
mCheckBox.setOnCheckedChangeListener(mCheckedChangeListener);
label.setText(title);
TypedArray imgTitle = myContext.getResources().obtainTypedArray(
R.array.colors);
String[] myColors = myContext.getResources().getStringArray(
R.array.colors);
int idx = new Random().nextInt(imgTitle.length());
String random = (myColors[idx]);
int color = Color.parseColor(random);
convertView.setBackgroundColor(color);
}
CompoundButton.OnCheckedChangeListener mCheckedChangeListener = new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mSparseBooleanArray.put((Integer) buttonView.getTag(),
isChecked);
}
};
答案 0 :(得分:0)
尝试更快的解决方案:删除if (convertView == null)
始终创建新的convertView。这不是一个好习惯,但可以帮助你找到bug。
答案 1 :(得分:0)
回收视图很棘手。当您重用视图时,需要重新初始化所有内容。例如,如果您在视图的一个版本中设置复选框的状态,然后在以后重复使用它,则您需要再次设置复选框状态,否则它将具有上次的状态。
我无法从您的代码中了解我是否正在解决您的问题 - 您没有显示成员变量,而且还有很多代码似乎并不存在与单元视图的初始化有关。如果我的解决方案不够充分,请尝试将您提供的代码减少到与问题相关的小部分。
答案 2 :(得分:0)
试试这个
mCheckBox.setTag(position);
mCheckBox.setOnCheckedChangeListener(null);
mCheckBox.setChecked(mSparseBooleanArray.get(position));
mCheckBox.setOnCheckedChangeListener(mCheckedChangeListener);
并在你的方法getView中 找到复选框并执行相同的操作
mCheckBox.setOnCheckedChangeListener(空);