Post please indicate this article from xiaanming blog (http://blog.csdn.net/xiaanming/article/details/17539199), please respect others' hard work results, thank you!
In my previous article, Android showed you how to parse Scroller's rolling implementation principle from the source code perspective, I believe that you have a certain understanding of the use of scroroller. This article will give you a small example of scroroller to help you better understand the use of scroroller, after understanding the use of scroroller, we can achieve a lot of sliding effects. For example, slide menus, launcher, and ListView pull-down refresh effects. What I implement today is the effect of sliding the left and right of the ListView item to delete the item, now many of my friends see this effect in the Android notification bar drop-down list, I can see that this effect is very good when I slide the phone left and right on my SamSung mobile phone and send a text message, but now many mobile phone contacts slide not the effect of my previous mobile phone, many friends on the Internet also wrote an example about sliding to delete an item of ListView. Some of them are moving the item to the left or right after moving the finger away, I think this user experience is not very good, so today I also wrote a small example about ListView sliding to delete items, the items of ListView will slide with the finger sliding on the screen, when the finger leaves the screen, the item will draw the screen left or right based on the judgment, which is similar to the effect of the notification bar. Next we will show you how to achieve this effect.
Let's talk about the main idea of achieving this effect.
The main idea is the above three steps. Next we will use the code to implement it. First, we will create a project called SlideCutListView.
As needed, we need to customize a ListView to implement this function. Next we will post the code and then explain the specific implementation.
Package com. example. slidecutlistview; import android. content. context; import android. util. attributeSet; import android. view. motionEvent; import android. view. velocityTracker; import android. view. view; import android. view. viewConfiguration; import android. view. windowManager; import android. widget. adapterView; import android. widget. listView; import android. widget. scroller;/*** @ blog http://blog.csdn.net/xiaanm Ing ** @ author xiaanming **/public class SlideCutListView extends ListView {/*** currently sliding ListView position */private int slidePosition; /*** press the coordinates of X by finger */private int downY;/*** press the coordinates of Y by finger */private int downX; /***** screen width */private int screenWidth;/***** ListView's item */private View itemView;/***** slide class */private Scroller scroller; private static final int SNAP_VELOCITY = 600;/*** Speed Tracing object */private Velocity Tracker velocityTracker;/*** whether to respond to slide. The default value is "no response" */private boolean isSlide = false;/*** determines it is the minimum distance between the user and the private int mTouchSlop; /*** callback interface after the item is removed */private RemoveListener mRemoveListener;/*** indicates the direction in which the item slides out of the screen, left or right, use an enumerated value to mark */private RemoveDirection removeDirection; // The enumerated value of the sliding Delete direction public enum RemoveDirection {RIGHT, LEFT;} public SlideCutListView (Context context) {this (context, null);} public SlideCutList View (Context context, AttributeSet attrs) {this (context, attrs, 0);} public SlideCutListView (Context context, AttributeSet attrs, int defStyle) {super (context, attrs, defStyle); screenWidth = (WindowManager) context. getSystemService (Context. WINDOW_SERVICE )). getdefadisplay display (). getWidth (); scroller = new Scroller (context); mTouchSlop = ViewConfiguration. get (getContext ()). getScaledTouchSlop ();}/*** settings Sliding the delete callback interface * @ param removeListener */public void setRemoveListener (RemoveListener removeListener) {this. mRemoveListener = removeListener;}/*** distribution event, mainly used to determine the item clicked, and postDelayed to set the response to the left and right sliding event */@ Overridepublic boolean dispatchTouchEvent (MotionEvent event) {switch (event. getAction () {case MotionEvent. ACTION_DOWN: {addVelocityTracker (event); // if the scroller scroll is not over, we will return if (! Scroller. isFinished () {return super. dispatchTouchEvent (event);} downX = (int) event. getX (); downY = (int) event. getY (); slidePosition = pointToPosition (downX, downY); // The position is invalid and will not be processed. if (slidePosition = AdapterView. INVALID_POSITION) {return super. dispatchTouchEvent (event);} // obtain the item viewitemView = getChildAt (slidePosition-getFirstVisiblePosition (); break;} case MotionEvent. ACTION_MOVE: {I F (Math. abs (getScrollVelocity ()> SNAP_VELOCITY | (Math. abs (event. getX ()-downX)> mTouchSlop & Math. abs (event. getY ()-downY) <mTouchSlop) {isSlide = true;} break;} case MotionEvent. ACTION_UP: recycleVelocityTracker (); break;} return super. dispatchTouchEvent (event);}/*** slide to the right. getScrollX () returns the distance from the left edge, that is, the distance from the left edge of the View to the start of sliding, so sliding to the right is a negative value */private void scrollRight () {removeDirection = RemoveDirection. R IGHT; final int delta = (screenWidth + itemView. getScrollX (); // call the startScroll method to set some rolling parameters. We call scrollTo in the computeScroll () method to scroll itemscroller. startScroll (itemView. getScrollX (), 0,-delta, 0, Math. abs (delta); postInvalidate (); // refresh itemView}/*** slides to the left. Based on the above information, sliding to the left is a positive value */private void scrollLeft () {removeDirection = RemoveDirection. LEFT; final int delta = (screenWidth-itemView. getScrollX (); // call startScrol L method to set some rolling parameters. We call scrollTo in the computeScroll () method to scroll itemscroller. startScroll (itemView. getScrollX (), 0, delta, 0, Math. abs (delta); postInvalidate (); // refresh itemView}/*** use the finger to scroll the itemView distance to determine whether to scroll to the start position or to the left or right */private void scrollByDistanceX () {// if the left-side scrolling distance is greater than 1/3 of the screen size, delete if (itemView. getScrollX ()> = screenWidth/3) {scrollLeft ();} else if (itemView. getScrollX () <=-screenWidth/3) {scrollRight ();} else {// Roll back to the original location. In order to steal the lazy information, scrollTo is called directly to scroll itemView. scrollTo (0, 0) ;}}/*** process the logic of dragging the ListView item */@ Overridepublic boolean onTouchEvent (MotionEvent ev) {if (isSlide & slidePosition! = AdapterView. INVALID_POSITION) {addVelocityTracker (ev); final int action = ev. getAction (); int x = (int) ev. getX (); switch (action) {case MotionEvent. ACTION_MOVE: int deltaX = downX-x; downX = x; // scroll itemView with your fingers. Scroll itemView with deltaX greater than 0 to the left, and scroll itemView with deltaX less than 0 to the right. scrollBy (deltaX, 0); break; case MotionEvent. ACTION_UP: int velocityX = getScrollVelocity (); if (velocityX> SNAP_VELOCITY) {scrollRight ();} else if (velocityX <-S NAP_VELOCITY) {scrollLeft ();} else {scrollByDistanceX ();} recycleVelocityTracker (); // when the finger leaves, the isSlide = false; break;} return true; // when dragging, The ListView does not scroll} // otherwise, it is directly handed over to the ListView to handle the onTouchEvent return super. onTouchEvent (ev) ;}@ Overridepublic void computeScroll () {// scroller when startScroll is called. computescroloffset () returns true, if (scroller. computescroloffset () {// Let the ListView item scroll itemView based on the current rolling offset. scrollTo (Scroller. getCurrX (), scroller. getCurrY (); postInvalidate (); // call the callback interface if (scroller. isFinished () {if (mRemoveListener = null) {throw new NullPointerException ("RemoveListener is null, we shocould called setRemoveListener ()");} itemView. scrollTo (0, 0); mRemoveListener. removeItem (removeDirection, slidePosition) ;}}/ *** Add a user's speed tracker ** @ param event */private void addVelocityTracker (MotionEvent eve Nt) {if (velocityTracker = null) {velocityTracker = VelocityTracker. obtain ();} velocityTracker. addMovement (event);}/*** Remove User speed tracker */private void recycleVelocityTracker () {if (velocityTracker! = Null) {velocityTracker. recycle (); velocityTracker = null;}/*** get the sliding speed in the X direction. If the sliding speed is greater than 0, slide to the right, and vice versa to the left ** @ return */private int getScrollVelocity () {velocityTracker. computeCurrentVelocity (1000); int velocity = (int) velocityTracker. getXVelocity (); return velocity;}/***** when the ListView item slides out of the screen, the callback interface * we need to remove this Item from the callback method removeItem, then refresh the ListView ** @ author xiaanming **/public interface RemoveListener {public void removeItem (RemoveDirection direction, int position );}}
- First, we override the dispatchTouchEvent () method, which is the event distribution method. We only perform some simple steps in it. When we press the screen, if an item is rolling, we directly handed it to the parent class of SlideCutListView to handle the distribution event. Otherwise, based on the X and Y coordinates of the click, pointToPosition (int x, int y) is used to obtain which position of the ListView is clicked, so as to get the View of the item we need to slide, we also added the sliding speed detection in this method, and in ACTION_MOVE, we can determine whether to respond to the left and right movement of the item, isSlide is used to record whether to respond to Sliding between left and right
- The onTouchEvent () method is rewritten. We first judge that isSlide is true, and click the valid position on the ListView. Otherwise, it is directly handed over to the parent class of SlideCutListView, that is, ListView for processing, in ACTION_MOVE, scrollBy () is called to move an item. scrollBy () is relative to the previous position of the item, so every time we use the current moving distance minus the distance from the previous position and then assign it to the scrollBy () method, we implement smooth movement of items, when we lift our fingers, we first determine whether the item slides out of the screen or to the original position based on the speed at which the finger slides. If the speed to the right is greater than the SNAP_VELOCITY we set, the scrollRight () method is called to roll out the screen. If the speed to the left is less than-SNAP_VELOCITY, scrollLeft () is called to roll out the screen to the left. If we move the item slowly, then, the scrollByDistanceX () method is called to determine which position is to be rolled.
In the scrollRight () and scrollLeft () methods, we use the startScroll () method of the scroroller class to set the rolling parameters first, and then call postInvalidate () to refresh the interface, when the interface is refreshed, The computeScroll () method is called. You can process the rolling logic in it. It is worth mentioning the code in computeScroll ().
itemView.scrollTo(0, 0);
We need to scroll this item to the (0, 0) point, because we only scroll the ListView Item out of the screen, and did not remove this item, in addition, we cannot manually call removeView () to remove this item from ListView. We can only change the data of ListView and then refresh the ListView through yydatasetchanged, so we need to scroll it to (0, 0), which is more important here.
After defining the left-right sliding ListView, we will use it next. The layout is very simple. A RelativeLayout package our custom ListView
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/darker_gray"> <com.example.slidecutlistview.SlideCutListView android:id="@+id/slideCutListView" android:layout_width="match_parent" android:layout_height="match_parent" android:listSelector="@android:color/transparent" android:divider="@drawable/reader_item_divider" android:cacheColorHint="@android:color/transparent"> </com.example.slidecutlistview.SlideCutListView></RelativeLayout>
Next, let's take a look at the layout of the ListView item.
<?xml version="1.0" encoding="UTF-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@drawable/friendactivity_comment_detail_list2" > <TextView android:id="@+id/list_item" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="15dip" /> </LinearLayout></LinearLayout>
I still remember the previous article mentioned that calling the scrollTo () method is to scroll the child View, rather than scrolling the entire layout, so we use LinearLayout to hide the layout of our items. Pay attention to this point. Otherwise, only TextView is scrolling.
The MainActivity code on the home page is relatively simple, and ArrayAdapter is used in it. I believe everyone can understand it.
Package com. example. slidecutlistview; import java. util. arrayList; import java. util. list; import android. app. activity; import android. OS. bundle; import android. view. view; import android. widget. adapterView; import android. widget. adapterView. onItemClickListener; import android. widget. arrayAdapter; import android. widget. toast; import com. example. slidecutlistview. slideCutListView. removeDirection; import com. exampl E. slidecutlistview. slideCutListView. removeListener; public class MainActivity extends Activity implements RemoveListener {private SlideCutListView slideCutListView; private ArrayAdapter <String> adapter; private List <String> javascelist = new ArrayList <String> (); @ Overrideprotected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); ini T ();} private void init () {slideCutListView = (SlideCutListView) findViewById (R. id. slideCutListView); slideCutListView. setRemoveListener (this); for (int I = 0; I <20; I ++) {dataSourceList. add ("slide Delete" + I);} adapter = new ArrayAdapter <String> (this, R. layout. listview_item, R. id. list_item, dataSourceList); slideCutListView. setAdapter (adapter); slideCutListView. setOnItemClickListener (new OnItemClickListener (){@ Overridepublic void onItemClick (AdapterView <?> Parent, View view, int position, long id) {Toast. makeText (MainActivity. this, dataSourceList. get (position), Toast. LENGTH_SHORT ). show () ;}}) ;}// sliding the callback method after deletion @ Overridepublic void removeItem (RemoveDirection direction, int position) {adapter. remove (adapter. getItem (position); switch (direction) {case RIGHT: Toast. makeText (this, "delete right" + position, Toast. LENGTH_SHORT ). show (); break; case LEFT: Toast. makeText (this, "delete from left" + position, Toast. LENGTH_SHORT ). show (); break; default: break ;}}}
In this case, you need to set RemoveListener for the SlideCutListView, and then delete the position data in the callback method RemoveDirection ction, int position, and refresh the ListView by calling notifyDataSetChanged, here I am using ArrayAdatper. You can directly call remove.
All the code is compiled. Let's run the program to see the effect.
Now, today's explanation is over. If you have any questions, please leave a message below. I will help you answer the question. Today is the last day of March 2013. I hope you will have a happy new year!
Project source code, click to download
I am honored to beCSDN 2013 blog Star SelectionHope to continue to get everyone's support and encouragement. If you see a friend, please vote for me!
Voting address: Http://vote.blog.csdn.net/blogstaritem/blogstar2013/xiaanming