`

可以拖动的listview+限制拖动某一图片

阅读更多

 

 

可以拖动的listview+限制拖动某一图片

package com.coolwind.weather;

import java.lang.reflect.Field;

import android.app.Activity;
import android.app.Service;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.nfc.Tag;
import android.os.Vibrator;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListView;


public class SimpleDragListView extends ListView {
    private static final String TAG = "TAG_SimpleDragListView";

    private ImageView mDragView;
    private ImageView defaultview;
    private WindowManager mWindowManager;
    private WindowManager.LayoutParams mWindowParams;
    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 SimpleListener mSimpleListener;
    private GestureDetector mGestureDetector;
    private static final int FLING = 0;
    private static final int SLIDE = 1;
    private int mRemoveMode = -1;
    private Rect mTempRect = new Rect();
    private Bitmap mDragBitmap;
    private int mItemHeightNormal;
    private int mItemHeightExpanded;
    private int mItemHeightHalf;
    private int mLinearDeleHeight;
    private int mOptionItem = -1;
    private boolean mOptionDelItem = false;
    private Context mContext;
    private int mStatusBarHeight = 0;
    //added by zhangyulin for CR00683126 start
    private int mUpperBound;
    private int mLowerBound;
    private int mHeight;
    private final int mTouchSlop;
    private int oneScreenCount;
    //added by zhangyulin for CR00683126 end
    public SimpleDragListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        Resources res = getResources();
        mContext = context;
        mItemHeightNormal = res.getDimensionPixelSize(R.dimen.managecity_item_height);
        mItemHeightHalf = mItemHeightNormal / 2;
        mLinearDeleHeight = res.getDimensionPixelSize(R.dimen.manage_menulist_layout_height);
        mItemHeightExpanded = res.getDimensionPixelSize(R.dimen.managecity_item_height) * 2;
        try {
            Class<?> c = Class.forName("com.android.internal.R$dimen");
            Object obj = c.newInstance();
            Field field = c.getField("status_bar_height");
            int x = Integer.parseInt(field.get(obj).toString());
            int sbar = context.getResources().getDimensionPixelSize(x);
            mStatusBarHeight = sbar;
        } catch (Exception e1) {
            e1.printStackTrace();
        } 
         
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        if (mSimpleListener != null && mGestureDetector == null) {
            if (mRemoveMode == FLING) {
                mGestureDetector = new GestureDetector(getContext(),
                        new SimpleOnGestureListener() {
                            @Override
                            public boolean onFling(MotionEvent e1,
                                    MotionEvent e2, float velocityX,
                                    float velocityY) {
                                if (mDragView != null) {
                                    if (velocityX > 1000) {
                                        Rect r = mTempRect;
                                        mDragView.getDrawingRect(r);
                                        if (e2.getX() > r.right * 2 / 3) {
                                            // fast fling right with
                                            // release near the right
                                            // edge of the screen
                                            stopDragging();
                                            mSimpleListener
                                                    .remove(mFirstDragPos);
                                            unExpandViews(true);
                                        }
                                    }
                                    // flinging while dragging should
                                    // have no effect
                                    return true;
                                }
                                return false;
                            }
                        });
            }
        }
        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            if (mSimpleListener != null) {
                int x = (int) ev.getX();
                // int y = (int) ev.getY();
                int y = (int) ev.getRawY();
                y = y - mStatusBarHeight;
                Log.d(TAG, "mStatusBarHeight=" + mStatusBarHeight);
                mOptionItem = pointToPosition(x, y - getTop());
                if (mOptionItem == AdapterView.INVALID_POSITION) {
                    return false;
                }
               
                ViewGroup item=(ViewGroup) getChildAt(mOptionItem- getFirstVisiblePosition());
                 
                int firstposition=getFirstVisiblePosition();
               int lastposition=getLastVisiblePosition();
               oneScreenCount=(lastposition-firstposition)+1;//added byzhangyulin at 2012.10.17
                Log.d(TAG,"getChildCount() = " + getChildCount() +"oneScreenCount="+oneScreenCount);   
                mDragPoint = y - item.getBottom() - getTop()
                        + mItemHeightNormal;
                mCoordOffset = ((int) ev.getRawY()) - y + getTop();
                View dragger = item.findViewById(R.id.managecity_list_dragimg);
                Rect r = mTempRect;
                r.left = dragger.getLeft();
                r.right = dragger.getRight();
                r.top = dragger.getTop();
                r.bottom = dragger.getBottom();
                if ((r.left < x) && (x < r.right)) {
                    mSimpleListener.visible(View.VISIBLE);
                    Vibrator vibrator = (Vibrator) mContext
                            .getSystemService(Service.VIBRATOR_SERVICE);
                    vibrator.vibrate(90);
                    if(0==mOptionItem){
                        defaultview = (ImageView) item.findViewById(R.id.weather_isDefault);
                        defaultview.setVisibility(View.GONE);
                    }
                    item.setDrawingCacheEnabled(true);
                    Bitmap bitmap = Bitmap.createBitmap(item.getDrawingCache());
                    item.destroyDrawingCache();
                    // startDragging(bitmap, y);
                    startDragging(bitmap, y + mStatusBarHeight);
                    mDragPos = mOptionItem;
                    mFirstDragPos = mDragPos;
                    // added by zhangyulin for CR00683126 start
                    mHeight = getHeight();
                    int touchSlop = mTouchSlop;
                    mUpperBound = Math.min(y - touchSlop, mHeight / 3);
                    mLowerBound = Math.max(y + touchSlop, mHeight * 2 / 3);
                    // added by zhangyulin for CR00683126 end
                    Object temObject=getItemAtPosition(mFirstDragPos);
                    System.out.println("temObjecttemObjecttemObject"+temObject);
                    return false;
                }
                return true;
            }
            break;

        }
        return super.onInterceptTouchEvent(ev);
    }

  

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        Log.d("cng",".......");
        if (mGestureDetector != null) {
            mGestureDetector.onTouchEvent(ev);
        }
        if ((mSimpleListener != null) && mDragView != null) {
            int action = ev.getAction();
            switch (action) {
                case MotionEvent.ACTION_UP:
                    mSimpleListener.visible(View.INVISIBLE);
                    mSimpleListener.deleback(Color.DKGRAY);
                case MotionEvent.ACTION_CANCEL:
                    mSimpleListener.visible(View.INVISIBLE);
                    mSimpleListener.deleback(Color.DKGRAY);
                    Rect r = mTempRect;
                    mDragView.getDrawingRect(r);
                    stopDragging();
                   // float listBottom = getChildAt(getChildCount()-1).getBottom();  //最后一项底部边缘y值 办一张玉林
                    if (mRemoveMode == SLIDE && ev.getX() > r.right * 3 / 4) {
                        mSimpleListener.remove(mFirstDragPos);
                        unExpandViews(true);
                    } else {
                        if (mDragPos >= 0 && mDragPos < getCount()) {
                            if (mOptionDelItem == true) {
                                mSimpleListener.remove(mOptionItem);
                                mOptionDelItem = false;
                            } else {
                                Log.d(TAG, "mFirstDragPos = " +mFirstDragPos+"mDragPos = "+mDragPos);
                             
                                if(oneScreenCount==mDragPos){//added byzhangyulin at 2012.10.17
                                      mSimpleListener.drop(mFirstDragPos, mDragPos+1);
                                }else{
                                      mSimpleListener.drop(mFirstDragPos, mDragPos);
                                }
                            }
                        }
                        unExpandViews(false);
                    }
                   // if(0==mOptionItem){
                  /*      ViewGroup item=(ViewGroup) getChildAt(0);
                        defaultview = (ImageView) item.findViewById(R.id.weather_isDefault);
                        defaultview.setVisibility(View.VISIBLE);*/
                    //}
                    break;

                case MotionEvent.ACTION_DOWN:
                case MotionEvent.ACTION_MOVE:
                       Log.d("cng",".......");
                    int mx = (int) ev.getX();
                    int my = (int) ev.getY();               
                    dragView(mx, my);
                    int mitemnum = getItemForPosition(my);
                    if (mitemnum >= 0) {
                        if (action == MotionEvent.ACTION_DOWN || mitemnum != mDragPos) {
                            mSimpleListener.drag(mDragPos, mitemnum);
                            Log.d(TAG, "mitemnum = "+mitemnum);//8
                            Log.d(TAG, "mDragPos = "+mDragPos);//7
                            mDragPos = mitemnum;
                            doExpansion();
                        }
                    }
                  //added by zhangyulin for CR00683126 start
                    int speed = 0;
                    adjustScrollBounds(my);

                    if (my > mLowerBound) {
                        // scroll the list up a bit
                        if (getLastVisiblePosition() < getCount() - 1) {
                            speed = my > (mHeight + mLowerBound) / 2 ? 16 : 4;
                        } else {
                            speed = 1;
                        }
                    } else if (my < mUpperBound) {
                        // scroll the list down a bit
                        speed = my < mUpperBound / 2 ? -16 : -4;
                        if (getFirstVisiblePosition() == 0
                                && getChildAt(0).getTop() >= getPaddingTop()) {
                            // if we're already at the top, don't try to scroll,
                            // because
                            // it causes the framework to do some extra drawing that
                            // messes
                            // up our animation
                            speed = 0;
                        }
                    }
                    if (speed != 0) {
                        smoothScrollBy(speed, 30);
                    }
                    //added by zhangyulin for CR00683126 end
                    break;
            }
            return true;
        }
        return super.onTouchEvent(ev);
    }

    /*
     * pointToPosition() doesn't consider invisible views, but we need to, so
     * implement a slightly different version.
     */
    private int myPointToPosition(int x, int y) {

        if (y < 0) {
            // when dragging off the top of the screen, calculate position
            // by going back from a visible item
            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 - mItemHeightNormal ;
        int pos = myPointToPosition(0, adjustedy);
         Log.d("cng","pos = " + pos + ",adjustedy = " + adjustedy);
        if (pos >= 0) {
            if (pos <= mFirstDragPos) {
                pos += 1;
            }
        } else if (adjustedy < 0) {
            // this shouldn't happen anymore now that myPointToPosition deals
            // with this situation
            pos = 0;
        }
       
        if ((y > mHeight - mItemHeightNormal)
                && (pos == getCount() - 2)
                && (y >= mFirstDragPos + mItemHeightNormal /3)) {
               pos += 1;
          }
        return pos;
    }

    /*
     * Restore size and visibility for all listitems
     */
    private void unExpandViews(boolean deletion) {
        for (int i = 0;; i++) {
            View v = getChildAt(i);
            if (v == null) {
                if (deletion) {
                    // HACK force update of mItemCount
                    int position = getFirstVisiblePosition();
                
                    int y = getChildAt(0).getTop();
                    setAdapter(getAdapter());
                    setSelectionFromTop(position, y);
                    // end hack
                }
                layoutChildren(); // force children to be recreated where needed
                v = getChildAt(i);
                if (v == null) {
                    break;
                }
            }
            ViewGroup.LayoutParams params = v.getLayoutParams();
            params.height = mItemHeightNormal;
            v.setLayoutParams(params);
            v.setVisibility(View.VISIBLE);
        }
    }

    /*
     * Adjust visibility and size to make it appear as though an item is being
     * dragged around and other items are making room for it: If dropping the
     * item would result in it still being in the same place, then make the
     * dragged listitem's size normal, but make the item invisible. Otherwise,
     * if the dragged listitem is still on screen, make it as small as possible
     * and expand the item below the insert point. If the dragged item is not on
     * screen, only expand the item below the current insertpoint.
     */
    private void doExpansion() {
        int childnum = mDragPos - getFirstVisiblePosition();
        if (mDragPos > mFirstDragPos) {
            childnum++;
        }
        Log.d(TAG,"childnum = " + 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)) {
                // processing the item that is being dragged
                if (mDragPos == mFirstDragPos) {
                    // hovering over the original location
                    visibility = View.INVISIBLE;
                } else {
                    // not hovering over it
                    height = 1;
                }
            } else if (i == childnum) {
                 
                Log.d(TAG,"getCount() = " + getCount() +"mDragPos="+mDragPos);
                if (mDragPos < getCount() - 1) {
                    height = mItemHeightExpanded;
                }
                if(mDragPos ==oneScreenCount){
                    height = mItemHeightNormal;
                }
            }
            ViewGroup.LayoutParams params = vv.getLayoutParams();
            params.height = height;
            vv.setLayoutParams(params);
            vv.setVisibility(visibility);
        }
    }

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

        mWindowParams = new WindowManager.LayoutParams();
        mWindowParams.gravity = Gravity.TOP;
        mWindowParams.y = y - mItemHeightHalf;

        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.TRANSPARENT;
        mWindowParams.windowAnimations = 0;

        Context context = getContext();
        ImageView v = new ImageView(context);
        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) {
        if (mRemoveMode == SLIDE) {
            float alpha = 1.0f;
            int width = mDragView.getWidth();
            if (x > width / 2) {//1/2
                alpha = ((float) (width - x)) / (width / 2);
            }
            mWindowParams.alpha = alpha;
        }
        if (mRemoveMode == FLING) {
            mWindowParams.x = x;
        }
        mWindowParams.y = y - mItemHeightHalf + mCoordOffset;
        if (mWindowParams.y <= mLinearDeleHeight) {
            mOptionDelItem = true;
            mSimpleListener.deleback(Color.RED);
        } else {
            mOptionDelItem = false;
            mSimpleListener.deleback(Color.DKGRAY);
        }
        mWindowManager.updateViewLayout(mDragView, mWindowParams);
    }

    private void stopDragging() {
        if (mDragView != null) {
            mWindowManager.removeView(mDragView);
            mDragView = null;
        }
        if (mDragBitmap != null) {
            mDragBitmap.recycle();
            mDragBitmap = null;
        }
    }
  //added by zhangyulin for CR00683126 start
    private void adjustScrollBounds(int y) {
        if (y >= mHeight / 3) {
            mUpperBound = mHeight / 3;
        }
        if (y <= mHeight * 2 / 3) {
            mLowerBound = mHeight * 2 / 3;
        }
    }
    //added by zhangyulin for CR00683126 end
    public void setSimpleListener(SimpleListener l) {
        mSimpleListener = l;
    }

    public interface SimpleListener {
        void drag(int from, int to);

        void drop(int from, int to);

        void remove(int which);

        void visible(int del);
       
        void deleback(int id);
    }
}

分享到:
评论

相关推荐

    RecycleView+listview+GritView 拖拽功能

    RecycleView是Android 5.0引入的一个高效的数据视图,它在内存管理上优于ListView,因为它的item可以复用,减少了对象创建和销毁的开销。要实现拖拽功能,我们需要使用第三方库如`androidx.recyclerview.widget....

    listview里面可以拖动Item上下_ListView_listview拖动项_

    在Windows编程领域,ListView控件是一种常见的用户界面元素,用于展示列表形式...在提供的文件“listview里面可以拖动Item上下”中,可能包含了实现这一功能的示例代码或详细教程,可以帮助开发者更好地掌握这一技术。

    可以拖拽的ListView

    "可以拖拽的ListView"正是针对这一需求的一种扩展功能,它允许用户通过手势直接拖动ListView中的条目(Item)并重新排列它们的位置,提升了用户体验。 实现拖拽功能的关键在于对触摸事件的处理和ListView的适配器...

    实现可以拖动listview

    "实现可以拖动的listview"就是这样一个功能,允许用户通过直观的手势操作来改变列表中的元素顺序或进行删除操作。 实现拖动功能的关键在于使用特定的库或自定义适配器(Adapter)和视图(View)。在这个项目中,...

    android listview item 拖动排序

    通过以上步骤,你就可以在Android应用中实现一个功能完备的可拖动排序的ListView了。`DragSortListView`库简化了这个过程,提供了丰富的定制选项,使得开发者可以轻松地为用户提供直观、流畅的排序体验。记得根据...

    ListView +RatingBar +TextView +adapter

    RatingBar是一个滑动条形图,用户可以通过拖动星星来选择评分。它可以设置为半星或整星模式,也可以设置初始值和最大值。例如,通过`setNumStars()`方法设置星星数量,`setStepSize()`设置步长(半星或整星),`...

    可拖拽 listview

    在IT领域,特别是Android开发中,"可拖拽listview"是一种常见的用户界面设计,它允许用户通过拖放操作来改变listview中的元素顺序。这种交互方式极大地提升了用户体验,使得数据排序变得更加直观和便捷。本篇文章将...

    拖拽ListView

    拖拽ListView是一种在Android开发中实现用户交互效果的高级技巧,允许用户通过手势将列表项上下拖动,改变其在列表中的位置。这种功能常见于任务管理器、日程安排等应用,增强了用户体验,使数据排序更加直观和便捷...

    可以拖动的listview

    "可以拖动的listview"是指一种具有用户交互功能的ListView,允许用户通过直接拖动列表中的子项(item)来改变它们的顺序,这种特性在很多应用中都非常实用,比如任务管理器、音乐播放列表等。实现这一功能,通常需要...

    android listview 拖拽效果

    "android listview 拖拽效果"是指在ListView上实现的一项高级功能,允许用户通过手势拖动ListView中的每个条目(item)来改变它们的位置,提供了一种直观且交互性强的用户体验。在本篇文章中,我们将深入探讨如何...

    WPF 拖拽的实现(以listview为例)

    在Windows Presentation Foundation (WPF) 中,拖放操作是一种常见的用户交互方式,允许用户通过鼠标将项目从一个位置拖动到另一个位置。本教程将详细解释如何在ListView控件中实现拖放功能。 首先,我们需要了解...

    水平listview+wheelview+滑动条

    SeekBar是Android系统提供的一个进度条控件,用户可以通过拖动滑块来改变进度。在与水平ListView或WheelView结合使用时,滑动条可以用来调整视图的滚动位置,或者作为调整某些设置(如音量、亮度)的直观工具。通过...

    Android luncher拖动效果+listview下拉加载

    在Android开发中,"Android launcher拖动效果"和"listview下拉加载"是两个重要的功能模块,它们分别涉及到用户界面交互和数据加载优化。让我们深入探讨这些知识点。 首先,Android launcher是用户启动应用程序的主...

    ListView拖拽移位具体实现

    拖拽移位功能在许多应用中非常实用,比如文件管理器、任务列表等,用户可以通过拖动ListView中的条目来改变它们的顺序。本篇文章将详细介绍如何在Android中实现ListView的拖拽移位功能。 首先,我们需要创建一个...

    Android RecycleView+任意头尾布局+拖拽换位+拖拽删除demo

    本项目"Android RecycleView+任意头尾布局+拖拽换位+拖拽删除demo"聚焦于RecycleView的高级用法,包括自定义头部和尾部布局、实现拖拽换位以及拖拽删除功能,这些都是提高应用交互性的关键点。 1. **RecycleView...

    delphi中ListView拖动图标

    最后,对于初学者来说,通过不断实践和查看实例代码是学习Delphi ListView拖动图标功能的最好方式。可以参考开源项目、在线教程和Delphi社区论坛中的相关讨论,以便更好地理解和掌握这一技术。 总之,Delphi中的...

    拖拽ListView的实现

    拖拽ListView的实现,主要是指用户可以通过手势拖动ListView中的某一项到不同的位置,以达到重新排序的效果。这种功能在很多应用中都很常见,比如音乐播放器的播放列表等。 首先,我们要明确实现拖拽ListView的基本...

    android 拖拽列表listview

    拖拽列表功能可以让用户通过手势直接改变ListView中行的顺序,提供了更加直观和友好的交互体验。在本案例中,我们将深入探讨如何在Android中实现ListView的行拖拽功能,以及如何实现在多级列表间的行拖拽。 首先,...

    listview拖拽实现.rar

    本项目“listview拖拽实现.rar”是基于Visual Studio 2019的一个C# WinForms应用,它实现了用户可以将图片拖放到ListView中,从而增强了用户体验并提供了更直观的操作方式。 在C#编程中,实现ListView控件的拖放...

Global site tag (gtag.js) - Google Analytics