Viewflow enhancement Onitemclick function and Viewflow abslistview source code Analysis

Source: Internet
Author: User
Tags gety

First look at the implementation effect:

Viewflow is an open source project that works well for horizontal swipe switching that is not sure about the item number. But the Viewflow downloaded from GitHub does not support the Onitemclick feature, and the touch event does not handle the click.
So how to support the Onitemclick function?

First, before the implementation, with three questions:
Serial Number problem
1 Does Viewflow need an Onitemclicklistener interface?
2 How does the ListView implement Onitemclick?
3 How is Onitemclick called?
1.1, Problem one

From the source code can be seen Viewflow is inherited extends Adapterview, and Adapterview is usually the ListView, GridView and other inherited and has been defined Onitemclicklistener.

1.2, question two

Analysis of the ListView source know its inheritance extends Abslistview, and Abslistview is inherited extends Adapterview. In the Abslistview is actually the realization of the Onitemclicklistener. Then the next step as long as the change, imitation Abslistview implementation Onitemclick can be.

1.3. Question Three

Analysis Abslistview source code, you can find a method Performitemclick method, the implementation of this method, naturally carried out to the Onitemclick, not much to say on the source to see:

/**     * Call the Onitemclicklistener, if it is defined.     *     * @param view the view within the adapterview that is clicked.     * @param position the position of the view in the adapter.     * @param ID of the row ID of the item that is clicked.     * @return True If there         was a assigned onitemclicklistener that were * called, FALSE otherwise is returned.     */Public    Boolean Performitemclick (view view, int position, long id) {        if (monitemclicklistener! = null) {            P Laysoundeffect (Soundeffectconstants.click);            if (view! = null) {                view.sendaccessibilityevent (accessibilityevent.type_view_clicked);            }            Monitemclicklistener.onitemclick (this, view, position, id);            return true;        }        return false;    }

So as long as we find a way to execute Performitemclick in Viewflow OK.

Second, Abslistview is how to execute Performitemclick?

The general use of Onitemclick is more important is the method into the postion, then how to get postion?

2.1, the acquisition of Postion

2.1.1 In the ontouchevent of Abslistview, in Motionevent.action_ Down time Evnet.getx and event.gety, get the x and Y coordinates, and then according to the Pointtoposition method to calculate the click item position subscript. The Intercept snippet code is as follows:

@Override Public    Boolean ontouchevent (motionevent ev) {        if (!isenabled ()) {            //A disabled view-is Clickab Le still consumes the touch            /events, it just doesn ' t respond to them.            Return isclickable () | | Islongclickable ();        }        ....        Switch (action & motionevent.action_mask) {case        motionevent.action_down: {            switch (mtouchmode) {            Case touch_mode_overfling: {                ...                break;            }            Default: {                Mactivepointerid = Ev.getpointerid (0);                Final int x = (int) ev.getx ();                Final int y = (int) ev.gety ();                int motionposition = pointtoposition (x, y);//Calculate down which item's postion}

The 2.1.2 Pointtoposition method is as follows:

/**     * Maps a point to a position in the list.     *     * @param x x in local coordinate     * @param y y in local coordinate     * @return The position of the item which C Ontains the specified point, or     *         {@link #INVALID_POSITION} If the point does not intersect an item.     *    /public int pointtoposition (int x, int y) {        Rect frame = mtouchframe;        if (frame = = null) {//Just to avoid repeating new rect             mtouchframe = new rect ();            frame = Mtouchframe;        }        Final int count = Getchildcount ();        for (int i = count-1; I >= 0; i--) {            final View child = Getchildat (i);            if (child.getvisibility () = = view.visible) {                child.gethitrect (frame);//Gets the child control's rectangle coordinate in the parent control's coordinate system                if ( Frame.contains (x, y)) {                    return mfirstposition + i;}}        }        return invalid_position;    }


2.2, the implementation of PerformClick

2.2.1 clicks are also handled in touch, so look directly at how the Ontouchevent is executed in the Click Association.

  Case MOTIONEVENT.ACTION_UP: {switch (mtouchmode) {case Touch_mode_down:case Touch_mo                de_tap:case touch_mode_done_waiting:final int motionposition = mmotionposition;                Final View child = Getchildat (motionposition-mfirstposition); ....//Constructs a performclick interior to perform a click event if (Mperformclick = = null) {MPERFORMC              lick = new PerformClick ();                    } final Abslistview.performclick PerformClick = Mperformclick;                    Performclick.mclickmotionposition = motionposition; Performclick.rememberwindowattachcount (), ..... if (Mtouchmode = = Touch_mode_down | | mtouchmode = = TOUCH_MODE_TAP) {..    .    Mlayoutmode = Layout_normal;            if (!mdatachanged && madapter.isenabled (motionposition)) {.... if (mtouchmodereset! = null) {        Removecallbacks (Mtouchmodereset); } mtouchmOdereset = new Runnable () {@Override public void run () {Mtouchmode = Touch_mode_res                T                Child.setpressed (FALSE);                Setpressed (FALSE);        if (!mdatachanged) {performclick.run ();//Direct execution of the Run Method}}};    Postdelayed (Mtouchmodereset, Viewconfiguration.getpressedstateduration ());        } else {mtouchmode = touch_mode_rest;    Updateselectorstate (); } return true; else if (!mdatachanged && madapter.isenabled (motionposition)) {Performclick.run ();//execute the Run method directly ...
2.2.2 and see how PerformClick is realized.

/** * A base class for runnables that would check that their view was still attached to * the original window as whe     n the Runnable was created. * */Private class Windowrunnnable {//is only used to determine if the window is the same when the click is currently going to be executed, is there a new window opened because of an exceptional situation private int Morigina        Lattachcount;        public void Rememberwindowattachcount () {moriginalattachcount = Getwindowattachcount (); } public boolean Samewindow () {return haswindowfocus () && getwindowattachcount () = = Moriginalat        Tachcount;        }} Private class PerformClick extends windowrunnnable implements Runnable {int mclickmotionposition; public void Run () {//The data have changed since we posted this action in the event queue,//Bai            L Out before bad things happen if (mdatachanged) return;            Final ListAdapter adapter = Madapter;            Final int motionposition = mclickmotionposition; if (adapter! = NULL && mitemcount > 0 && motionposition! = invalid_position && mot Ionposition < Adapter.getcount () && Samewindow ()) {final View view = Getchildat (motionposition                -Mfirstposition); If There is no view, something bad happened (the view scrolled off the//screen, etc.) and we should CA Ncel the Click if (view! = null) {//performitemclick is executed, so Abslistview implements Onitemclick per                Formitemclick (view, Motionposition, Adapter.getitemid (motionposition)); }            }        }    }

Iii. Viewflow Implementation of performitemclick?3.1, postion acquisition

Viewflow's postion is actually a bit different from Abslistview's postion, because Viewflow is horizontal and Abslistview is vertical. Item will not be in the same screen width, and using x and Y coordinates to traverse Childview's rectangular coordinate system does not apply. So how to get postion? Look at the source of Viewflow there is a viewswitchlistener,onswitched in the corresponding postion and view. Just see where onswitched is being called, and how postion and view are bin values.

private void postviewswitched (int direction) {if (direction = = 0) return;if (Direction > 0) {//to the Rightmcurrentada pterindex++;mcurrentbufferindex++, ...} else {//to the leftmcurrentadapterindex--;mcurrentbufferindex--; ...} ... if (mviewswitchlistener! = null) {//By initializing in constructor method Mloadedviews (list<view>), Mcurrentadapterindex the position position in the currently displayed adapter mviewswitchlistener.onswitched (Mloadedviews.get (mcurrentbufferindex ), Mcurrentadapterindex);} Logbuffer ();}

3.2, the implementation of PerformClick

The same is true with Abslistview's PerformClick execution, which is also done in 0nTouchEvent.

@Overridepublic boolean ontouchevent (motionevent ev) {... final int action = Ev.getaction (); final float x = Ev.getx ();//-- -------add start gets the y-coordinate final float y = ev.gety ();//---------Add Endswitch (action) {case motionevent.action_down:...//Rem Ember where the motion event Startedmlastmotionx = x;//---------Add start Mlastmotiony = y;//---------Add start Mtouchst ate = mscroller.isfinished ()? Touch_state_rest:touch_state_scrolling;misclick = true; Each down is the default is a click event, in the MOVE has an x-axis or y-axis offset when the cancellation is clickbreak;case MotionEvent.ACTION_MOVE:final int deltax = (int) ( Mlastmotionx-x); Boolean xmoved = Math.Abs (deltax) > mtouchslop;//---------Add start calculates the Y-shift offset to determine if the y-axis has moved and is down, is One click event float tempdeltax = Mlastmotionx-ev.getx (); Float Tempdeltay = Mlastmotiony-ev.gety (); Boolean isxmoved = Math.a BS (Tempdeltax) > Move_touchslop;boolean isymoved = Math.Abs (Tempdeltay) > Move_touchslop; Boolean tempismoved = isxmoved | | isymoved;  XY a bit offset is not considered a click event Misclick =!tempismoved; If the x and Y offsets are too small, theConsidered to be a click event//log.e ("------->", "Action_move tempdeltax:" +tempdeltax+ "Tempdeltay:" +tempdeltay+ "Mtouchslop:" + mtouchslop+ "isxmoved:" +isxmoved+ "isymoved:" +isymoved+ "Isclick:" +misclick);//---------add Start ... break;case motionevent.action_up:....//------------------If click is clicked, the tap is executed. Here The Imitation Abslistview uses PerformClick//log.e ("------->", "action_up Isclick:" +misclick); if (Misclick) {if (Mperformclick = = null) {Mperformclick = new PerformClick ();} Final Viewflow.performclick PerformClick = Mperformclick;performclick.mclickmotionposition = MCurrentAdapterIndex; Performclick.rememberwindowattachcount (); Record the number of connection windows when clicked Performclick.run ();} ------------------..... break, ...} return true;}
The implementation of PerformClick is as follows:

/** * A base class for runnables that would check that their view was still attached to * the original window as whe     n the Runnable was created.        * */Private class Windowrunnnable {private int moriginalattachcount;  public void Rememberwindowattachcount () {moriginalattachcount = Getwindowattachcount ();//getwindowattachcount            Gets the number of times that the control is bound to the window} public boolean Samewindow () {//To determine whether the same window is the same, the interface Attachwindowcount will be +1 when the exception occurs, then it is not the same window at this time.        Return Haswindowfocus () && getwindowattachcount () = = Moriginalattachcount;        }} Private class PerformClick extends windowrunnnable implements Runnable {int mclickmotionposition; public void Run () {//The data have changed since we posted this action in the event queue,//Bai            L Out before bad things happen//if (mdatachanged) return;            Final Adapter Adapter = Madapter; Final int motionposition = MclickmotionpositION;IF (Adapter! = NULL && madapter.getcount () > 0 && motionposition! = Invalid_posi tion && motionposition < Adapter.getcount () && Samewindow ()) {//fina L View view = Getchildat (motionposition-mfirstposition); Mfirstposition does not care about final view view = Mloadedviews.get (Mcurrentbufferindex);                Position and view for reference onswitched method//If There is no view, something bad happened (the view scrolled off the screen, etc.) And we should cancel the click if (view! = null) {Performitemclick (view, motionposition                , Adapter.getitemid (motionposition)); }            }        }    }

At this point the Viewflow Onitemclick has been settled.

With the last Viewflow example demo
public class Circleviewflowexample extends activity {Private Viewflow viewflow;/** called when the activity is first creat Ed. */@Overridepublic void onCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Settitle ( R.string.circle_title); Setcontentview (r.layout.circle_layout); viewflow = (Viewflow) Findviewbyid (R.id.viewflow); Viewflow.setonitemclicklistener (New Onitemclicklistener () {@Overridepublic void Onitemclick (adapterview<?> Parent, View view,int position, long id) {Toast.maketext (Circleviewflowexample.this, " Circleviewflowexample clicked Position: "+position+" Picture ", 1). Show (); LOG.E ("-----", "circleviewflowexample clicked on Position:" +position+ "of the Picture");}); Viewflow.setadapter (New Imageadapter (this), 5); Circleflowindicator indic = (circleflowindicator) Findviewbyid (r.id.viewflowindic); Viewflow.setflowindicator (Indic ); LOG.E ("-----", "circleviewflowexample onCreate");} /* If your min SDK version is < 8 "need to trigger" the onconfigurationchanged in Viewflow manually, like thiS */@Overridepublic void onconfigurationchanged (Configuration newconfig) {super.onconfigurationchanged (newconfig); Viewflow.onconfigurationchanged (Newconfig);}}
Summarize

First spit Groove One or two sentence: Csdn Markdown When the editor feels good, but finally save the release, always problem. Not a timeout, or a service exception, can not be released. Saved in the draft box can also be previewed normally, just can't publish normally. Helpless had to turn into the normal mode, the code is a piece of paste in. Depressed....


Viewflow on GitHub:

Https://github.com/pakerfeldt/android-viewflow

Full Source demo Download (support Onitemclick's Viewflow)

http://download.csdn.net/detail/chenshufei2/9003119




Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Viewflow enhancement Onitemclick function and Viewflow abslistview source code Analysis

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.