سؤال

لقد قمت بإنشاء ListView مخصص عن طريق توسيع SimpleCursorAdapter. والنتيجة هي Image + CheckedTextView (Text + Checkbox).

عندما أقوم بنقر فوق عنصر طويل ، يعمل كل شيء بشكل جيد - أحصل على المعرف الصحيح وتفاصيل العنصر الذي تم النقر عليه.

تحدث المشكلة عندما أحاول وضع علامة على عنصر ما كما هو محدد ولكنه يتحقق من خانة الاختيار الخاطئة.

علي سبيل المثال: لدي 9 عناصر في قائمتي ، مرتبة 1-9. إذا قمت بالنقر فوق ListItem 1 ، يتم فحص خانة الاختيار على السطر 9. إذا قمت بالنقر فوق البند 4 ، يتم التحقق من مربع الاختيار على السطر 6 وإذا قمت بالنقر فوق الخط الأوسط ، فسيتم فحصه.

من الواضح أنني أفتقد شيئًا هنا :) أتذكر عندما انقر فوق الخط الطويل (يفتح ContextMenu) ، كل شيء يعمل بشكل رائع.

هذا هو المستمع:

lv.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                CheckedTextView markedItem = (CheckedTextView) view.findViewById(R.id.btitle);

                if (!markedItem.isChecked()) {
                    markedItem.setChecked(true);
                } else {
                    markedItem.setChecked(false);
                }

            }
        });

نقدر أي مساعدة!

اسمحوا لي أن أعرف إذا كنت بحاجة لي لنشر المزيد من التعليمات البرمجية.

شكرًا لك!

راجع للشغل ، إذا قمت بالنقر فوق أكثر من واحد ... يستمر الطرف ... لا يوجد أمر واضح ...

تحرير: رمز المحول

public class ImageCursorAdapter extends SimpleCursorAdapter {

    private Cursor c;
    private Context context;

    private String url;
    private TextView bUrl;

    public ImageCursorAdapter(Context context, int layout, Cursor c,
            String[] from, int[] to) {
        super(context, layout, c, from, to);
        this.c = c;
        this.context = context;
    }

    public View getView(int pos, View inView, ViewGroup parent) {
        View v = inView;
        if (v == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = inflater.inflate(R.layout.image_list, null);
        }

        this.c.moveToPosition(pos);

        final TextView bTitle = (TextView) v.findViewById(R.id.btitle);
        String bookmark = this.c.getString(this.c.getColumnIndex(Browser.BookmarkColumns.TITLE));


        byte[] favicon = this.c.getBlob(this.c.getColumnIndex(Browser.BookmarkColumns.FAVICON));

        if (favicon != null) {
            ImageView iv = (ImageView) v.findViewById(R.id.bimage);
            iv.setImageBitmap(BitmapFactory.decodeByteArray(favicon, 0, favicon.length));
        }
        bTitle.setText(bookmark);

        return (v);
    }
}
هل كانت مفيدة؟

المحلول

Mayra على حق - المشكلة تتعلق بالطريقة التي تقوم بها ListView بإعادة استخدام وجهات نظرك. ليس كما لو كانت هناك 9 حالات من CheckedTextView كائن ، واحد لكل عرض. بدلاً من ذلك ، هناك واحد يتم إعادة استخدامه في جميع الصفوف. وبالتالي ، لا يمكنك الاعتماد على كائن checkedTextView للاحتفاظ بحالة ما إذا كان تم التحقق من عنصر ما. ستحتاج إلى بعض بنية البيانات الإضافية للاحتفاظ بما إذا كان يتم التحقق من صف معين على سبيل المثال ،

ArrayList<Boolean> checkedStates = new ArrayList<Boolean>();

أين ال ith العنصر صحيح IFF ith يجب فحص الصف. ثم داخل itemClickListener الخاص بك:

lv.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            boolean currentlyChecked = checkedStates.get(position);
            checkedStates.set(position, !currentlyChecked);
            // Refresh the list
        }
    });

ثم داخل رمز العرض الخاص بك:

public View getView(int pos, View inView, ViewGroup parent) {
    View v = inView;
    if (v == null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = inflater.inflate(R.layout.image_list, null);
    }

    this.c.moveToPosition(pos);

    final TextView bTitle = (TextView) v.findViewById(R.id.btitle);
    String bookmark = this.c.getString(this.c.getColumnIndex(Browser.BookmarkColumns.TITLE));


    byte[] favicon = this.c.getBlob(this.c.getColumnIndex(Browser.BookmarkColumns.FAVICON));

    if (favicon != null) {
        ImageView iv = (ImageView) v.findViewById(R.id.bimage);
        iv.setImageBitmap(BitmapFactory.decodeByteArray(favicon, 0, favicon.length));
    }
    bTitle.setText(bookmark);


    // Change the state of the checkbox to match that of the row's checked state.
    // This check box item is reused for every row, so we need to reset its state each
    // time the row is rendered.
    CheckedTextView markedItem = (CheckedTextView) view.findViewById(R.id.btitle);
    markedItem.setChecked(checkedStates.get(pos));


    return (v);
}

هذا يجب ان يحل مشكلتك. تتمثل النهج البديل في نقل منطق ما إذا كان الصف قد تم فحصه أم لا في كائن المجال الذي يمثله الصف. وهذا هو تفضيلي.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top