Ghadeer
Ghadeer

Reputation: 638

Drag-and-Drop Listview Item with "Custom Adapter" OnItemLongClickListener

I am working on Drag-and-Drop Listview Item for days and have search a lot about.

I have found an interesting link [DragNDropListView][1], but unfortunately could be applied to "SimpleCursorAdapter"

However, I need a to apply the Drag-and-Drop on

  1. ListView Item (Not CardView nor RecycleView)
  2. On Custom Adapter extended from BaseAdapter
  3. OnItemLongClickListener

Here is My Custom Adapter:

public class BookingsListAdapter extends BaseAdapter implements DragNDropAdapter {

//Fragments
private static final int HOME_FRAGEMENT = 1;
private static final int MANAGE_BOOKINGS_FRAGMENT = 2;

//
private Context context;
private View rootView;
private Bundle bundle;
private LayoutInflater layoutInflater;

//Bookings
private ArrayList<PNRModel> pnrModels;

//Fragments
private int srcFragment;

//Drag-and-Dop
private int positions[];
private int handler;

public BookingsListAdapter(Context context, View rootView, Bundle bundle, int srcFragment, ArrayList<PNRModel> pnrModels, int handler) {
    super();

    this.context = context;
    this.rootView = rootView;
    this.bundle = bundle;
    this.pnrModels = pnrModels;
    setup(pnrModels.size());
    this.srcFragment = srcFragment;
    this.handler = handler;
    layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

}

private void setup(int size) {
    positions = new int[size];

    for (int i = 0; i < size; ++i)
        positions[i] = i;
}

//Remove PNR Item
public boolean remove(int position) {

    boolean isRemoved = false;

    PNRsTable pnrsTable = new PNRsTable(context, DatabaseInfo.DATABASE_NAME, null, DatabaseInfo.DATABASE_VERSION);

    switch (srcFragment) {

        case HOME_FRAGEMENT:
            //Update" MyBookings" PNRsTable field with "N"
            isRemoved = pnrsTable.updateMyBooking(pnrModels.get(position).getBookingReference(), "N");
            break;
        case MANAGE_BOOKINGS_FRAGMENT:
            //Delete PNR info from the DB PNRsTable
            isRemoved = pnrsTable.deletePNR(pnrModels.get(position).getBookingReference());

            //Delete PNR details from the File
            FileHelper.deleteFile(context, pnrModels.get(position).getBookingReference());
            break;
        default:
            break;

    }

    //Remove PNR from the Listview
    pnrModels.remove(position);
    notifyDataSetChanged();

    return isRemoved;
}


@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
    return super.getDropDownView(positions[position], convertView, parent);
}

@Override
public int getCount() {
    return pnrModels.size();
}

@Override
public Object getItem(int position) {
    return pnrModels.get(positions[position]);
}

@Override
public int getItemViewType(int position) {
    return super.getItemViewType(positions[position]);
}

@Override
public long getItemId(int position) {
    return positions[position];
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {

    layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    final BookingViewHolder bookingViewHolder;
    final PNRModel listItem = (PNRModel) getItem(position);

    if (convertView == null) {
        convertView = layoutInflater.inflate(R.layout.item_my_booking, null);
        bookingViewHolder = new BookingViewHolder(context, rootView , bundle,
                srcFragment, convertView);
        convertView.setTag(bookingViewHolder);

    } else {
        bookingViewHolder = (BookingViewHolder) convertView.getTag();
    }

    //Set Listview Item Contents
    bookingViewHolder.setItemContents(listItem);

    //On Refresh click
    bookingViewHolder.imgbtnRefresh.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            bookingViewHolder.setOnButtonClick(listItem, position);

        }
    });

    return convertView;
}

@Override
public boolean isEnabled(int position) {
    return super.isEnabled(positions[position]);
}

@Override
public int getDragHandler() {
    return handler;
}

@Override
public void onItemDrag(DragNDropListView parent, View view, int position, long id) {

}

@Override
public void onItemDrop(DragNDropListView parent, View view, int startPosition, int endPosition, long id) {

    int position = positions[startPosition];

    if (startPosition < endPosition)
        for (int i = startPosition; i < endPosition; ++i)
            positions[i] = positions[i + 1];
    else if (endPosition < startPosition)
        for (int i = startPosition; i > endPosition; --i)
            positions[i] = positions[i - 1];

    positions[endPosition] = position;
}

@Override
public void notifyDataSetChanged() {
    setup(pnrModels.size());
    super.notifyDataSetChanged();
}

}

And My Activity:

    DragNDropListView lstvBookings = (DragNDropListView) rootView.findViewById(R.id.lstvBookings);


//Display PNRs List in the ListView
        BookingsListAdapter bookingsListAdapter = new BookingsListAdapter(context, rootView, bundle, srcFragment, pnrModels, R.id.rltvManageBookings);
        lstvBookings.setDragNDropAdapter(bookingsListAdapter);

        lstvBookings.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {

                BookingViewHolder bookingViewHolder = (BookingViewHolder) view.getTag();

                view.startDrag(null, new View.DragShadowBuilder(view),view,0);
                view.setVisibility(View.INVISIBLE);



                return true;
            }
        });

Upvotes: 0

Views: 758

Answers (1)

anhtuannd
anhtuannd

Reputation: 963

You can just let your CustomAdapter implements DragNDropAdapter, similar to https://github.com/terlici/DragNDropList/blob/master/src/com/terlici/dragndroplist/DragNDropSimpleAdapter.java
Then you can use your adapter with DragNDropListView normally.

UPDATE: sample custom adapter

package com.jason.test.dragndroplist;

import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class DragNDropCustomAdapter extends BaseAdapter implements DragNDropAdapter {
    private Context mContext;
    private int mPosition[];
    private int mHandler;
    private List<String> dataList;

    public DragNDropCustomAdapter(Context context, List<String> data, int handler) {
        super();
        mContext = context;
        mHandler = handler;

        dataList = data;
        setup(data.size());
    }

    private void setup(int size) {
        mPosition = new int[size];

        for (int i = 0; i < size; ++i)
            mPosition[i] = i;
    }

    @Override
    public View getDropDownView(int position, View view, ViewGroup group) {
        return super.getDropDownView(mPosition[position], view, group);
    }

    @Override
    public Object getItem(int position) {
        return dataList.get(mPosition[position]);
    }

    @Override
    public int getItemViewType(int position) {
        return super.getItemViewType(mPosition[position]);
    }

    @Override
    public long getItemId(int position) {
        return mPosition[position];
    }

    @Override
    public View getView(int position, View view, ViewGroup group) {
        LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if (view == null) {
            view = inflater.inflate(android.R.layout.simple_list_item_1, group, false);
        }
        TextView textView = (TextView) view.findViewById(android.R.id.text1);
        textView.setText(dataList.get(mPosition[position]));
        return view;
    }

    @Override
    public boolean isEnabled(int position) {
        return super.isEnabled(mPosition[position]);
    }

    @Override
    public void onItemDrag(DragNDropListView parent, View view, int position, long id) {

    }

    @Override
    public void onItemDrop(DragNDropListView parent, View view, int startPosition, int endPosition, long id) {
        int position = mPosition[startPosition];

        if (startPosition < endPosition)
            for (int i = startPosition; i < endPosition; ++i)
                mPosition[i] = mPosition[i + 1];
        else if (endPosition < startPosition)
            for (int i = startPosition; i > endPosition; --i)
                mPosition[i] = mPosition[i - 1];

        mPosition[endPosition] = position;
    }

    @Override
    public int getCount() {
        return dataList.size();
    }

    @Override
    public void notifyDataSetChanged() {
        setup(dataList.size());
        super.notifyDataSetChanged();
    }

    @Override
    public int getDragHandler() {
        return mHandler;
    }
}

Upvotes: 1

Related Questions