使用拖放listview拖动文本?

时间:2014-05-12 07:06:52

标签: android android-listview drag-and-drop

目前我正在开发需要使用拖放列表视图的应用程序。但是当我拖放列表项时,我无法拖放文本。均值列表能够拖放但文本保持在同一位置。那么如何用列表项拖动文本?

Main.java类

package com.example.dragdroplistview;
import android.app.ListActivity;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;


public class Main extends ListActivity {
    private ListView mExampleList;
/** Called when the activity is first created. */

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    mExampleList = getListView();

  System.out.println("position values = "+mExampleList);
    mExampleList.setOnCreateContextMenuListener(this);
    ((DDListView) mExampleList).setDropListener(mDropListener);
    mExampleList.setAdapter(new ExampleArrayAdapter(getApplicationContext(),
                    R.layout.rowexample,new String[]{"Row one", "Row two", "Row tree"}));
}

//ArrayAdapter
private class ExampleArrayAdapter extends ArrayAdapter<String>{
    private Context mContext;
    private int mLayoutId;
    private String[] mListContent;
            public ExampleArrayAdapter(Context context, int textViewResourceId,
                            String[] objects) {
                    super(context, textViewResourceId, objects);
                    mContext = context;
                    mLayoutId = textViewResourceId;
                    mListContent = objects;
            }

            public View getView(int position, View rowView, ViewGroup parent) {
                    if (rowView != null) {
                            return rowView;
                    }
                    LayoutInflater inflater= LayoutInflater.from(mContext);
                    View v  = inflater.inflate(mLayoutId, null);
                    v.setBackgroundColor(Color.RED);
                   TextView rowTitle = (TextView)v.findViewById(R.id.text1);
                    rowTitle.setText(mListContent[position]);

                    return v;
            }

}

//Drop Listener
private DDListView.DropListener mDropListener =
    new DDListView.DropListener() {
    public void drop(int from, int to) {

    }
};
}

DDListView.java类

package com.example.dragdroplistview;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListView;


public class DDListView extends ListView {

private int mDragPos;      // which item is being dragged
private int mFirstDragPos; // where was the dragged item originally
private int mDragPoint;    // at what offset inside the item did the user grab it
private int mCoordOffset;  // the difference between screen coordinates and coordinates in this view

private WindowManager mWindowManager;
private WindowManager.LayoutParams mWindowParams;
private Rect mTempRect = new Rect();

//dragging elements
private Bitmap mDragBitmap;
private ImageView mDragView;
private int mHeight;
private int mUpperBound;
private int mLowerBound;
private int mTouchSlop;
    private int mItemHeightHalf;
private int mItemHeightNormal;
private int mItemHeightExpanded;

    private DragListener mDragListener;
    private DropListener mDropListener;


    public DDListView(Context context, AttributeSet attrs) {
            super(context, attrs);
        Resources res = getResources();
        mItemHeightNormal = res.getDimensionPixelSize(R.dimen.normal_height);
    mItemHeightHalf = mItemHeightNormal / 2;
    mItemHeightExpanded = res.getDimensionPixelSize(R.dimen.expanded_height);
    }
    @Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    if (mDragListener != null || mDropListener != null) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                int x = (int) ev.getX();
                int y = (int) ev.getY();
                int itemnum = pointToPosition(x, y);
                if (itemnum == AdapterView.INVALID_POSITION) {
                    break;
                }
                ViewGroup item = (ViewGroup) getChildAt(itemnum - getFirstVisiblePosition());
                mDragPoint = y - item.getTop();
                mCoordOffset = ((int)ev.getRawY()) - y;
                item.setDrawingCacheEnabled(true);
                Bitmap bitmap = Bitmap.createBitmap(item.getDrawingCache());
                startDragging(bitmap, y);
                mDragPos = itemnum;
                mFirstDragPos = mDragPos;
                mHeight = getHeight();
                int touchSlop = mTouchSlop;
                mUpperBound = Math.min(y - touchSlop, mHeight / 3);
                mLowerBound = Math.max(y + touchSlop, mHeight * 2 /3);
                return false;
        }
    }
    return super.onInterceptTouchEvent(ev);
}

    private int myPointToPosition(int x, int y) {
    if (y < 0) {
        int pos = myPointToPosition(x, y + mItemHeightNormal);
        if (pos > 0) {
            return pos - 1;
        }
    }
    Rect frame = mTempRect;
    final int count = getChildCount();
    for (int i = count - 1; i >= 0; i--) {
        final View child = getChildAt(i);
        child.getHitRect(frame);
        if (frame.contains(x, y)) {
            return getFirstVisiblePosition() + i;
        }
    }
    return INVALID_POSITION;
}

private int getItemForPosition(int y) {
    int adjustedy = y - mDragPoint - mItemHeightHalf;
    int pos = myPointToPosition(0, adjustedy);
    if (pos >= 0) {
        if (pos <= mFirstDragPos) {
            pos += 1;
        }
    } else if (adjustedy < 0) {
        pos = 0;
    }
    return pos;
}

private void adjustScrollBounds(int y) {
    if (y >= mHeight / 3) {
        mUpperBound = mHeight / 3;
    }
    if (y <= mHeight * 2 / 3) {
        mLowerBound = mHeight * 2 / 3;
    }
}

private void unExpandViews(boolean deletion) {
    for (int i = 0;; i++) {
        View v = getChildAt(i);
        if (v == null) {
            if (deletion) {
                int position = getFirstVisiblePosition();
                int y = getChildAt(0).getTop();
                setAdapter(getAdapter());
                setSelectionFromTop(position, y);
            }
            layoutChildren();
            v = getChildAt(i);
            if (v == null) {
                break;
            }
        }
        ViewGroup.LayoutParams params = v.getLayoutParams();
        params.height = mItemHeightNormal;
        v.setLayoutParams(params);
        v.setVisibility(View.VISIBLE);
    }
}

private void doExpansion() {
    int childnum = mDragPos - getFirstVisiblePosition();
    if (mDragPos > mFirstDragPos) {
        childnum++;
    }

    View first = getChildAt(mFirstDragPos - getFirstVisiblePosition());

    for (int i = 0;; i++) {
        View vv = getChildAt(i);
        if (vv == null) {
            break;
        }
        int height = mItemHeightNormal;
        int visibility = View.VISIBLE;
        if (vv.equals(first)) {
           if (mDragPos == mFirstDragPos) {
               visibility = View.INVISIBLE;
            } else {
                height = 1;
            }
        } else if (i == childnum) {
            if (mDragPos < getCount() - 1) {
                height = mItemHeightExpanded;
            }
        }
        ViewGroup.LayoutParams params = vv.getLayoutParams();
        params.height = height;
        vv.setLayoutParams(params);
        vv.setVisibility(visibility);
    }
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if ((mDragListener != null || mDropListener != null) && mDragView != null) {
        int action = ev.getAction();
        switch (action) {
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                Rect r = mTempRect;
                mDragView.getDrawingRect(r);
                stopDragging();
                if (mDropListener != null && mDragPos >= 0 && mDragPos < getCount()) {
                    mDropListener.drop(mFirstDragPos, mDragPos);
                 }
                 unExpandViews(false);
                break;
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
                int x = (int) ev.getX();
                int y = (int) ev.getY();
                dragView(x, y);
                int itemnum = getItemForPosition(y);
                if (itemnum >= 0) {
                    if (action == MotionEvent.ACTION_DOWN || itemnum != mDragPos) {
                        if (mDragListener != null) {
                            mDragListener.drag(mDragPos, itemnum);
                        }
                        mDragPos = itemnum;
                        doExpansion();
                    }
                    int speed = 0;
                    adjustScrollBounds(y);
                    if (y > mLowerBound) {
                        // scroll the list up a bit
                        speed = y > (mHeight + mLowerBound) / 2 ? 16 : 4;
                    } else if (y < mUpperBound) {
                        // scroll the list down a bit
                        speed = y < mUpperBound / 2 ? -16 : -4;
                    }
                    if (speed != 0) {
                        int ref = pointToPosition(0, mHeight / 2);
                        if (ref == AdapterView.INVALID_POSITION) {
                            //we hit a divider or an invisible view, check somewhere else
                            ref = pointToPosition(0, mHeight / 2 + getDividerHeight() + 64);
                        }
                        View v = getChildAt(ref - getFirstVisiblePosition());
                        if (v!= null) {
                            int pos = v.getTop();
                            setSelectionFromTop(ref, pos - speed);
                        }
                    }
                }
                break;
        }
        return true;
    }
    return super.onTouchEvent(ev);
}

