android listview拖拽,拖动item 改变位置
来源:互联网 发布:ios开发语言 java 编辑:程序博客网 时间:2024/05/16 07:34
转自:http://blog.csdn.net/dany1202/article/details/6109160#comments
在packages/apps/Music/src/touchIncepter.java中
该类提供了listview的拖动效果,并提供接口,在程序接口中实现数据的交换即可。
- package com.and.DragListview;
- import java.util.ArrayList;
- import java.util.List;
- import android.app.ListActivity;
- import android.content.Context;
- import android.os.Bundle;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.BaseAdapter;
- import android.widget.ImageView;
- import android.widget.TextView;
- public class DragListview extends ListActivity {
- MyAdapter adapter;
- TouchInterceptor list;
- List<String> arrayText;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- list = (TouchInterceptor) getListView();//(TouchInterceptor)findViewById(android.R.id.list);
- getText();
- adapter = new MyAdapter(this);
- setListAdapter(adapter);
- list.setDropListener(mDropListener);
- // list.setRemoveListener(mRemoveListener);
- }
- public void getText(){
- arrayText = new ArrayList<String>();
- arrayText.add("传奇");
- arrayText.add("红豆");
- arrayText.add("流年");
- arrayText.add("棋子");
- }
- //交换listview的数据
- private TouchInterceptor.DropListener mDropListener =
- new TouchInterceptor.DropListener() {
- public void drop(int from, int to) {
- String item = arrayText.get(from);
- arrayText.remove(item);//.remove(from);
- arrayText.add(to, item);
- adapter.notifyDataSetChanged();
- }
- };
- private TouchInterceptor.RemoveListener mRemoveListener =
- new TouchInterceptor.RemoveListener() {
- public void remove(int which) {
- }
- };
- class MyAdapter extends BaseAdapter{
- private LayoutInflater mInflater;
- Context mContext;
- public MyAdapter(Context c){
- mInflater = LayoutInflater.from(c);
- }
- public int getCount() {
- return arrayText.size();
- }
- public Object getItem(int arg0) {
- return arrayText.get(arg0);
- }
- public long getItemId(int arg0) {
- return arg0;
- }
- public View getView(int arg0, View contentView, ViewGroup arg2) {
- ImageView img;
- TextView text;
- if(contentView==null){
- contentView = mInflater.inflate(R.layout.list_layout, null);
- //contentView = mInflater.inflate(R.layout.list_layout,null);
- }
- img = (ImageView)contentView.findViewById(R.id.img);
- img.setBackgroundResource(R.drawable.icon);
- text = (TextView)contentView.findViewById(R.id.text);
- text.setText(arrayText.get(arg0).toString());
- return contentView;
- }
- }
- }
源码中的类:
- /*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package com.and.DragListview;
- import android.content.Context;
- import android.content.SharedPreferences;
- import android.content.res.Resources;
- import android.graphics.Bitmap;
- import android.graphics.PixelFormat;
- import android.graphics.Rect;
- import android.util.AttributeSet;
- import android.view.GestureDetector;
- import android.view.Gravity;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.ViewConfiguration;
- import android.view.ViewGroup;
- import android.view.WindowManager;
- import android.view.GestureDetector.SimpleOnGestureListener;
- import android.widget.AdapterView;
- import android.widget.ImageView;
- import android.widget.ListView;
- public class TouchInterceptor extends ListView {
- private ImageView mDragView;
- 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 DragListener mDragListener;
- private DropListener mDropListener;
- private RemoveListener mRemoveListener;
- private int mUpperBound;
- private int mLowerBound;
- private int mHeight;
- 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 final int mTouchSlop;
- private int mItemHeightNormal;
- private int mItemHeightExpanded;
- private int mItemHeightHalf;
- public TouchInterceptor(Context context, AttributeSet attrs) {
- super(context, attrs);
- SharedPreferences pref = context.getSharedPreferences("Music", 3);
- mRemoveMode = pref.getInt("deletemode", -1);
- mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
- Resources res = getResources();
- mItemHeightNormal = 48;//res.getDimensionPixelSize(R.dimen.normal_height);
- mItemHeightHalf = mItemHeightNormal / 2;
- mItemHeightExpanded = 96;//res.getDimensionPixelSize(R.dimen.expanded_height);
- }
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (mRemoveListener != 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();
- mRemoveListener.remove(mFirstDragPos);
- unExpandViews(true);
- }
- }
- // flinging while dragging should have no effect
- return true;
- }
- return false;
- }
- });
- }
- }
- 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;
- View dragger = item.findViewById(R.id.img);//..........................
- Rect r = mTempRect;
- dragger.getDrawingRect(r);
- // The dragger icon itself is quite small, so pretend the touch area is bigger
- if (x < r.right * 2) {
- item.setDrawingCacheEnabled(true);
- // Create a copy of the drawing cache so that it does not get recycled
- // by the framework when the list tries to clean up memory
- 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;
- }
- stopDragging();
- break;
- }
- }
- return super.onInterceptTouchEvent(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 - mDragPoint - mItemHeightHalf;
- int pos = myPointToPosition(0, 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;
- }
- return pos;
- }
- private void adjustScrollBounds(int y) {
- if (y >= mHeight / 3) {
- mUpperBound = mHeight / 3;
- }
- if (y <= mHeight * 2 / 3) {
- mLowerBound = mHeight * 2 / 3;
- }
- }
- /*
- * 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++;
- }
- 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) {
- 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 (mGestureDetector != null) {
- mGestureDetector.onTouchEvent(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 (mRemoveMode == SLIDE && ev.getX() > r.right * 3 / 4) {
- if (mRemoveListener != null) {
- mRemoveListener.remove(mFirstDragPos);
- }
- unExpandViews(true);
- } else {
- 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.dragndrop_background);
- // v.setBackgroundColor(backGroundColor);
- v.setImageBitmap(bm);
- mDragBitmap = bm;
- mWindowManager = (WindowManager)context.getSystemService("window");
- 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) {
- alpha = ((float)(width - x)) / (width / 2);
- }
- mWindowParams.alpha = alpha;
- }
- if (mRemoveMode == FLING) {
- mWindowParams.x = x;
- }
- mWindowParams.y = y - mDragPoint + mCoordOffset;
- mWindowManager.updateViewLayout(mDragView, mWindowParams);
- }
- private void stopDragging() {
- if (mDragView != null) {
- WindowManager wm = (WindowManager)getContext().getSystemService("window");
- 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 void setRemoveListener(RemoveListener l) {
- mRemoveListener = 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);
- }
- }
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="18sp"
android:drawSelectorOnTop="false"
android:fastScrollEnabled="true" />
如果想要实现源码音乐播放器那种顺畅的拖动效果,则需注意2点:
1.<!-- height of a normal list item in edit playlist mode -->
<dimen name="normal_height">48dip</dimen>
<!-- height of an expanded list item in edit playlist mode -->
<dimen name="expanded_height">96dip</dimen>
后者的高度要为前者的2倍。
2.item对应的布局要在listview的item的bottom位置,即:
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="48dip">
- <com.android.weather.CityListItemLayout
- android:id="@+id/item_layout"
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="48dip"
- android:gravity="center_vertical"
- android:layout_alignParentBottom="true">
- 。。。
- </com.android.weather.CityListItemLayout>
- </RelativeLayout>
- android listview拖拽,拖动item 改变位置
- android listview拖拽,拖动item 改变位置
- Android中ListView组件的Item拖动(Item改变顺序)
- Android中ListView组件的Item拖动(Item改变顺序)
- Android拖动改变小球位置
- Android中ListView组件的Item拖动
- 拖动实现listview的item改变顺序(DragSortListView)
- listview长按后拖动item交换位置的帮助类
- ListView 拖拽Item交换位置
- Android拖动控件改变其位置
- Android拖动控件改变其位置
- 【Android多屏适配】动态改变Listview item高度
- android的listview,怎么改变item内容?
- ListView拖动(或长按拖动)子项item,更改位置,且可以左右滑删除子项item
- Android使用ItemTouchHelper实现RecyclerView的item拖动位置交换
- android 开源项目(二)可以左右拖动删除、调换位置的的listview的 item的实现(drag-sort-listview)
- listview 拖动item效果实现
- Android:图片中叠加文字,支持拖动改变位置
- 无线网络攻防实战:WEP密钥如何被攻破的
- NYOJ143 康托的应用
- 求Sn=a+aa+aaa+……+aa……a的值
- UVA 11218 (KTV唱歌 回溯法 13.11.09)
- WindowForms读取Excel文件的数据
- android listview拖拽,拖动item 改变位置
- HQL查询
- jsp在ie中不兼容问题
- Linux菜鸟入门级命令大全
- Winpcap学习
- 初识MongoDB-用法和用途
- 闲谈机器学习
- 最详细的黑客教程
- html Image Placeholder