我的應用程序活動顯示了一個列表視圖,通過一個BaseAdapter的自定義實現 填充。項目由一個progressBar和一個CheckBox組成。BaseAdapter.notifyDataSetChanged()隱藏用戶的點擊
progressBars值由後臺線程通過使用調用BaseAdapter.notifyDataSetChanged()的Handler來更新。 在這個應用程序中,用戶應該能夠檢查複選框。
問題是,它似乎notifyDataSetChanged()隱藏或關閉用戶對CheckBox的點擊。 會發生什麼事是onClickListener.onClick()被稱爲類似用戶點擊的1/5。
在開始時,我認爲由BaseAdapter.getView()設置的值會覆蓋由用戶在CheckBox上的點擊設置的任何值。於是,我就在getView(像這樣):
if (checkBox.isChecked != data.isChecked(){
checkBox.setOnCheckedChangeListener(null);
checkBox.setChecked(data.isChecked());
checkBox.setOnCheckedChangeListener(cbClickListener);
}
有沒有變化,加入了日誌中onClickListener.onClick()清楚地表明的onClick不叫每次。 我該怎麼辦?
這裏的適配器代碼,這是非常經典:
class InputsConfAdapter extends BaseAdapter {
private static LayoutInflater inflater = null;
private final Model model;
private final inputsConfAdapterInterface handler;
private int[] positions;
//---------------------------------------------------------------------------------------------------
class CbClickListener implements CheckBox.OnCheckedChangeListener{
int inputId;
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
handler.setFailSafe((byte) inputId, isChecked);
}
}
//---------------------------------------------------------------------------------------------------
public InputsConfAdapter(LayoutInflater inflater, Model model, inputsConfAdapterInterface handler) {
super();
InputsConfAdapter.inflater = inflater;
this.handler = handler;
this.model = model;
}
@Override
public int getCount() {
return model.inputs.length;
}
@Override
public Object getItem(int i) {
return i;
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (view == null) {
view = inflater.inflate(R.layout.theIem, null);
ViewHolder viewHolder = new ViewHolder();
viewHolder.pbPosition = (ProgressBar) view.findViewById(R.id.pbPosition);
viewHolder.checkBox = (CheckBox) view.findViewById(R.id.cb);
final CbClickListener cbClickListener = new CbClickListener();
viewHolder.checkBox.setOnCheckedChangeListener(cbClickListener);
viewHolder.cbClickListener = new CbClickListener();
view.setTag(viewHolder);
}
final ViewHolder viewHolder = (ViewHolder) view.getTag();
final CheckBox checkBox = viewHolder.checkBox;
final ProgressBar pbPosition = viewHolder.pbPosition;
final CbClickListener cbClickListener = viewHolder.cbClickListener;
final Input data = model.inputs[i];
//--- progressBar
if (positions != null)
pbPosition.setProgress(positions[i]);
//--- checkBox
cbClickListener.inputId = i;
checkBox.setOnCheckedChangeListener(null);
checkBox.setChecked(data.isChecked());
checkBox.setOnCheckedChangeListener(cbClickListener);
return view;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public int getViewTypeCount() {
return 1;
}
public void serPositions(int[] positions) {
this.positions = positions;
}
private class ViewHolder {
public CheckBox checkBox;
public ProgressBar pbPosition;
CbClickListener cbClickListener;
public ViewHolder() {
}
}
public interface inputsConfAdapterInterface {
void setFailSafe(byte inputId, boolean value);
}
}
更新@Khaled:在接收列表視圖的片段。 有一個「同步」:
private final Synchronizer synchronizer = new Synchronizer(new Handler(), new DefaultListener() {
@Override
public void ValuesReceived(ValueStruct values) {
if (getActivity() != null) {
adapter.serPositions(values.values);
adapter.notifyDataSetChanged();
}
}
});
的更新線程調用synchronizer.valuesReceived(),該職位在處理程序可運行在 GUI線程實例化:
public interface ISink {
void ValueReceived(
ValueStruct inputValue
);
}
public class defaultListener implements ISink {
}
public class Synchronizer implements ISink {
private ISink sink;
private Handler handler;
public Synchronizer(Handler handler, ISink sink) {
this.handler = handler;
this.sink = sink;
}
private class ValueRunnable implements Runnable {
ValueStruct s;
ValueRunnable(ValueStruct s) {
this.s = new ValueStruct(s);
}
@Override
public void run() {
sink.ValuesReceived(s);
}
}
@Override
public void ValuesReceived(ValueStruct s) {
handler.post(new ValueRunnable(s));
}
}
當您通過您的列表中滾動出現這種情況? –
也不是特別的。它總是發生。 – Julien