private void startDragging(Bitmap bm, int y) {
    stopDragging();

    mWindowParams = new WindowManager.LayoutParams();
    mWindowParams.gravity = Gravity.TOP;
    mWindowParams.x = 0;
    mWindowParams.y = y - mDragPoint + mCoordOffset;

    mWindowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
    mWindowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
    mWindowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
            | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
            | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
            | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
            | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
    mWindowParams.format = PixelFormat.TRANSLUCENT;
    mWindowParams.windowAnimations = 0;

    Context context = getContext();
    ImageView v = new ImageView(context);
    int backGroundColor = context.getResources().getColor(R.color.appwidget_text);
    v.setBackgroundColor(backGroundColor);
    v.setImageBitmap(bm);
    mDragBitmap = bm;

    mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
    mWindowManager.addView(v, mWindowParams);
    mDragView = v;
}

private void dragView(int x, int y) {
    mWindowParams.y = y - mDragPoint + mCoordOffset;
    mWindowManager.updateViewLayout(mDragView, mWindowParams);
}

private void stopDragging() {
    if (mDragView != null) {
        WindowManager wm = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
        wm.removeView(mDragView);
        mDragView.setImageDrawable(null);
        mDragView = null;
    }
    if (mDragBitmap != null) {
        mDragBitmap.recycle();
        mDragBitmap = null;
    }
}

public void setDragListener(DragListener l) {
    mDragListener = l;
}

public void setDropListener(DropListener l) {
    mDropListener = l;
}

public interface DragListener {
    void drag(int from, int to);
}
public interface DropListener {
    void drop(int from, int to);
}
public interface RemoveListener {
    void remove(int which);
}
}

main.xml中

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView  
android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="@string/main_title"/>
<!--  Custom list view goes here :) -->
<com.example.dragdroplistview.DDListView
    android:id="@android:id/list"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:drawSelectorOnTop="false"
    android:fastScrollEnabled="true" android:clickable="false" android:drawingCacheQuality="high">
</com.example.dragdroplistview.DDListView>
</LinearLayout>

rowexample.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">

<TextView
android:id="@+id/text1"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:gravity="center_vertical"
android:paddingLeft="6dip"
android:minHeight="?android:attr/listPreferredItemHeight"
    android:text="TEXTO" android:layout_width="wrap_content"/>


</LinearLayout>

listview的图片,其中我无法拖动文本 - 第一行,第二行,行树。

image

1 个答案:

答案 0 :(得分:0)

将主XML从LinearLayout更改为RelativeLayout

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView  
android:id="@+id/txttitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="@string/main_title"
android:layout_alignPatentTop="true"
/>
<!--  Custom list view goes here :) -->
<com.example.dragdroplistview.DDListView
    android:id="@android:id/list"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:drawSelectorOnTop="false"
    android:fastScrollEnabled="true" android:clickable="false" android:drawingCacheQuality="high"

android:layout_below="@+id/txttitle"
>
</com.example.dragdroplistview.DDListView>
</RelativeLayout>