Custom ListView Implementation Drag-and-drop ListItem Exchange location (with source code) _android

Source: Internet
Author: User
Tags gety
It 's written in front of you.
In the previous article to achieve through the layout of the pump to get different layout for the ListItem layout, and then realize the contact ListView, this chapter is to do is drag ListView item, this chapter is based on the principle of a blog, Previous blog: Custom adapter and edit each item through layout pump layoutinflater crawl Layout template

Implementation of the effect diagram


Description
First of all we see the above picture is the implementation of the effect diagram. The data entry completes the swap position after dragging.

Functional Analysis
We see that this effect is a drag-and-drop ListView Item Location function, in terms of layout or using layout pump layoutinflater to get different layouts from different layout templates and then return view. About the layout of this knowledge in a detailed explanation, the beginning of the article has been explained, OK, let us analyze the implementation of this drag effect, the following article will be executed in the order of the method to give the code of each method. Then analyze the function of each method in turn.

Method Execution Order
[Dragview]-> [Initialize Listviewcontext, and the minimum distance variable that triggers the move event]
[Onintercepttouchevent]-> [initialize dragged variable]
[StartDrag]-> [ready to drag images, window, etc. variables]
[Stopdrag]-> [to determine the image of the reset drag]
[StartDrag]-> [ready to drag images, window, etc. variables]
[Ontouchevent]-> [Judge Click events, do different actions depending on the action, or redraw the move effect, or stop drag. Exchange data, which is the following two methods
[Ondrag]-> [implement scrolling action]
[OnDrop]-> [Implement data item position toggle]
Attention
The above method execution order is only probably logic, this also has the judgment and the method calls the other method, therefore the method invocation is many times, everybody does not have to look the method the general function, needs to note that we rewrite the ontouchevent to be continuously listens to our key, If the move is always going to call the Ondrag method to achieve the scrolling action, I did the test, for you to see the printed log as follows:

We saw that the move log was executed several times. This means that we have been executing this method while dragging. Below I will give you the custom ListView code, the code annotation quantity is very big, the readability is very high, recommended everybody reference above I give the method to run the order to understand, finally I will give the operation source code.
Copy Code code as follows:

Package Com.example.draglistview;
Import Com.example.draglistview.MainActivity.DragListAdapter;
Import Android.content.Context;
Import Android.graphics.Bitmap;
Import Android.graphics.BitmapFactory;
Import Android.graphics.PixelFormat;
Import Android.util.AttributeSet;
Import Android.util.Log;
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.widget.AdapterView;
Import Android.widget.ImageView;
Import Android.widget.ListView;
Import Android.widget.Toast;
public class Dragview extends listview{
Private ImageView ImageView; The picture being dragged
private int scaledtouchslop; Determine the distance to drag

private int dragsrcposition; The original position of the finger when touching the touch event
private int dragposition; The position of the finger when dragging the list item

private int dragpoint; Finger click Position in Current data item item, only Y coordinate
private int dragoffset; The position of the current view ListView in the screen, only the Y coordinate

private int upscrollbounce; The border that slides up
private int downscrollbounce; The border that slides down when you drag

Private WindowManager WindowManager = null; Window Management class
Window Parameter class
Private Windowmanager.layoutparams layoutparams = null;



Note that this view must be initialized using the following construct if the layout XML is registered
Public Dragview (context context, AttributeSet Attrs) {
Super (context, attrs);
The minimum distance to trigger a move event
Scaledtouchslop = Viewconfiguration.get (context). Getscaledtouchslop ();
}
Rewrite in Abslistview
@Override
public boolean onintercepttouchevent (Motionevent ev) {

if (ev.getaction () = = Motionevent.action_down) {
Gets the x-coordinate and y-coordinate of the touch event, which is relative to the upper-left corner of the component
int x = (int) ev.getx ();
int y = (int) ev.gety ();
Assign the start coordinates of the finger when clicked
Dragsrcposition = Dragposition = This.pointtoposition (x, y);
If you click outside the list, which is not allowed
if (dragposition = = adapterview.invalid_position) {
Execute the parent class directly without any action
return super.onintercepttouchevent (EV);
}

/***
* Lock the finger touch list item,
* parameter is the touch coordinate of the screen minus the coordinates of the upper-left corner of the ListView
* Here the Getchildat method parameter is relative to the component's upper left corner coordinates 00
* So there's the following parameter algorithm
*/
ViewGroup Itemview = (viewgroup) this.getchildat (Dragposition-this.getfirstvisibleposition ());
/****
* Description: GetX y is the touch point relative to the upper-left corner of the assembly distance
* GETRAWX, Y is the touch point relative to the upper left corner of the screen
* Reference http://blog.csdn.net/love_world_/article/details/8164293
*/
The distance from the touch point's view relative to the top coordinate of the ChildItem
Dragpoint = Y-itemview.gettop ();
Subtract the y from the upper-left corner of the screen from the y in the upper-left corner, which is actually
view+ title bar + status bar on top of component Y
Dragoffset = (int) (Ev.getrawy ()-y);

Get the dragged ImageView object
View Drager = Itemview.findviewbyid (r.id.imageview1);

Determines whether the condition is to drag the touch picture to a null and touch position, or to match
if (Drager!= null && x>drager.getleft ()-20) {

To determine the value of sliding up and down
Upscrollbounce = Math.min (Y-scaledtouchslop, GetHeight ()/3);
Downscrollbounce = Math.max (Y+scaledtouchslop, GetHeight () *2/3);
Enable drawing caching
Itemview.setdrawingcacheenabled (TRUE);
Get the corresponding bitmap from the image cache
Bitmap BM = Bitmap.createbitmap (Itemview.getdrawingcache ());
StartDrag (BM, y);
}
return false;
}
return super.onintercepttouchevent (EV);
}


Rewrite ontouchevent, touch events
@Override
public boolean ontouchevent (Motionevent ev) {
if (ImageView!= null && dragposition!= invalid_position) {
int currentaction = Ev.getaction ();

Switch (currentaction) {
Case MOTIONEVENT.ACTION_UP:
int upy = (int) ev.gety ();
There are also some operations
Stopdrag ();
OnDrop (Upy);
Break
Case Motionevent.action_move:
LOG.V ("Move", "Move---------");
int movey = (int) ev.gety ();
Ondrag (Movey);
Break
Default
Break
}
return true;
}
Determines the effect of the selection
return super.ontouchevent (EV);
}



/****
* Ready to drag, initialize the image when dragging, and some window parameters
* @param BM Drag cache bitmap
* @param y drag before the touch position
*/
public void StartDrag (Bitmap bm,int y) {
Stopdrag ();
Layoutparams = new Windowmanager.layoutparams ();
Set Gravity
layoutparams.gravity = Gravity.top;
The axis coordinates are unchanged.
layoutparams.x = 0;
/**
*
* y-coordinate is the view relative to the upper-left corner of the Y-touch point in the list item Y
* + View relative to the top left corner of the screen y,=
* The position of the view relative to the upper-left corner of the screen
*/
Layoutparams.y = Y-dragpoint+dragoffset;
/****
* Width and height are wrapcontent
*/
Layoutparams.width = WindowManager.LayoutParams.WRAP_CONTENT;
Layoutparams.height = WindowManager.LayoutParams.WRAP_CONTENT;

/****
* Set some flags parameters for the layout parameter
*/
Layoutparams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
Set the window item to be a semitransparent format
Layoutparams.format = pixelformat.translucent;
Settings are not animated
layoutparams.windowanimations = 0;

Configure an image ImageView
ImageView Imageviewfordragani = new ImageView (GetContext ());
Imageviewfordragani.setimagebitmap (BM);
Configure the WindowManager
WindowManager = (WindowManager) this.getcontext (). Getsystemservice ("window");
Windowmanager.addview (Imageviewfordragani, layoutparams);
ImageView = Imageviewfordragani;
}

/***
* Stop dragging, remove the image when dragging
*/
public void Stopdrag () {
if (ImageView!= null) {
Windowmanager.removeview (ImageView);
ImageView = null;
}
}


/****
* Drag method
* @param y
*/
public void Ondrag (int y) {

if (ImageView!= null) {
Transparency
Layoutparams.alpha = 0.8f;
Layoutparams.y = Y-this.dragpoint+this.dragoffset;
Windowmanager.updateviewlayout (ImageView, layoutparams);
}


Avoid dragging to split line return-1
int tempposition = this.pointtoposition (0, y);
if (tempposition!= this. Invalid_position) {
This.dragposition = tempposition;
}


int scrollheight = 0;
if (y<upscrollbounce) {
ScrollHeight = 8;//definition scrolls up by 8 pixels, if you can scroll up.
}else if (y>downscrollbounce) {
ScrollHeight = -8;//definition scrolls down by 8 pixels, if you can scroll up
}

if (scrollheight!=0) {
True scrolling Method Setselectionfromtop ()
Setselectionfromtop (Dragposition, Getchildat (Dragposition-getfirstvisibleposition ()). GetTop () +scrollHeight);
}
}


/***
* Drag down the time
* Param:y
*/
public void OnDrop (int y) {
int tempposition = this.pointtoposition (0, y);
if (tempposition!= this. Invalid_position) {
This.dragposition = tempposition;
}

Beyond boundary handling
if (Y<getchildat (1). GetTop ()) {
Beyond the upper boundary
Dragposition = 1;
}else if (Y>getchildat (Getchildcount ()-1). Getbottom ()) {
Beyond the bottom boundary
Dragposition = Getadapter (). GetCount ()-1;
//
}
Data exchange
if (Dragposition>0&&dragposition<getadapter (). GetCount ()) {
@SuppressWarnings ("Unchecked")
Draglistadapter adapter = (draglistadapter) getadapter ();
Item at original location
String Dragitem = Adapter.getitem (dragsrcposition);
Adapter.remove (Dragitem);
Adapter.insert (Dragitem, dragposition);
Toast.maketext (GetContext (), Adapter.getlist (). toString (), Toast.length_short). Show ();
}
}
}

It 's written in the back.
The above is the custom ListView source code. And of course there's some code that's not given. Includes mainactivity, 3 layout XML files. [Relatively simple] if you read [or have some questions] above this part of the code, you can download my source check related APIs and cases to learn, to progress, I wish success!

SOURCE download

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.