0

我知道这个问题被问了很多次,但我似乎无法让它在我的应用程序中工作

我创建了扩展 BaseAdapter 的自定义适配器,并在其中放置了拖放功能的侦听器以重新排列列表中项目的顺序。

所以我需要在执行删除操作时调用 notifydatasetchanged ,我确实这样做了,但似乎没有重新排序数据,即使当我将数据打印到 LogCat 时已经按照我想要的方式排序。

我尝试使用 asyncTask、Activity.runOnUIThread 等推荐,但对我来说没有结果。我也不是很适合我,因为我在适配器本身内部调用它,尽管我从适配器内部的另一个类调用它。

我在适配器本身内部提供的适配器数据来自本地数据库。

请帮助我,看看我的代码:

类别适配器 -> 自定义适配器

public class CategoryAdapter extends BaseAdapter {
private static final String TAG = CategoryAdapter.class.getSimpleName();

private List<CategoryUIO> categoryUIOs;
private Context context;
private LayoutInflater inflater;
private CategorySequenceComparator comparator = new CategorySequenceComparator();

public CategoryAdapter(Activity activity) {
    this.context = activity;
    inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    getData();
}

private void getData() {
    Cursor cursor = MoneyTracker.getCategoryDB().queryAll();
    categoryUIOs = new ArrayList<CategoryUIO>();
    if (cursor != null && cursor.moveToFirst()) {
        do {
            CategoryUIO bo = new CategoryUIO(cursor);
            categoryUIOs.add(bo);
        } while (cursor.moveToNext());
        cursor.close();
    }
    notifyDataSetChanged();
}

private void sortData() {
    if (categoryUIOs != null) {
        Collections.sort(categoryUIOs, comparator);
        notifyDataSetChanged();

        Log.w(TAG, "\n\n");
        for (CategoryUIO uio : categoryUIOs) {
            Log.w(TAG, Utilities.formatString("Name = %s", uio.getName()));
        }
    }
}

@Override
public int getCount() {
    if (categoryUIOs != null) {
        return categoryUIOs.size();
    } else {
        return 0;
    }
}

@Override
public Object getItem(int position) {
    if (categoryUIOs != null) {
        return categoryUIOs.get(position);
    } else {
        return null;
    }
}

@Override
public long getItemId(int position) {
    if (categoryUIOs != null) {
        return ((CategoryUIO) getItem(position)).getId();
    } else {
        return -1;
    }
}

public void refresh() {
    getData();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;
    if (v == null) {
        v = inflater.inflate(R.layout.row_list, parent, false);
        CategoryUIO uio = ((CategoryUIO) getItem(position));
        v.setTag(uio);
        if (uio != null) {
            final TextView tvItem = (TextView) v.findViewById(R.id.tvItem);
            final ImageView ivMove = (ImageView) v.findViewById(R.id.ivMove);
            final ImageView ivSecured = (ImageView) v.findViewById(R.id.ivSecured);
            tvItem.setText(uio.getDisplayName());
            v.setOnDragListener(new MyDragListener());
            ivMove.setOnTouchListener(new MyTouchListener());

            if (uio.isSecured()) {
                ivSecured.setVisibility(ImageView.VISIBLE);
            } else {
                ivSecured.setVisibility(ImageView.INVISIBLE);
            }
        }
    } else {

    }
    return v;
}

private final class MyTouchListener implements OnTouchListener {
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
            View parent = (View) view.getParent();
            CategoryUIO uio = (CategoryUIO) parent.getTag();
            ClipData data = ClipData.newPlainText("label", uio.getDisplayName());
            DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(parent);
            //              shadowBuilder.onProvideShadowMetrics(new Point(parent.getWidth() / 2, parent.getHeight() / 2), new Point(0, 0));
            view.startDrag(data, shadowBuilder, parent, 0);
            //              view.setVisibility(View.INVISIBLE);
            return true;
        } else {
            return false;
        }
    }
}

private final class MyDragListener implements OnDragListener {

