مشکل CursorAdapter در لیست ویو
سلام
استاد در درس آموزش لیست ویو گفت که اگر در checkbox از onclicklistener استفاده بشه با اسکرول کردن تیک checkbox برداشته نمیشه.
من با استفاده از cursorAdapter اطلاعات یک دیتابیس آماده را در لیست میخونم که یه checkbox برای افزودن به علاقه مندی وجود داره.
وقتی روی چک باکس تیک میزنی خوب مقدار yes به دیتابیس افزوده میشه و اون آیتم به علاقه مندی ها افزوده میشه.
اما با اسکرول کردن تیک چک باکس برداشته میشه و البته با دوباره وارد اون اکتیویتی شدن علاقه مندی ها نشان داده میشه.
از onclicklistener هم استفاده میکنم فرقی نمیکنه.
اگر از آرایه ها استفاده کنی مشکلی پیش نمیاد ولی اگه بخوای cursorAdapter استفاده کنم چطور باید این قضیه را درست کنم
کد adapter در زیر قرار دادم
عکس برنامه :

این هم کد CursorAdapter :
public class MyAdapter extends CursorAdapter {
Context b;
LayoutInflater inflater;
@SuppressWarnings("deprecation")
public MyAdapter(Context context, Cursor c) {
super(context, c);
inflater = LayoutInflater.from(context);
b= (Context) context;
}
@SuppressWarnings("unused")
@Override
public void bindView(View view, Context context, final Cursor cursor) {
// TODO Auto-generated method stub
TextView tv1 = (TextView)view.findViewById(R.id.txt_name);
TextView tv2 = (TextView)view.findViewById(R.id.txt_numer);
tv1.setText(cursor.getString(2));
tv2.setText(cursor.getString(3));
final int pos = cursor.getPosition();
final CheckBox repeatChkBx = (CheckBox)view.findViewById(R.id.favorite_check);
String me = cursor.getString(cursor.getColumnIndex("like"));
if (me.equals("yes")) {
repeatChkBx.setChecked(true);
} else {
repeatChkBx.setChecked(false);
}
repeatChkBx.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
MyDatabase MyDatabase = new MyDatabase(b);
SQLiteDatabase mydb = MyDatabase.getWritableDatabase();
cursor.moveToPosition(pos);
if (repeatChkBx.isChecked()) {
mydb.execSQL("update list set like = 'yes' where id = " + cursor.getString(1));
}else{
mydb.execSQL("update list set like = 'no' where id = " + cursor.getString(1));
}
}
});
}
protected Context getActivity() {
// TODO Auto-generated method stub
return null;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return inflater.inflate(R.layout.item, parent, false);
}
}
اگر از آرایه ها استفاده بشه قسمتی که دیتابیس را آپدیت میکنیم ستون علاقه مندی ها را برابر مقدار داده میکنیم و درست میشه
ولی تو cursoradapter این طور نیست
if(favotite.isChecked()) {
mydb.execSQL("update list set like = 'yes' where id = " + ids[position]);
likes[position] = "yes";
} else {
mydb.execSQL("update list set like = 'no' where id = " + ids[position]);
likes[position] = "no";
}
حامد جان شما خودت استادی ، ولی گفتم یه یاد آوری بکنم
1 - مقدار ثبت شده در دیتابیس رو چک کنید ، حتما ثبت شده باشه
2- آرایه ای که ست شده رو هم تغییر بدید ! ، یعنی فقط تغییر رو دیتابیس نباشه
3- وقتی که متد Fill فراخوانی میشه ، مقدار چک باکس رو هم از آرایه ست کنید (من با cursor adapter کار نکردم ، احتمالا یه تابه مشابهی داشته باشه دیگه :| )
فکر کنم تابع new view باشه که اونجا هم مقدار چک باکس را چک کردم نشد
من پروژه را آپلود کردم که اگر کسی خواست پروژه را هم ببینه :
اشکال برنامه ات رو پیدا کردم ولی راه حلشو نمیدونم. آخه این آداپترت رو یه جور خاصی نوشتی و مثل اونی که باهاش کار میکنم نیست
مشکل کارت اینه که موقع چک شرط این بخش :
if (repeatChkBx.isChecked()) {
mydb.execSQL("update list set like = 'yes' where id = " + Integer.parseInt(cursor.getString(1)));
} else {
mydb.execSQL("update list set like = 'no' where id = " + Integer.parseInt(cursor.getString(1)));
}
مقدار repeatChBx به اون الوار آخری اشاره میکنه نه اون الواری که کلیک میشه.
شما اگه اون الوار آخرو کلیک کنی میبینی که مقدارش yes میشه و باقی میمونه
اما میگم به خاطر نوع خاص آداپترت من نمیدونم باید چطور مشکلو رفع کنی
امیدوارم کمکی کرده باشم
لینک پروژه جدید :
http://upir.ir/1393.2/listview-custom.rar
کد myadapter :
@Override
public void bindView(View view, Context context, final Cursor cursor) {
TextView tv1 = (TextView)view.findViewById(R.id.txt_name);
TextView tv2 = (TextView)view.findViewById(R.id.txt_numer);
tv1.setText(cursor.getString(2));
tv2.setText(cursor.getString(3));
final int pos = cursor.getPosition();
final CheckBox repeatChkBx = (CheckBox)view.findViewById(R.id.favorite_check);
String likes = cursor.getString(cursor.getColumnIndex("like"));
if (likes.equals("yes")) {
repeatChkBx.setChecked(true);
} else {
repeatChkBx.setChecked(false);
}
repeatChkBx.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
MyDatabase mydatabase = new MyDatabase(b);
SQLiteDatabase mydb = mydatabase.getWritableDatabase();
cursor.moveToPosition(pos);
if (repeatChkBx.isChecked()) {
ContentValues cv = new ContentValues();
cv.put("like", "yes");
mydb.update("list", cv, "id ="+cursor.getString(1), null);
} else {
ContentValues cv = new ContentValues();
cv.put("like", "no");
mydb.update("list", cv, "id ="+cursor.getString(1), null);
}
mydb.close();
}
});
}
ماشالا خودت حرفه ای و احتمالا خودت هم متوجه مشکل شدی ولی خوب منم میگم شاید کمکی بشه.
مشکل از اون cursor ه . توی بخش onclick دائم دیتابیس باز و بسته میشه و مشکلی نیست اما اون cursor که از پارامتر های bindView ه چون یه بار اول برنامه باز شده و تا آخر برنامه هم بسته نمیشه ، مقادیر جدید دیتابیس رو دریافت نمیکنه . فکر کنم یا باید راهی پیدا کنی که اون cursor رو آپدیت کنه ( خودم نمیدونم اون bindView ه از کجا فراخونی میشه) یا باید از یه آرایه برای روشن و خاموش کردن شون استفاده کنی . یعنی هم تو دیتابیس ذخیره کنی و هم اونجا که likes رو میخونی، به جای cursor، از آرایه پرش کنی.
البته چون کلاست از CursorAdapter اکستند شده ، نمیذاره ArrayList تعریف کنی. به جاش فکر کنم بشه آرایه رو توی کلاس main تعریف کنی و با دو تا متد set و get مقداردهیش کنی (البته مطمئن نیستم اجازه دسترسی بده به خاطر اینکه باید متد استاتیک باشه و ...)
یا اینکه از آرایه استاتیک استفاده کنی.
ایشالا فردا یه تلاشی روش میکنم ببینم چکارش میشه کرد :)
ویرایش : الان فرداست D:
برای ستاره ها به نظرم کارت با cursorAdapter راه نمیوفتهیا خیلی سختتر بشه. فکر کنم بهتره از همون ArrayAdapter استفاده کنی.
تو stack یه نفر جواب ساده داده و بقیه تایید کردند که لینکش را گذاشتم
یه نگاه بندازین ببینین دقیقا چی میگه؟
من که نتونستم ازش استفاده کنم
http://stackoverflow.com/questions/1...oradapter?rq=1
پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .