Android:Scrollview拖放以重新排序子组件

时间:2014-04-18 10:12:36

标签: java android

我无法创建具有拖放功能的ScrollView来重新排序所有组件。我不想使用Listview创建它。任何人都可以帮助我.Thnaks:)

public class ActivityDragAndDrop extends Activity {
    private CustomScrollView customScrollView;
    private LinearLayout llMain;
    private float defaultPos;
    private float heightRequestItem;
    private float halfitemHeight;
    private int lastAddedAt = -1;
    float lastY = -1;
    LayoutInflater inflater;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_drag_and_drop);
        initData();
        initUI();
    }

    private void initData() {
        heightRequestItem = getResources().getDimensionPixelSize(
                R.dimen.item_height);
        halfitemHeight = heightRequestItem / 2;
    }

    private void initUI() {
        customScrollView = (CustomScrollView) findViewById(R.id.scrollView);
        llMain = (LinearLayout) findViewById(R.id.llMain);
        inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);

        for (int i = 0; i <= 5; i++) {
            View vTemp = inflater.inflate(R.layout.single_tv_tag_name, null);
            if (i != 4 && i != 5) {
                TextView tvTagName = ((TextView) vTemp
                        .findViewById(R.id.tvTagName));
                tvTagName.setText("Tag" + i);
                tvTagName.setTag("" + i);
            }

            vTemp.setOnTouchListener(new ChoiceTouchListener());
            vTemp.setOnDragListener(new ChoiceDragListener());

            llMain.addView(vTemp);
        }


    }

    private final class ChoiceTouchListener implements OnTouchListener {

        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {

            if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
                defaultPos = view.getY();
                ClipData data = ClipData.newPlainText("", "");
                DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(
                        view);
                view.startDrag(data, shadowBuilder, view, 1);
                return true;
            } else {
                return false;
            }

        }

    }

    private class ChoiceDragListener implements OnDragListener {

        @Override
        public boolean onDrag(View v, DragEvent event) {
            // handle drag events


            switch (event.getAction()) {
            case DragEvent.ACTION_DRAG_STARTED:
                // no action necessary

                break;
            case DragEvent.ACTION_DRAG_ENTERED:
                // no action necessary

                break;
            case DragEvent.ACTION_DRAG_EXITED:
                // no action necessary

                break;
            case DragEvent.ACTION_DROP:


                View view = (View) event.getLocalState();

                // stop displaying the view where it was before it was dragged
                view.setVisibility(View.INVISIBLE);

                // view being dragged and dropped
                LinearLayout dropped = (LinearLayout) view;

                // view dragged item is being dropped on
                LinearLayout dropTarget = (LinearLayout) v;

                // update the text in the target view to reflect the data being
                // dropped

                // make it bold to highlight the fact that an item has been
                // dropped


                break;
            case DragEvent.ACTION_DRAG_ENDED:
                // no action necessary

                break;
            default:
                break;
            }
            return true;
        }

    }

    private void addBlankviewAt(int pos) {
        Log.v("TT", " pos-->" + pos + " N: " + llMain.getChildCount());

        if (lastAddedAt != -1) {
            llMain.removeViewAt(lastAddedAt);
        }
        View vBlank = inflater.inflate(R.layout.blank_layout, null);
        llMain.addView(vBlank, pos);

        lastAddedAt = pos;
    }


}

R.layout.SingleTv_tagname是一个布局,我想使用拖放动画在scrollview中重新排序。滚动视图在initUI()方法中创建。

enter image description here

1 个答案:

答案 0 :(得分:0)

试试这个...... 魔术发生在ACTION_DRAG中,您在其中创建orignal布局的副本,然后找到您正在拖动的视图的Yposition,然后将该Yposition除以该项目的高度。这将在滚动视图中给出光标在屏幕上的yo位置。然后使用addViewAt(view,pos)你可以添加组件。最后使用llMain.removeView(originalView)删除orignal视图;享受:)你做完了....

public class ActivityDragAndDrop extends Activity
{
    private Rect rect;   
    DragShadowBuilder shadowBuilder;
    private CustomScrollView customScrollView;
    private LinearLayout llMain;
    private float defaultPos;
    private float heightRequestItem ;
    private float halfitemHeight;
    private int  lastAddedAt=-1;
    float lastY=-1;
    float prevPos=-1;
    Display display;
    float screenWidth,screenheight;
    Timer t;
    LayoutInflater inflater;

    private int widthRequestItem;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_drag_and_drop);
        initData();
        initUI();
    }

    private void initData() 
    {
        display = getWindowManager().getDefaultDisplay();
        screenWidth = display.getWidth();
        screenheight = display.getHeight();
        heightRequestItem= getResources().getDimensionPixelSize(R.dimen.item_height);   
        halfitemHeight=heightRequestItem/2;
    }

    private void initUI() 
    {
        customScrollView=(CustomScrollView) findViewById(R.id.scrollView);
        llMain=(LinearLayout)findViewById(R.id.llMain);
        inflater=(LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);

        for(int i=0;i<10;i++)
        {
            View vTemp=inflater.inflate(R.layout.single_tv_tag_name, null);
            TextView tvTagName=((TextView)vTemp.findViewById(R.id.tvTagName));
            tvTagName.setText("Tag"+i);
            tvTagName.setTag(""+i);


            vTemp.setOnTouchListener(new ChoiceTouchListener());
            vTemp.setOnDragListener(new ChoiceDragListener());

            llMain.addView(vTemp);
        } 
        View vBlank=inflater.inflate(R.layout.blank_layout, null);
        vBlank.setOnTouchListener(new ChoiceTouchListener());
        vBlank.setOnDragListener(new ChoiceDragListener());
        llMain.addView(vBlank);
        View vBlank1=inflater.inflate(R.layout.blank_layout, null);
        vBlank1.setOnTouchListener(new ChoiceTouchListener());
        vBlank1.setOnDragListener(new ChoiceDragListener());
        llMain.addView(vBlank1);

        t=new Timer();
        t.schedule(new TimerTask() {

            @Override
            public void run() {

                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        findHeight();

                    }
                });
            }
        }, 200);

    }

    private void findHeight() 
    {
        heightRequestItem=llMain.getChildAt(0).getMeasuredHeight();
         widthRequestItem=llMain.getChildAt(0).getMeasuredWidth();
        Toast.makeText(getApplicationContext(), " "+heightRequestItem, Toast.LENGTH_LONG).show();

    }
    private final class ChoiceTouchListener implements OnTouchListener 
    {

        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {

            if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) 
            {
                 rect = new Rect(view.getLeft(), view.getTop(), view.getRight(),view.getBottom());

                prevPos=view.getY();
                ClipData data = ClipData.newPlainText("", "");

                Point offset = new Point((int) motionEvent.getX(), (int) motionEvent.getY());
                  shadowBuilder = new CustomDragShadowBuilder(view, offset);

                view.startDrag(data, shadowBuilder, view, 1);
                return true;
            }
             else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) 
             {


                 return true;
             } else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {


                 return true;
             }
            return false;

        }

    }
    private class ChoiceDragListener implements OnDragListener 
    {



        private int FLAG;
        private boolean containsDragable;
        private int _yDelta;

        @Override
        public boolean onDrag(View v, DragEvent event) {




                View view = (View) event.getLocalState();

        //view being dragged and dropped
        LinearLayout dropped = (LinearLayout) view;


        //view dragged item is being dropped on
        LinearLayout dropTarget = (LinearLayout) v;





            switch (event.getAction()) {
            case DragEvent.ACTION_DRAG_STARTED:
                //no action necessary

                break;
            case DragEvent.ACTION_DRAG_ENTERED:
                //no action necessary

                break;
            case DragEvent.ACTION_DRAG_EXITED:       
                //no action necessary

                break;
            case DragEvent.ACTION_DROP:




                float lastPos=dropTarget.getY();
                View vBlank=inflater.inflate(R.layout.single_tv_tag_name, null);
                ((TextView)vBlank.findViewById(R.id.tvTagName)).setText(((TextView)dropped.findViewById(R.id.tvTagName)).getText());
                vBlank.setOnTouchListener(new ChoiceTouchListener());
                vBlank.setOnDragListener(new ChoiceDragListener());
                llMain.addView(vBlank, ((int)(lastPos/heightRequestItem)));
                llMain.removeView(dropped);

                break;
            case DragEvent.ACTION_DRAG_ENDED:
                //no action necessary

                break;
            default:
                break;
        }
            return true;
        }


    }


    public class CustomDragShadowBuilder extends View.DragShadowBuilder {

        private Point _offset;


        public CustomDragShadowBuilder(View view, Point offset) {

            // Stores the View parameter passed to myDragShadowBuilder.
            super(view);


            _offset = offset;
        }

        @Override
        public void onProvideShadowMetrics (Point size, Point touch) {


            size.set(getView().getWidth(), getView().getHeight());


            touch.set(_offset.x, _offset.y);
        }

        }


}

