Pull to achieve the head image amplification effect, to achieve similar QQ, Sina Personal Center Interface _ Personal Center page

Source: Internet
Author: User
Tags diff float max gety

Today to write this effect belongs to refresh class, more practical, like many popular apps are used in this effect, we are familiar with the QQ space, Weibo personal homepage and so on.

In fact, this idea is completely in accordance with the existing ideas in Android to achieve this effect.

1. Before you begin, please take a look at the implementation of the effect chart.


2. So let's analyze the principle of implementation together.

What is the principle of image amplification?
By changing the height of the parent control ImageView the picture display control, for example, the head View here is a framelayout;

Add the picture in the Framelayout again: AddView (ImageView);

Where ImageView has several attributes to pay special attention to, the ImageView type is intercepted from the middle

Setscaletype (ImageView.ScaleType.CENTER_CROP);
And the width height is set to match the parent control, so if you want the picture to have a magnifying effect, just set the height value in the Framelayout's layoutparams and change the height of the ImageView by changing the height value.

If you're a friend who knows a lot about gesture events, there's no difficulty in implementing this effect, and the only thing is to decide when to enlarge the picture and when to scroll listview.

3. The principle analysis is finished, then everybody looks down the code together:

/** * Created by Guaju on 16/09/17.
* * public class Pullzoomlistview extends ListView {* * * head view container/private framelayout mheadercontainer;/* head View picture/*
Private ImageView mheaderimg;
/* The height of the screen * * private int mscreenheight;

/* The width of the screen * * private int mscreenwidth;

private int mheaderheight;
/* Invalid point * * private static final int invalid_pointer =-1; /* Sliding Animation Execution Time * * private static final int min_settle_duration = 200; MS/* Defines a time interpolation that is defined according to the ViewPage control/private static final interpolator Sinterpolator = new Interpolator () {public fl
        Oat getinterpolation (float t) {t-= 1.0f;
    return T * t * t * t + 1.0f;

}
};
/* Record last finger touch point * * private float Mlastmotionx;

private float Mlastmotiony;
/* Current active point ID, valid point of id*/protected int mactivepointerid = Invalid_pointer;

/* Start sliding the logo distance * * private int mtouchslop;
* * Magnification of the multiple/private float mscale;

* * The previous magnification/private float mlastscale;
/* Maximum magnification/private final float Mmaxscale = 2.0f; /* Whether you need to prohibit ListView event Response * * Private Boolean Isneedcancelparent

* * This does not explain/private onscrolllistener mscrolllistener;

/* Drop-down Refresh threshold * * Private final float Refresh_scale = 1.20F;


/* Drop-down Refresh Monitor/private Onrefreshlistener Mrefreshlistener;
    Public Pullzoomlistview {Super (context);
Init (context);
    Public Pullzoomlistview (context, AttributeSet attrs) {Super (context, attrs);
Init (context); Pullzoomlistview (context, AttributeSet attrs, int defstyleattr) {Super (context, Attrs, defstyleattr
    );
Init (context); The private void init (context context) {/* * Here is a worthless value that can be ignored/final viewconfiguration configuration = Viewconfigura
    Tion.get (context);

    Mtouchslop = viewconfigurationcompat.getscaledpagingtouchslop (configuration);
    /* Create head View Container * * Mheadercontainer = new Framelayout (context);
    /* Get the pixel value of the screen * * displaymetrics metrics = new Displaymetrics ();
    (activity). Getwindowmanager (). Getdefaultdisplay (). Getmetrics (metrics);
Mscreenheight = Metrics.heightpixels;    Mscreenwidth = Metrics.widthpixels;
    /* Set the initial size of the head view * * mheaderheight = (int) (9 * 1.0f/16) * mscreenwidth);
    Layoutparams abslayoutparams = new Layoutparams (mscreenwidth, mheaderheight);
    Mheadercontainer.setlayoutparams (Abslayoutparams);
    /* Create picture display view*/mheaderimg = new ImageView (context); Framelayout.layoutparams imglayoutparams = new Framelayout.layoutparams (ViewGroup.LayoutParams.MATCH_PARENT,
    ViewGroup.LayoutParams.MATCH_PARENT);
    Mheaderimg.setscaletype (ImageView.ScaleType.CENTER_CROP);
    Mheaderimg.setlayoutparams (Imglayoutparams);

    Mheadercontainer.addview (MHEADERIMG);
    /* Add head view*/addheaderview (Mheadercontainer);