    @Override
    public boolean onDrag(View droppedView, DragEvent event) {
        int action = event.getAction();
        switch (action) {
        case DragEvent.ACTION_DRAG_STARTED: {
            return true;
        }
        case DragEvent.ACTION_DRAG_ENTERED: {
            return true;
        }
        case DragEvent.ACTION_DRAG_EXITED: {
            return true;
        }
        case DragEvent.ACTION_DROP: {
            View draggedView = (View) event.getLocalState();
            CategoryBO draggedBO = ((CategoryBO) draggedView.getTag());
            CategoryBO dropedBO = ((CategoryBO) droppedView.getTag());

            // persist the sequence to db
            SQLiteDatabase db = MoneyTracker.getDB();
            db.beginTransaction();
            try {
                // swap the sequence
                int temp = draggedBO.getSequence();
                draggedBO.setSequence(dropedBO.getSequence());
                dropedBO.setSequence(temp);

                ContentValues cv = new ContentValues();
                cv.put(CategoryDB.C_ID, draggedBO.getId());
                cv.put(CategoryDB.C_SEQUENCE, draggedBO.getSequence());
                Response response1 = CategoryBLService.getInstance().update(cv);
                cv = new ContentValues();
                cv.put(CategoryDB.C_ID, dropedBO.getId());
                cv.put(CategoryDB.C_SEQUENCE, dropedBO.getSequence());
                Response response2 = CategoryBLService.getInstance().update(cv);

                // TODO: THIS PART IS NOT NECESSARY IF CALL TO NOTIFYDATASETCHANGED WORKS {
                // the data is updated but seems like notifydatasetchanged in sortData()
                // don't have any effect

                // swap the BOs
                //                  CategoryBO tempBO = draggedBO;
                //                  draggedBO = dropedBO;
                //                  dropedBO = tempBO;
                //
                //                  droppedView.setTag(dropedBO);
                //                  draggedView.setTag(draggedBO);
                //
                //                  // refresh the views
                //                  TextView droppedTvItem = (TextView) droppedView.findViewById(R.id.tvItem);
                //                  droppedTvItem.setText(dropedBO.getDisplayName());
                //                  TextView draggedTvItem = (TextView) draggedView.findViewById(R.id.tvItem);
                //                  draggedTvItem.setText(draggedBO.getDisplayName());
                // TODO: } THIS IS THE END OF UNNECESSARY BLOCK

                if (response1.isSuccess() && response2.isSuccess()) {
                    db.setTransactionSuccessful();
                    sortData();
                    return true;
                } else {
                    return false;
                }
            } finally {
                db.endTransaction();
            }
        }
        case DragEvent.ACTION_DRAG_ENDED: {
            return true;
        }
        default: {
            return true;
        }
        }
    }
}
}
4

2 回答 2

1

尝试

CategoryAdapter. notifyDataSetChanged()

当你必须刷新一个适配器时,你应该在 notifydatasetchanged() 之前输入他的名字;

于 2013-03-06T08:20:28.637 回答
1

你正在搞乱你getView的实现。

if (v == null)

你应该只View用你的数据集填充你想要填充的数据。我会尝试类似的东西:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;
    if (v == null) {
        v = inflater.inflate(R.layout.row_list, parent, false);
        final TextView tvItem = (TextView) v.findViewById(R.id.tvItem);
        final ImageView ivMove = (ImageView) v.findViewById(R.id.ivMove);
        final ImageView ivSecured = (ImageView) v.findViewById(R.id.ivSecured);
     }
        CategoryUIO uio = ((CategoryUIO) getItem(position));
        v.setTag(uio);

        if (uio != null) {

            tvItem.setText(uio.getDisplayName());
            v.setOnDragListener(new MyDragListener());
            ivMove.setOnTouchListener(new MyTouchListener());

            if (uio.isSecured()) {
                ivSecured.setVisibility(ImageView.VISIBLE);
            } else {
                ivSecured.setVisibility(ImageView.INVISIBLE);
            }
        }

    return v;
}
于 2013-03-06T08:24:16.990 回答