notifydatasetchange not working

孤者浪人 提交于 2019-12-12 05:38:53

问题


I know that this question is asked many times but i can't seem to make it work in my app

I create custom adapter that extends BaseAdapter, and inside it I put listener of drag and drop function to rearrange the order of the items on the list.

so I need to call notifydatasetchanged when drop action is performed, and I did, but don't seem to reorder the data even though when I print out the data to LogCat is already sorted the way I want it.

I try recommendation like using asyncTask, Activity.runOnUIThread but no result for me. I also that's not very suitable for me since i calling it inside the adapter itself, though I called it from another class inside the adapter.

The data for my adapter I provide inside the adapter itself, get from local DB.

Please help me and take a look at my code:

CategoryAdapter -> customAdapter

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;
        }
        }
    }
}
}

回答1:


You are messing with your getView's implementation.

if (v == null)

you should only inflate the View you want to fill up with your dataset. I will try something like:

@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;
}



回答2:


try

CategoryAdapter. notifyDataSetChanged()

When ever you have to refresh an adapter your should enter his name before notifydatasetchanged();



来源:https://stackoverflow.com/questions/15242087/notifydatasetchange-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!