我一直在寻找关于堆栈的指南,教程和答案,但我仍然无法想出这个。
我有一个自定义绘制状态。如果我点击ListView
中的一行,它会突出显示并在数据库中更新此信息。 (已完成任务(习惯))。一切都很好,直到我开始滚动。我了解到,需要覆盖getView()
方法,而getItemViewType()
可能会覆盖getViewTypeCount()
。
如何正确地做到这一点?我目前使用getView()和其他提到的方法的HabitsCursorAdapter代码看起来像这样。
public class HabitsCursorAdapter extends CursorAdapter {
private LayoutInflater inflater;
private Context context;
public static final int PERFORMED = 1;
public static final int NOT_PERFORMED = 0;
public HabitsCursorAdapter(Context context, Cursor c) {
super(context, c, 0);
inflater = LayoutInflater.from(context);
this.context = context;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
String habitName = cursor.getString(cursor
.getColumnIndexOrThrow(SQLiteHabitHelper.COLUMN_NAME));
TextView habitNameTV = (TextView) view.findViewById(R.id.habit_name);
habitNameTV.setText(habitName);
/******************* OK ***********************/
ImageButton editButton = (ImageButton) view.findViewById(R.id.habit_edit_button);
Integer _id = cursor.getInt(cursor.getColumnIndexOrThrow(SQLiteHabitHelper.COLUMN_ID));
editButton.setTag(R.id.EDITED_HABIT_ID, _id);
view.setTag(_id);
editButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(HabitsCursorAdapter.this.context,
HabitDetailActivity.class);
i.putExtra("_id", (Integer) v.getTag(R.id.EDITED_HABIT_ID));
HabitsCursorAdapter.this.context.startActivity(i);
}
});
ImageButton deleteButton = (ImageButton) view
.findViewById(R.id.habit_history_button); // NEED TO REWRITE TO DELETING BUTTON
deleteButton.setTag(R.id.EDITED_HABIT_ID, _id);
deleteButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//itemized due debugging issue
HabitListActivity hla = ((HabitListActivity) HabitsCursorAdapter.this.context);
Object o = v.getTag(R.id.EDITED_HABIT_ID);
Integer i = (Integer) o;
long l = i.longValue();
hla.delete(l);
}
});
/******************* OK **********************/
HabitListItemView hv = (HabitListItemView) view;
hv.setHabitPerformed(
(1 == cursor.getInt(cursor.getColumnIndexOrThrow(SQLiteHabitHelper.COLUMN_PERFORMED))) ? true : false
);
view.refreshDrawableState();
}
@Override
public View newView(Context context, Cursor c, ViewGroup container) {
HabitListItemView v = (HabitListItemView) inflater.inflate(
R.layout.habit_item_layout, container, false);
bindView(v, context, c);
return v;
}
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public int getItemViewType(int position) {
Cursor c = (Cursor) getItem(position);
c.moveToPosition(position);
int value = c.getInt(c.getColumnIndexOrThrow(SQLiteHabitHelper.COLUMN_PERFORMED));
if(0 != value){
return PERFORMED;
}
return NOT_PERFORMED;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (!mDataValid) {
throw new IllegalStateException("this should only be called when the cursor is valid");
}
if (!mCursor.moveToPosition(position)) {
throw new IllegalStateException("couldn't move cursor to position " + position);
}
View v;
if (convertView == null) {
v = newView(mContext, mCursor, parent);
return v;
} else {
mCursor.moveToPosition(position);
HabitListItemView hv = (HabitListItemView) convertView;
int convertViewIsPerformed = hv.getHabitPerformed() ? 1 : 0;
int actualItemPerformed = getItemViewType(position);
if(actualItemPerformed == convertViewIsPerformed){
v = convertView;
bindView(v, mContext, mCursor);
return v;
}else{
v = newView(mContext, mCursor, parent);
return v;
}
}
}
}
自定义行视图为:
public class HabitListItemView extends RelativeLayout {
private static final int[] STATE_HABIT_PERFORMED = { R.attr.state_habit_performed };
private boolean performed;
public HabitListItemView(Context context) {
this(context, null);
}
public HabitListItemView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
loadViews();
}
public HabitListItemView(Context context, AttributeSet attributeSet,
int defStyle) {
super(context, attributeSet, defStyle);
loadViews();
}
private void loadViews() {
setBackgroundResource(R.drawable.habit_list_item_background);
}
@Override
protected int[] onCreateDrawableState(int extraSpace) {
if (performed) {
final int[] drawableState = super
.onCreateDrawableState(extraSpace + 1);
mergeDrawableStates(drawableState, STATE_HABIT_PERFORMED);
return drawableState;
} else {
return super.onCreateDrawableState(extraSpace);
}
}
public void setHabitPerformed(boolean performed) {
this.performed = performed;
refreshDrawableState();
}
public boolean getHabitPerformed() {
return performed;
}
}
和ListFragment中的onListItemClick()
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
HabitListItemView hv = (HabitListItemView) v;
ContentValues cv = new ContentValues();
String habitId = v.getTag().toString();
SQLiteDatabase db = dh.getWritableDatabase();
Cursor cPerfomed = db.query(SQLiteHabitHelper.TABLE_HABIT,
new String[]{SQLiteHabitHelper.COLUMN_ID, SQLiteHabitHelper.COLUMN_PERFORMED},
"_id = ?", new String[]{habitId}, null, null, null);
cPerfomed.moveToFirst();
int performed = cPerfomed.getInt(cPerfomed.getColumnIndexOrThrow(SQLiteHabitHelper.COLUMN_PERFORMED));
cPerfomed.close();
cv.put(SQLiteHabitHelper.COLUMN_ID, (Integer) v.getTag());
cv.put(SQLiteHabitHelper.COLUMN_PERFORMED, (performed == 0) ? 1 : 0);
db.update(SQLiteHabitHelper.TABLE_HABIT, cv, "_id = ?", new String[]{habitId});
db.close();
hv.setHabitPerformed((performed == 0) ? true : false);
}
有关如何以及何时调用覆盖方法的详细解释可能有助于我解决问题。我认为,newView和bindView只能被getView调用,因此我相信我可以通过我的覆盖getView来控制它。但是getItemViewType和getViewTypeCount是由我没有实现的方法调用的,我不明白为什么以及如何使用结果。也许他们会引起问题。
如果需要更多代码,我会根据要求编辑我的帖子。
任何帮助将不胜感激!
答案 0 :(得分:0)
我的一位朋友通过向我发送此链接来帮助我
Android: CursorAdapter, ListView and CheckBox
我尝试了解决方案,但是,我没有使用复选框,但使用背景颜色。
我必须相应地修改getView()方法:
public View getView(int position, View inView, ViewGroup parent) {
if (inView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inView = inflater.inflate(R.layout.habit_item_layout, null);
}
HabitListItemView hliv = (HabitListItemView) inView;
mCursor.moveToPosition(position);
bindView(hliv, mContext, mCursor);
hliv.setHabitPerformed(habitPerformed.get(position)); //line added
return inView;
}
并向适配器添加一个数组,我存储的地方,如果它应该有一个背景为绿色。
public ArrayList<Boolean> habitPerformed = new ArrayList<Boolean>();
在带有listItemClick()方法列表的片段中,我添加了相应修改数组的代码。
if (hv.getHabitPerformed()) {
adapter.habitPerformed.set(position, true);
} else if (!hv.getHabitPerformed()) {
adapter.habitPerformed.set(position, false);
}
这解决了我的问题。