Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 仿網易一元奪寶客戶端下拉加載動畫實現(一)

Android 仿網易一元奪寶客戶端下拉加載動畫實現(一)

編輯:關於Android編程

上上周寫的一個demo,仿照網易一元奪寶的下拉刷新效果。

原效果是(第一部分)一個小太陽拉下來,然後松開回彈上去,

(第二部分)再掉下來一個硬幣進行中軸旋轉。

本文實現的效果的是第一部分的,效果演示圖如下:

\

Gif圖看起來比較卡頓。。。其實真機演示效果還是很流暢的。

下面分析實現過程

當時因為時間有限沒有寫在下拉刷新的組件中,也沒有封裝成一個單獨的組件,只是在主布局後面寫了一個View然後實現相應的操作,進行封裝並不難,這裡就不花時間BB了,下面是布局文件:

 



    

    

    

        
        

        

        
    


布局文件預覽:

 

\

因為設置了透明,所以這裡在沒有item的情況下是能看到後面的布局的。

代碼實現

通過下拉刷新類NGReFlashListView進行事件判斷,然後通過回調把相應的事件傳遞給NGImageView中改變視圖顯示。

下面是兩個類的源代碼:

NGReFlashListView類:

 

package location.haidian.com.wypulltoreflush.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;

import location.haidian.com.wypulltoreflush.R;


public class NGReFlashListView extends ListView implements OnScrollListener {
    private View header;
    private int headerHeight;
    private int firstVisibleItem;
    private int scrollState;
    private final int NONE = 0;
    private final int PULL = 1;
    private final int RELESE = 2;
    private final int REFLASHING = 3;

    public NGReFlashListView(Context context) {
        super(context);
        initView(context);
    }

    public NGReFlashListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }

    public NGReFlashListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initView(context);
    }

    /**
     * @param context
     */
    private void initView(Context context) {
        LayoutInflater inflater = LayoutInflater.from(context);
        header = inflater.inflate(R.layout.layout_heard, null);
        measureView(header);
        headerHeight = header.getMeasuredHeight();
        topPadding(-headerHeight);
        this.addHeaderView(header);
        this.setOnScrollListener(this);
    }

    /**
     * @param view
     */
    private void measureView(View view) {
        ViewGroup.LayoutParams p = view.getLayoutParams();
        if (p == null) {
            p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
        }
        int width = ViewGroup.getChildMeasureSpec(0, 0, p.width);
        int height;
        int tempHeight = p.height;
        if (tempHeight > 0) {
            height = MeasureSpec.makeMeasureSpec(tempHeight,
                    MeasureSpec.EXACTLY);
        } else {
            height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        }
        view.measure(width, height);
    }

    /**
     * @param topPadding
     */
    private void topPadding(int topPadding) {
        header.setPadding(header.getPaddingLeft(), topPadding,
                header.getPaddingRight(), header.getPaddingBottom());
        header.invalidate();
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
                         int visibleItemCount, int totalItemCount) {
        this.firstVisibleItem = firstVisibleItem;
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        this.scrollState = scrollState;
    }

    boolean isRemark;//初始化標識
    int startY;
    int state;

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (firstVisibleItem == 0) {
                    onRlvScrollListener.onScrollYChangged(0, 0);
                    isRemark = true;
                    startY = (int) ev.getY();
                }
                break;

            case MotionEvent.ACTION_MOVE:
                onMove(ev);
                break;
            case MotionEvent.ACTION_UP:
                if (state == RELESE) {
                    onRlvScrollListener.onScrollYChangged(0, 3);
                    state = REFLASHING;
                    reflashViewByState();
                    //iReflashListener.onReflash();
                } else if (state == PULL) {
                    state = NONE;
                    onRlvScrollListener.onScrollYChangged(0, 0);
                    isRemark = false;
                    reflashViewByState();
                }
                break;
        }
        return super.onTouchEvent(ev);
    }

    int space;  //間距
    int topPadding;     //headview距離頂端的距離,初始-200

    /**
     * @param ev
     */
    private void onMove(MotionEvent ev) {
        if (!isRemark) {
            return;
        }
        int tempY = (int) ev.getY();
        space = tempY - startY;
        if (space >= 230) {
            space = 230;
        }
        topPadding = space - headerHeight;


        onRlvScrollListener.onScrollYChangged(space, state);


        switch (state) {
            case NONE:
                if (space > 0) {
                    state = PULL;
                    reflashViewByState();
                }
                break;

            case PULL:
                topPadding(topPadding);
                if (space == headerHeight + 30
                        && scrollState == SCROLL_STATE_TOUCH_SCROLL) {
                    state = RELESE;
                    reflashViewByState();
                }

                break;
            case RELESE:
                if (space < headerHeight + 30) {
                    state = PULL;
                    reflashViewByState();
                } else if (space <= 0) {
                    state = NONE;
                    isRemark = false;
                    reflashViewByState();
                }
                break;
        }
    }

    /**
     * 控制下拉刷新的圖像文字顯示
     */
    private void reflashViewByState() {
        switch (state) {
            case NONE:
                //緩慢滑上去
                topPadding(-headerHeight);
                break;
            case PULL:
                break;
            case RELESE:
                break;
            case REFLASHING:
                break;
        }
    }


    /**
     * 刷新完成
     */
    public void reflashComplete() {
        state = NONE;
        onRlvScrollListener.onScrollYChangged(0, state);
        isRemark = false;
        reflashViewByState();
    }

    //繪制背景的接口
    public interface OnRlvScrollListener {
        void onScrollYChangged(int Y, int state);
    }

    private OnRlvScrollListener onRlvScrollListener;

    public void setOnRlvScrollListener(OnRlvScrollListener onRlvScrollListener) {
        this.onRlvScrollListener = onRlvScrollListener;
    }


}