// CustomScrollView.java

public class CustomScrollView extends ScrollView{

    private OnScrollChanged onScrollChanged;
    private boolean hasScrollListener;




    private int mMaxYOverscrollDistance;    

    public CustomScrollView(Context context, AttributeSet attrs, int defStyle) 
    {
        super(context, attrs, defStyle);
        initBounceScrollView();
    }

    public CustomScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initBounceScrollView();

    }

    public CustomScrollView(Context context) {
        super(context);
        initBounceScrollView();
    }


    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) 
    {
        //if(AppConstants.DEBUG)Log.v(AppConstants.DEBUG_TAG,"onScrollChanged: "+l+":"+t+":"+oldl+":"+oldt);

        if(hasScrollListener)
        {
            onScrollChanged.onScrollChanged(this,l, t, oldl, oldt);

        }

        super.onScrollChanged(l, t, oldl, oldt);
    }

    @Override
    protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX,
            boolean clampedY) {

        super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
    }

    public OnScrollChanged getOnScrollChanged() {
        return onScrollChanged;
    }

    public void setOnScrollChanged(OnScrollChanged onScrollChanged) {

        this.onScrollChanged = onScrollChanged;
        hasScrollListener = true;
    }

     private void initBounceScrollView()
    {
        //get the density of the screen and do some maths with it on the max overscroll distance
        //variable so that you get similar behaviors no matter what the screen size


        mMaxYOverscrollDistance = getResources().getDimensionPixelSize(R.dimen.height_pullrefresh);//(int) (density * MAX_Y_OVERSCROLL_DISTANCE);
    }

    @Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) 
    { 

        //if(AppConstants.DEBUG) Log.v(AppConstants.DEBUG_TAG, "deltaX  "+deltaX+"  "+ deltaY+" "+ scrollX+" "+ scrollY+" "+ scrollRangeX+" "+ scrollRangeY+" "+ maxOverScrollX+" "+ maxOverScrollY+" "+ isTouchEvent);         
        if(scrollY==(-mMaxYOverscrollDistance) && isTouchEvent)
        {
            if(onScrollChanged!=null)   onScrollChanged.onOverScrolledAtMax();
        }
        //This is where the magic happens, we have replaced the incoming maxOverScrollY with our own custom variable mMaxYOverscrollDistance; 
        return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, mMaxYOverscrollDistance, isTouchEvent);  
    }

}

// OnScrollChanged.java接口

public interface OnScrollChanged {
     void onScrollChanged(View v,int l, int t, int oldl, int oldt );
     void onOverScrolledAtMax();
     void onOverScrolledStarted();
     void onOverScrolledEnded();
}