/* Set the Listening Event/Super.setonscrolllistener (New Internalscrollerlistener ()); /* * Handling event with/@Override public boolean ontouchevent (Motionevent ev) {final int action = Ev.getaction () & Motionev

    Entcompat.action_mask; Switch (action) {case Motionevent.action_down:/* Calculation x,y The distance */INT index = MOTIONEVENTCOMPAT.GETACTIONINDEX (EV);
            Mactivepointerid = Motioneventcompat.getpointerid (EV, index);
            if (Mactivepointerid = = invalid_pointer) break;
            Mlastmotionx = motioneventcompat.getx (EV, index);
            Mlastmotiony = motioneventcompat.gety (EV, index);
            End animation, currently does not do processing, can ignore abortanimation ();
            /* Calculate the proportion of the time to shrink/Mlastscale = (This.mHeaderContainer.getBottom ()/this.mheaderheight);
            /* When pressed, set this flag to be valid/isneedcancelparent = true;
        Break
            Case MotionEvent.ACTION_MOVE:int Indexmove = motioneventcompat.getactionindex (EV);

            Mactivepointerid = Motioneventcompat.getpointerid (EV, indexmove);
                if (Mactivepointerid = = Invalid_pointer) {/* Here is the equivalent of letting go */finishpull ();
            Isneedcancelparent = true; else {/* This is a key value that is judged by this valueWhether the need to enlarge the picture/if (Mheadercontainer.getbottom () >= mheaderheight) {VIEWGROUP.LAYOUTPA
                    Rams params = This.mheadercontainer. Getlayoutparams ();
                    Final float y = motioneventcompat.gety (ev, indexmove);
                    float dy = y-mlastmotiony;  float F = ((Y-this.mlastmotiony + This.mheadercontainer. Getbottom ())/This.mheaderheight-
                    This.mlastscale)/2.0F + This.mlastscale; if ((This.mlastscale <= 1.0D) && (F <= this.mlastscale)) {params.height = This.mhea
                        Derheight;
                        This.mheadercontainer. Setlayoutparams (params);
                    return super.ontouchevent (EV);
             /* Here Set the compactness * * dy = dy * 0.5f * (mheaderheight * 1.0f/params.height);       Mlastscale = (dy + params.height) * 1.0f/mheaderheight;
Mscale = Clamp (Mlastscale, 1.0f, Mmaxscale);

                    LOG.V ("Zgy", "=======mscale=====" + mlastscale+ ", F =" +f);
                    Params.height = (int) (mheaderheight * mscale);
                    Mheadercontainer.setlayoutparams (params);
                    Mlastmotiony = y;  /* Here, if the picture is magnified, then the other event response of shielding ListView/if (isneedcancelparent) {isneedcancelparent
                        = false;
                        Motionevent motionevent = motionevent.obtain (EV);
                        Motionevent.setaction (Motionevent.action_cancel);
                    Super.ontouchevent (motionevent);
                return true;

            } mlastmotiony = motioneventcompat.gety (EV, indexmove);
        } break;

           Case MOTIONEVENT.ACTION_UP:/* End Event response, do the corresponding operation * * Finishpull (); Break Case MOTIONEVENT.ACTION_POINTER_UP:/* Here need to pay attention to, multi-point processing, here the treatment is: if there are two fingers pressed, lift the back of the finger, then do not do processing * If you lift the first press
            Fingers, the image effect is restored.
            * * */int pointupindex = Motioneventcompat.getactionindex (EV);
            int pointid = Motioneventcompat.getpointerid (EV, POINTUPINDEX); if (Pointid = = Mactivepointerid) {/* Let go execution end drag/////End Event response, do the appropriate operation * * finish
            Pull ();

    } break;
return super.ontouchevent (EV);

@Override public void Setonscrolllistener (Onscrolllistener l) {mscrolllistener = l;} 
    private void Abortanimation () {/* Nothing done, not done for the time being * *} private void Finishpull () {mactivepointerid = Invalid_pointer; /* This is a threshold, if set, it means that the picture has been enlarged, the finger to lift the need to restore the image */if (Mheadercontainer.getbottom () > Mheaderheight) {//LOG.V ("Zgy", " 
===super====ontouchevent======== "); /Here is the drop down refresh threshold, and when reached, indicates a need to refresh and can add refresh animations/if (Mscale > Refresh_scale) {if Mrefreshlistener!= null) {Mrefreshlistener.onrefresh (); 
}/Picture Restoration animation/pullbackanimation (); }/** * This is the knowledge of property animation, do not understand can go to see the knowledge of attribute animation/private void Pullbackanimation () {Valueanimator pullback = Valueanimator.of
    Float (Mscale, 1.0f);
    Pullback.setinterpolator (Sinterpolator); Pullback.addupdatelistener (New Valueanimator.animatorupdatelistener () {@Override public void Onanimationu
            Pdate (Valueanimator animation) {Float value = (float) animation.getanimatedvalue ();
            Layoutparams params = (layoutparams) mheadercontainer.getlayoutparams ();
            Params.height = (int) (mheaderheight * value);
        Mheadercontainer.setlayoutparams (params);
    }
    });
    Pullback.setduration ((Long) (Min_settle_duration*mscale));

Pullback.start (); /** * Retrieves the index of the point via event and Point ID * @param EV * @param ID * @return/private int getpointerindex (motionevent ev, int
    ID) {int activepointerindex = Motioneventcompat.findpointerindex (ev, ID); If (Activepointerindex = = 1) Mactivepointerid = Invalid_pointer;
return activepointerindex;

public void Setonrefreshlistener (Onrefreshlistener l) {mrefreshlistener = l;}


Public ImageView Getheaderimageview () {return this.mheaderimg;}

Private float Clamp (float value, float min, float max) {return math.min (Math.max (value, min), max);} Private class Internalscrollerlistener implements onscrolllistener{@Override public void onscrollstatechanged (Abs ListView view, int scrollstate) {if (Mscrolllistener!= null) {mscrolllistener.onscrollstatechanged (
        View,scrollstate); @Override public void Onscroll (Abslistview view, int firstvisibleitem, int visibleitemcount, int totalite
        Mcount) {Float diff = mheaderheight-mheadercontainer.getbottom ();
            if (diff > 0.0F) && (diff < mheaderheight)) {int i = (int) (0.3D * diff);
        Mheaderimg.scrollto (0,-i);else if (mheaderimg.getscrolly ()!= 0) {mheaderimg.scrollto (0, 0);

        } log.v ("Zgy", "=========height===" +getscrolledy ()); if (Mscrolllistener!= null) {Mscrolllistener.onscroll (view, Firstvisibleitem, VisibleItemCount, Totalitemcoun
        T);
    }} public int getscrolledy () {View c = getchildat (0);
    if (c = = null) {return 0;
    int firstvisibleposition = Getfirstvisibleposition ();

    int top = C.gettop ();
    int headerheight = 0;
    if (firstvisibleposition >= 1) {headerheight = Mheaderheight;
} return-top + firstvisibleposition * c.getheight () + headerheight;

public interface Onrefreshlistener {void Onrefresh ();} public void Computerefresh () {if (Mactivepointerid!= invalid_pointer) {}}}




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.