NGImgView.java

 

實現比較簡單,根據傳來的回調狀態改變進行小太陽和兩只球球手以及手臂的繪制就可以了。

 

package location.haidian.com.wypulltoreflush.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;
import location.haidian.com.wypulltoreflush.R;

/**
 * Created by nangua on 2016/8/28.
 */
public class NGImgView extends ImageView implements NGReFlashListView.OnRlvScrollListener {
    private float scale;
    private final int NONE = 0;
    private final int PULL = 1;
    private final int RELESE = 2;
    private final int REFLASHING = 3;
    public int state = 0;
    private float WITH;     //屏幕總寬
    private float scrollY;
    private Bitmap sun0;
    public float time = 0;

    public NGImgView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    private void initView() {
        sun0 = ((BitmapDrawable) getResources().getDrawable(R.drawable.ic_sun0)).getBitmap();
        scale = this.getResources().getDisplayMetrics().density;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Paint paint = new Paint();
        paint.setAntiAlias(true);//抗鋸齒
        paint.setColor(Color.parseColor("#C4885A"));
        Log.d("xiaojingyu","State:" + state);
        if (state!=3) {
            time = 0; //重置時間
            //畫兩只球球手
            canvas.drawCircle(WITH / 2 - 40 * scale, 55 * scale, 5 * scale, paint);
            canvas.drawCircle(WITH / 2 + 40 * scale, 55 * scale, 5 * scale, paint);
            //畫笑臉
            canvas.drawBitmap(sun0,
                    null,
                    new RectF(WITH / 2 - 50,
                            55 * scale + scrollY - (scrollY / 230) * 50,
                            WITH / 2 + 50,
                            55 * scale + scrollY - (scrollY / 230) * 50 + 100),
                    null
            );
            //畫手臂
            paint.setStrokeWidth(1);
            canvas.drawLine(WITH / 2 - 40 * scale, 55 * scale,
                    WITH / 2 - 50, 55 * scale + scrollY,
                    paint
            );
            canvas.drawLine(WITH / 2 + 40 * scale, 55 * scale,
                    WITH / 2 + 50, 55 * scale + scrollY,
                    paint
            );
        } else if (state == 3) {
            //1秒鐘拉上去,2秒鐘旋轉
            //第一秒
            if (time < 30) {
                time += 1;
                //畫兩只球球手
                canvas.drawCircle(WITH / 2 - 40 * scale, 55 * scale, 5 * scale, paint);
                canvas.drawCircle(WITH / 2 + 40 * scale, 55 * scale, 5 * scale, paint);
                //畫笑臉
                canvas.drawBitmap(sun0,
                        null,
                        new RectF(WITH / 2 - 50,
                                55 * scale + 180 - (time / 30) * 230,
                                WITH / 2 + 50,
                                55 * scale + 280 - (time / 30) * 230),
                        null
                );
                //畫手臂
                paint.setStrokeWidth(1);
                canvas.drawLine(WITH / 2 - 40 * scale, 55 * scale,
                        WITH / 2 - 50,
                        55 * scale + 230 - (time / 30) * 230,
                        paint
                );
                canvas.drawLine(WITH / 2 + 40 * scale, 55 * scale,
                        WITH / 2 + 50,
                        55 * scale + 230 - (time / 30) * 230,
                        paint
                );
                postInvalidateDelayed(1);
            } else {
                if (!isBeginMainAnimation) {
                    isBeginMainAnimation = true;
                    iReflashListener.onReflash();
                }

            }
        }
        super.onDraw(canvas);


    }

    public static boolean isBeginMainAnimation = false;

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        WITH = this.getWidth();
    }

    @Override
    public void onScrollYChangged(int Y, int state) {
        this.state = state;
        switch (state) {
            case NONE:
                break;
            case PULL:
                //下拉
                scrollY = Y;
                break;
            case RELESE:
                break;
            case REFLASHING:
                break;
        }
    }

    private IReflashListener iReflashListener;  //回調接口

    public void setInterface(IReflashListener iReflashListener) {
        this.iReflashListener = iReflashListener;
    }

    /**
     * @author Administrator
     */
    public interface IReflashListener {
        void onReflash();
    }


}

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved