Shashank Degloorkar
Shashank Degloorkar

Reputation: 3231

ListView drag and drop

I have two listviews. And i want to drag an item from one listview and drop at a specific location on another listview. How can i do that. This is my layout.

 <LinearLayout
                android:id="@+id/parentLayout"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="horizontal"
                android:weightSum="3" >

                <LinearLayout
                    android:id="@+id/vert1"
                    android:layout_width="0dip"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:background="@drawable/bg_shadowed_frame"
                    android:gravity="center_horizontal"
                    android:orientation="vertical"
                    android:padding="15dip" >

                    <TextView
                        android:id="@+id/tv1"
                        style="@style/TextViewMedStyleShadowWhite"
                        android:layout_width="wrap_content"
                        android:layout_height="30dip"
                        android:text="LIST 1"
                        android:textColor="@color/theme_blue" />

                    <View
                        android:layout_width="match_parent"
                        android:layout_height="1dip"
                        android:layout_marginLeft="20dip"
                        android:layout_marginRight="20dip"
                        android:layout_marginTop="5dip"
                        android:background="@color/theme_blue" />

                    <RelativeLayout
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content" >

                        <ListView
                            android:id="@+id/listView1"
                            android:layout_width="wrap_content"
                            android:layout_height="match_parent"
                            android:divider="@null"
                            android:paddingLeft="10dip"
                            android:paddingRight="10dip" />

                        <ProgressBar
                            android:id="@+id/progres1"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_centerInParent="true"
                            android:indeterminate="true" />
                    </RelativeLayout>
                </LinearLayout>

                <LinearLayout
                    android:id="@+id/vert2"
                    android:layout_width="0dip"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:background="@drawable/bg_shadowed_frame"
                    android:gravity="center_horizontal"
                    android:orientation="vertical"
                    android:padding="15dip" >

                    <RelativeLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:orientation="horizontal"
                        android:paddingLeft="15dip"
                        android:paddingRight="15dip" >

                        <TextView
                            android:id="@+id/tv1"
                            style="@style/TextViewMedStyleShadowWhite"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_centerHorizontal="true"
                            android:layout_centerVertical="true"
                            android:text="LIST 2"
                            android:textColor="@color/theme_blue" />

                        <ImageButton
                            android:id="@+id/addButton"
                            android:layout_width="30dip"
                            android:layout_height="30dip"
                            android:layout_alignParentRight="true"
                            android:background="@null"
                            android:scaleType="fitCenter"
                            android:src="@drawable/ic_mini_add" />
                    </RelativeLayout>

                    <View
                        android:layout_width="match_parent"
                        android:layout_height="1dip"
                        android:layout_marginLeft="20dip"
                        android:layout_marginRight="20dip"
                        android:layout_marginTop="5dip"
                        android:background="@color/theme_blue" />

                    <RelativeLayout
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content" >

                        <ListView
                            android:id="@+id/listView2"
                            android:layout_width="wrap_content"
                            android:layout_height="match_parent"
                            android:divider="@null"
                            android:paddingLeft="10dip"
                            android:paddingRight="10dip" />

                        <ProgressBar
                            android:id="@+id/progres2"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_centerInParent="true"
                            android:indeterminate="true" />
                    </RelativeLayout>
                </LinearLayout>
      </LinearLayout>

Here i have two ListViews. now on my long click listener i hide the item clicked

listView2.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
                View selectedView = listView2.getChildAt(arg2);
                selectedView.setVisibility(View.INVISIBLE);
                mCellIsMobile = true;

                return false;
            }
        });


listView2.setOnTouchListener(new View.OnTouchListener() {

                @Override
                public boolean onTouch(View v, MotionEvent event) {

                    int xPos = (int)event.getX();
                    int yPos = (int)event.getY();
                    Log.i("Touched","ListView2"+xPos+" , "+yPos);

                    parentLayout.requestDisallowInterceptTouchEvent(false);
                    parentLayout.onInterceptTouchEvent(event);

                    return false;
                }
            });

Also parentLayout also has its touch listener but touch never reaches the parent as child consumes it.

 parentLayout.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {

                int xPos = (int)event.getX();
                int yPos = (int)event.getY();
                Log.i("Touched","Parent"+xPos+" , "+yPos);
   return false;
            }
        });

Upvotes: 0

Views: 597

Answers (1)

Nadeem Iqbal
Nadeem Iqbal

Reputation: 2338

The only problem in below code is that : You want to drop item at a SPECIFIC place on second listview and below code is only adding it either END of the 2nd List or either the Start of the List.

Basically the problem is I can't find the exact position where you will be dropping the item on 2nd ListView. If you could find out that then replace the POSITION_TO_DROP variable with that value.

 int POSITION_TO_DROP = 0;
 droppedList.add(POSITION_TO_DROP, droppedItem);

or just use this to add at the end of 2nd Listview

 droppedList.add(droppedItem);

see these images

Dragging

and After Drop, it will add in the start of 2nd List.

And After Droping

Code:


 //onCreate Start
    targetLayout = (LinearLayout) findViewById(R.id.targetlayout);
    listSource = (ListView) findViewById(R.id.sourcelist);
    listTarget = (ListView) findViewById(R.id.targetlist);
    comments = (TextView) findViewById(R.id.comments);

    // Create and set the tags for the Buttons

    final String SOURCELIST_TAG = "listSource";
    final String TARGETLIST_TAG = "listTarget";
    final String TARGETLAYOUT_TAG = "targetLayout";

    listSource.setTag(SOURCELIST_TAG);
    listTarget.setTag(TARGETLIST_TAG);
    targetLayout.setTag(TARGETLAYOUT_TAG);

    listSource.setAdapter(new ArrayAdapter<String>(this,
            android.R.layout.simple_list_item_1, month));
    listSource.setOnItemLongClickListener(listSourceItemLongClickListener);

    droppedList = new ArrayList<String>();
    droppedAdapter = new ArrayAdapter<String>(this,
            android.R.layout.simple_list_item_1, droppedList);
    listTarget.setAdapter(droppedAdapter);

    listSource.setOnDragListener(myDragEventListener);
    targetLayout.setOnDragListener(myDragEventListener);

   // OnCreate End


    OnItemLongClickListener listSourceItemLongClickListener = new OnItemLongClickListener() {

    @Override
    public boolean onItemLongClick(AdapterView<?> l, View v, int position,
            long id) {

        // Selected item is passed as item in dragData
        ClipData.Item item = new ClipData.Item(month[position]);

        String[] clipDescription = { ClipDescription.MIMETYPE_TEXT_PLAIN };
        ClipData dragData = new ClipData((CharSequence) v.getTag(),
                clipDescription, item);
        DragShadowBuilder myShadow = new MyDragShadowBuilder(v);

        v.startDrag(dragData, // ClipData
                myShadow, // View.DragShadowBuilder
                month[position], // Object myLocalState
                0); // flags

        commentMsg = v.getTag() + " : onLongClick.\n";
        comments.setText(commentMsg);

        return true;
    }
};

private static class MyDragShadowBuilder extends View.DragShadowBuilder {
    private static Drawable shadow;

    public MyDragShadowBuilder(View v) {
        super(v);
        shadow = new ColorDrawable(Color.LTGRAY);
    }

    @Override
    public void onProvideShadowMetrics(Point size, Point touch) {
        int width = getView().getWidth();
        int height = getView().getHeight();

        shadow.setBounds(0, 0, width, height);
        size.set(width, height);
        touch.set(width / 2, height / 2);
    }

    @Override
    public void onDrawShadow(Canvas canvas) {
        shadow.draw(canvas);
    }

}

protected class MyDragEventListener implements View.OnDragListener {

    @Override
    public boolean onDrag(View v, DragEvent event) {
        final int action = event.getAction();

        switch (action) {
        case DragEvent.ACTION_DRAG_STARTED:
            // All involved view accept ACTION_DRAG_STARTED for
            // MIMETYPE_TEXT_PLAIN
            if (event.getClipDescription().hasMimeType(
                    ClipDescription.MIMETYPE_TEXT_PLAIN)) {
                commentMsg += v.getTag()
                        + " : ACTION_DRAG_STARTED accepted.\n";
                comments.setText(commentMsg);
                return true; // Accept
            } else {
                commentMsg += v.getTag()
                        + " : ACTION_DRAG_STARTED rejected.\n";
                comments.setText(commentMsg);
                return false; // reject
            }
        case DragEvent.ACTION_DRAG_ENTERED:
            commentMsg += v.getTag() + " : ACTION_DRAG_ENTERED.\n";
            comments.setText(commentMsg);
            return true;
        case DragEvent.ACTION_DRAG_LOCATION:
            commentMsg += v.getTag() + " : ACTION_DRAG_LOCATION - "
                    + event.getX() + " : " + event.getY() + "\n";
            comments.setText(commentMsg);
            return true;
        case DragEvent.ACTION_DRAG_EXITED:
            commentMsg += v.getTag() + " : ACTION_DRAG_EXITED.\n";
            comments.setText(commentMsg);
            return true;
        case DragEvent.ACTION_DROP:
            // Gets the item containing the dragged data
            ClipData.Item item = event.getClipData().getItemAt(0);

            commentMsg += v.getTag() + " : ACTION_DROP" + "\n";
            comments.setText(commentMsg);

            // If apply only if drop on buttonTarget
            if (v == targetLayout) {
                String droppedItem = item.getText().toString();

                commentMsg += "Dropped item - " + droppedItem + "\n";
                comments.setText(commentMsg);

                int POSITION_TO_DROP = 0;
                droppedList.add(POSITION_TO_DROP, droppedItem);

                droppedAdapter.notifyDataSetChanged();

                return true;
            } else {
                return false;
            }

        case DragEvent.ACTION_DRAG_ENDED:
            if (event.getResult()) {
                commentMsg += v.getTag()
                        + " : ACTION_DRAG_ENDED - success.\n";
                comments.setText(commentMsg);
            } else {
                commentMsg += v.getTag() + " : ACTION_DRAG_ENDED - fail.\n";
                comments.setText(commentMsg);
            }
            ;
            return true;
        default: // unknown case
            commentMsg += v.getTag() + " : UNKNOWN !!!\n";
            comments.setText(commentMsg);
            return false;

        }
    }
}

Check the complete project here => Drag and Drop Between 2 ListViews

Upvotes: 1

Related Questions