Android Event Distribution learning app-Photo carousel implementation

Source: Internet
Author: User

The previous article written to the Android event distribution mechanism Learning notes, below we have an example of the application to practice understanding the Android event distribution mechanism. We are here to implement a picture of the carousel function, and finally the way to achieve the automatic rotation of the chip.

Our picture carousel is encapsulated in a viewgroup, and when we are sliding horizontally, we need to block events from ViewGroup to child controls to distribute, ViewGroup to consume our current sliding picture where to go. Below we post the code for our encapsulated ViewGroup as follows:

public class Imageswitcher extends ViewGroup {private String TAG = ImageSwitcher.class.getSimpleName ();p rivate static fin Al int snap_velocity = 300;private Scroller scroller;private velocitytracker mvelocitytracker;private int mTouchSlop; private float mmotionx;private int mimagewidth; private int imagecount;private int mindex;private int mimageheight;private int[] Imageitems;private Boolean forcetorelayout;private int mtouchstate = touch_state_rest;private static final int touch_state_rest = 0;private static fi nal int touch_state_scrolling = 1;private static final int auto_msg = 0;private static final int start_msg =2;private stat IC final int handle_msg = 1;private static final long photo_change_time = 4000;private Handler Mhandler = new Handler () { Handle pictures automatically or manually scrolling operations public void Handlemessage (Message msg) {switch (msg.what) {case auto_msg:scrolltonext (); Mhandler.sendemptymessagedelayed (auto_msg, photo_change_time); Break;case start_msg: Mhandler.sendemptymessagedelayed (Auto_msg, Photo_chanGe_time); break;case HANDLE_MSG:mHandler.removeMessages (auto_msg); Mhandler.sendemptymessagedelayed (Auto_msg, Photo_change_time);d efault:break;}}};/ * * indicates scrolling to the next picture this action */private static final int scroll_next = 0;/** * means scrolling to the previous picture this action */private static final int Scroll_prev IOUS = 1;private static final int scroll_back = 2;public Imageswitcher (context context, AttributeSet Attrs) {Super (context , attrs); scroller = new Scroller (context); mtouchslop = Viewconfiguration.get (GetContext ()). Getscaledtouchslop (); /** * Start execution when view is added to the window container: life cycle successively Onmeasure > OnLayout > OnDraw >onattachedtowindow */@ overrideprotected void Onattachedtowindow () {Super.onattachedtowindow (); Mhandler.sendemptymessage (START_MSG);// Send a message let the picture automatically start scrolling} @Overrideprotected void OnLayout (Boolean changed, int l, int t, int r, int b) {if (changed | | forcetorelayout {imagecount = Getchildcount (); mimagewidth = Getmeasuredwidth (); mimageheight = Getmeasuredheight (); int marginLeft = 0; Scroller.abortanimation (); Set Scroller to scrollStatus This.scrollto (0, 0); Resets the scrolling initial position each time the layout is int[] items = {Getindexforitem (1), Getindexforitem (2), Getindexforitem (3), Getindexforitem (4), Getindexforitem (5)};imageitems = items;for (int i = 0; i < items.length; i++) {ImageView Childview = (ImageView) Getchi Ldat (Items[i]); Childview.layout (marginleft, 0, marginleft+ mimagewidth, mimageheight); marginleft = MarginLeft + Mimagewidth;} Refreshimageview (); forcetorelayout = false;}} private void Refreshimageview () {for (int i = 0; i < imageitems.length; i++) {ImageView Childview = (ImageView) Getchilda T (Imageitems[i]); Childview.invalidate ();}} private int Getindexforitem (int item) {int index = -1;index = Mindex + item-3;while (Index < 0) {index = index + imag Ecount;} while (Index > imageCount-1) {index = Index-imagecount;}    return index;} @Overridepublic boolean onintercepttouchevent (motionevent ev) {int action = ev.getaction (); if (action = = Motionevent.ac Tion_move) && (mtouchstate! = touch_state_rest)) {return true;} Float Xloc = Ev.getx (); switch (action) {case MotionEvent.ACTION_DOWN:mMotionX = Xloc;mtouchstate = Touch_state_rest;  LOG.E (TAG, "onintercepttouchevent action_down");   Break;case motionevent.action_move:log.e (TAG, "onintercepttouchevent action_move"); int xdif = (int) math.abs (mmotionx-xloc); if (Xdif > Mtouchslop) {//when our horizontal distance scrolls to reach the minimum distance we scroll, start intercepting ViewGroup events to the child control distribution mtouchstate = touch_state_scrolling;}  Break;case motionevent.action_up:log.e (TAG, "onintercepttouchevent action_up"); Mtouchstate = Touch_state_rest;break;case motionevent.action_cancel:log.e (TAG, "Onintercepttouchevent ACTION_CANCEL "); mtouchstate = TOUCH_STATE_REST;BREAK;DEFAULT:LOG.E (TAG," onintercepttouchevent default "); mtouchstate = TOUCH_    State_rest; break;} return mtouchstate! = touch_state_rest;} @Overridepublic boolean ontouchevent (Motionevent event) {if (scroller.isfinished ()) {//scroller has not yet started or has been completed, The following code starts execution if the finger slips (Mvelocitytracker = = null) {Mvelocitytracker = Velocitytracker.obtain ();} Mvelocitytracker.addmovement (EVENT); int action = Event.getaction (); float x = Event.getx (); switch (action) {case motionevent.action_down:// Record the horizontal axis when pressed Mmotionx = x;case MotionEvent.ACTION_MOVE:int disx = (int) (mmotionx-x); Mmotionx = X;scrollby (disx, 0); Break;ca Se MotionEvent.ACTION_UP:mVelocityTracker.computeCurrentVelocity (+); int velocityx = (int) Mvelocitytracker.getxvelocity (); if (Judescrolltonext (Velocityx)) {//Next graph Scrolltonext ();} else if ( Judescrolltoprevious (Velocityx)) {//Previous picture scrolltoprevious ();} else {//Current picture Scrollback ();} if (mvelocitytracker! = null) {mvelocitytracker.recycle (); mvelocitytracker = null;} Mhandler.sendemptymessagedelayed (handle_msg, photo_change_time); return true;}} return false; }private void Scrollback () {if (scroller.isfinished ()) {Beginscroll (GETSCROLLX (), 0,-getscrollx (), 0,scroll_back);}} private void Scrolltoprevious () {if (scroller.isfinished ()) {Setimageswitchindex (scroll_previous); int DISX =- Mimagewidth-getscrollx (); Beginscroll (Getscrollx (), 0, DISX, 0,scroll_previous);}} Privatevoid Scrolltonext () {if (scroller.isfinished ()) {Setimageswitchindex (scroll_next); int disx = MIMAGEWIDTH-GETSCROLLX () ; Beginscroll (GETSCROLLX (), 0, DISX, 0,scroll_next);}} /** * Picture starts sliding */private void beginscroll (int startX, int starty, int dx, int dy,final int action) {int duration = (int) (70 0f/mimagewidth * Math.Abs (DX)); Scroller.startscroll (StartX, starty, DX, dy, duration); invalidate (); Mhandler.postdelayed (New Runnable () {@Overridepublic void run () {if (action = = Scroll_next | | action = = scroll_previous) { Forcetorelayout = True;requestlayout ();}}}, duration);} private void Setimageswitchindex (int action) {if (action = = Scroll_next) {if (Mindex < imagecount) {mindex++;} Else{mindex = 0;}} else if (action = = scroll_previous) {if (Mindex > 0) {mindex--;} Else{mindex = ImageCount-1;}}} /** * Judge Time slip forward A * @param Velocityx * @return */private boolean judescrolltoprevious (int velocityx) {return Velocityx > snap_velocity | | GETSCROLLX () <-MIMAGEWIDTH/2;} /** * Judge time slip backwards one * @param velocitYX * @return */private boolean judescrolltonext (int velocityx) {return Velocityx <-snap_velocity| | getscrollx () > m IMAGEWIDTH/2;} @Overridepublic void Computescroll () {if (Scroller.computescrolloffset ()) {ScrollTo (Scroller.getcurrx ()),    Scroller.getcurry ()); Refresh view otherwise the effect may have an error postinvalidate ();}}}

From code Analysis We know that when we judge finger events, when we are in the action_move, we judge when the horizontal moving distance can be judged to be greater than the minimum distance of the movement, we intercept the event ViewGroup down, Events this time will go viewgroup ontouchevent to consume events, we have to read the picture of the roller skating processing in the ontouchevent to deal with.

In this demo we want to note that we look at our layout file as follows:

<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 "> < Com.zhanglei.imageswitcher.ImageSwitcher android:id= "@+id/image_switch_view" android:layout_width= "Match_par Ent "android:layout_height=" 200DP "> <imageview android:id=" @+id/image1 "Android            : layout_width= "match_parent" android:layout_height= "match_parent" android:scaletype= "FitXY" Android:clickable= "true" android:src= "@drawable/item01"/> <imageview android:id= "@+i D/image2 "android:layout_width=" match_parent "android:layout_height=" Match_parent "Androi D:scaletype= "Fitxy" android:clickable= "true" android:src= "@drawable/item02"/> <imagevie W android:id= "@+id/image3" AndroidOid:layout_width= "Match_parent" android:layout_height= "match_parent" android:scaletype= "FitXY" Android:clickable= "true" android:src= "@drawable/item03"/> <imageview android:id= " @+id/image4 "android:layout_width=" match_parent "android:layout_height=" Match_parent "and Roid:scaletype= "Fitxy" android:clickable= "true" android:src= "@drawable/item04"/> <imag Eview android:id= "@+id/image5" android:layout_width= "Match_parent" android:layout_height= "Match_parent" android:scaletype= "Fitxy" android:clickable= "true" android:src= "@drawable/ Item05 "/> </com.zhanglei.imageswitcher.ImageSwitcher></RelativeLayout>
We see that we have set the clickable = "true" property on ImageView, and if we remove the attribute here, we cannot manually swipe the image.

Everybody's going to wonder why. Let's follow the previous article on the Android event distribution mechanism to learn the event distribution analysis of notes to make a solution. We pass analysis, if we do not give ImageView set clickable= "true", ImageView Oneventtouch try to consume time will find if (((viewflags & clickable) = = clickable | | (ViewFlags & long_clickable) = = long_clickable) go into judgment, Oneventtouch return value is False, The ImageView dispatchtouchevent returns to false, meaning that the ImageView control is not consuming events by default. Remember that we mentioned in the event distribution of Android that when one of our events started distributing from activity to the leaf control, to the leaf control to start a layer of backtracking to try consuming events, remember what we said last time the event "Memory" function, When the events we distribute from activity go back to when the activity is not consumed, subsequent events do not continue to be distributed from the root control Decorview.

below we want to ask, then we do not give imageview set clickable = "true", there is no way to let the picture can slide it? The answer, of course, is that we use a button here instead of ImageView; method Two, we imageview not consume the event, our event will go back to ViewGroup to try to consume, We can spend in ViewGroup ontouchevent, by modifying the return value of Ontouchevent to true, to achieve the effect of consumption. Then we will remember the action of the event distribution consumption "loop", our subsequent events will be able to get consumption, our approach is to return to the ViewGroup in the Ontouchevent return value to consume, Here we can completely comment out the event intercept onintercepttouchevent, which also achieves the effect of our code above. The above is the main explanation of the event processing process of the picture carousel, and the code that handles the automatic rotation of the picture is added.

There is time later, I will try to analyze the process of more complex event distribution, for example, the base class of the ListView Abslistview has joined its own event distribution, interception processing, how we do our own event to the ListView interception processing, Welcome to shoot bricks. Finally, the Demowith the chip carousel example.

Reprint Please specify source: http://blog.csdn.net/johnnyz1234/article/details/43737455




Android Event Distribution learning app-Photo carousel implementation

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.