• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            xiaoguozi's Blog
            Pay it forword - 我并不覺的自豪,我所嘗試的事情都失敗了······習慣原本生活的人不容易改變,就算現狀很糟,他們也很難改變,在過程中,他們還是放棄了······他們一放棄,大家就都是輸家······讓愛傳出去,很困難,也無法預料,人們需要更細心的觀察別人,要隨時注意才能保護別人,因為他們未必知道自己要什么·····
            實現思路,剛開始的時候我是用ViewFlipper控件來做非常的簡單但是實現不了拖拽移動屏幕的效果,最終放棄決定自定義一個控件實現這樣效果。

            接下來我詳細的解說一下我開發時寫的這個實驗demo,軟件中用的滑屏就是由這樣的代碼實現的。

                   首先新建一個控件類TouchPageView并且繼承自ViewGroup,左右滑動換屏我的實現是在TouchPageView添加3個子view 分別代表看不到的左邊屏幕、可以看到的中間屏幕、看不到的右邊屏幕,這樣在滑屏時候就可以通過不斷調整這3個view的位置實現連續不間斷滑屏換屏,下面 的實驗中我分別把3個view設置成紅色、綠色、黃色這樣切換的時候可以看到明顯效果,這3個view在TouchPageView的構造方法中調用 init方法進行初始化:

            private void init()
            {
            views= new ArrayList<LinearLayout>();
            view1=new LinearLayout(context);
            view1.setBackgroundColor(Color.YELLOW);
            this.addView(view1);
            TextView tv=new TextView(context);
            tv.setText("測試");
            view1.addView(tv);
            views.add(view1);


            view2=new LinearLayout(context);
            view2.setBackgroundColor(Color.RED);
            this.addView(view2);
            views.add(view2);

            view3=new LinearLayout(context);
            view3.setBackgroundColor(Color.GREEN);
            this.addView(view3);
            views.add(view3);

            final ViewConfiguration configuration = ViewConfiguration.get(getContext());
            mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
            }

                   接下來的實現是關鍵,重寫onLayout方法對3個view的顯示位置布局進行控制,通過下面的這個方法,把3個view進行水平一個跟著一個進行布局顯示。

            @Override
            protected void onLayout(boolean changed, int l, int t, int r, int b) {
            int childLeft = -1;
            final int count = views.size();
            //水平從左到右放置
            for (int i = 0; i < count; i++) {

            final View child =views.get(i);
            if (child.getVisibility() != View.GONE) {
            final int childWidth = child.getMeasuredWidth();
            if(childLeft==-1)
            {
            childLeft=-childWidth;
            }
            child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight());
            childLeft += childWidth;
            }
            }

            }

                   3個view位置放置好之后,接下來的實現實現手指在屏幕拖拽滑動時讓3個view跟著手指的位置進行變化顯示,這個肯定是在onTouchEvent 方法中實現了,分別在MotionEvent.ACTION_DOWN、MotionEvent.ACTION_MOVE、 MotionEvent.ACTION_UP三個手指狀態中進行控制,在下面的實現中還采用了VelocityTracker的方法對手指的滑動速度進行 跟蹤,這樣根據滑動速度決定屏幕往哪個方向換屏,關鍵的代碼如下:

            @Override
            public boolean onTouchEvent(MotionEvent ev){

            if(!lock)
            {
            if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
            }
            mVelocityTracker.addMovement(ev);

            final int action = ev.getAction();
            final float x = ev.getX();
            final float y = ev.getY();

            switch (action) {
            case MotionEvent.ACTION_DOWN://按下去
            if(touchState==TOUCH_STATE_REST)

            {
            //記錄按下去的的x坐標
            lastMotionX = x;

            touchState=TOUCH_STATE_MOVING;

            isMoved=false;
            }

            break;
            case MotionEvent.ACTION_MOVE://拖動時
            if(touchState==TOUCH_STATE_MOVING)

            {
            float offsetX=x-lastMotionX;
            float offsetY=y-lastMotionY;

            if(isMoved)
            {
            lastMotionX=x;
            lastMotionY=y;

            final int count = views.size();
            //水平從左到右放置
            for (int i = 0; i < count; i++) {

            final View child =views.get(i);
            if (child.getVisibility() != View.GONE) {
            final int childWidth = child.getMeasuredWidth();
            int childLeft = child.getLeft()+(int)offsetX;
            child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight());
            childLeft += childWidth;
            }
            }
            }
            else if(Math.abs(offsetX)>TOUCH_SLOP||Math.abs(offsetY)>TOUCH_SLOP)
            {
            //移動超過閾值,則表示移動了
            isMoved=true;

            removeCallbacks(mLongPressRunnable);
            }
            }

            break;
            case MotionEvent.ACTION_UP://放開時
            //釋放了
            removeCallbacks(mLongPressRunnable);


            if(isMoved)
            {
            if(touchState==TOUCH_STATE_MOVING)
            {
            touchState=TOUCH_STATE_SLOWING;
            int sign=0;
            final VelocityTracker velocityTracker = mVelocityTracker;
            //計算當前速度
            velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);

            //x方向的速度
            int velocityX = (int) velocityTracker.getXVelocity();

            if(velocityX > SNAP_VELOCITY)//足夠的能力向左
            {

            sign=1;
            Log.e("enough to move left", "true");
            }
            else if (velocityX < -SNAP_VELOCITY)//足夠的能力向右
            {

            sign=-1;
            Log.e("enough to move right", "right");
            }
            else
            {
            sign=0;
            }
            moveToFitView(sign);
            if (mVelocityTracker != null) {
            mVelocityTracker.recycle();
            mVelocityTracker = null;
            }

            }
            }


            break;
            }
            }
            return true;
            }

                   完成手指滑的功能后,最后在手指離開屏幕的時候,讓3個view滑動到合適的位置,保證當前屏幕只能看到一個完整的view另外2個view不可見,并 且在滑動的過程中為了達到比較自然的效果,采用減速滑動的實現,這里是用了Handler進行間隔的減速移動效果,這樣滑動起來比較舒服,其實最好的效果 應該加入阻尼效果,就是讓view一定程度的沖過屏幕邊界然后在回彈,經過幾次這樣的緩減至速度為零然后最終停止,這個可以由各位自己去實現,并不難寫。

            int offset=0;
            private void moveToFitView(int sign)
            {
            boolean b=swapView(sign);
            if(true)
            {
            View view1=views.get(1);
            int left=view1.getLeft();
            //int offset=0;
            if(left!=0)

            {
            offset=-1*left;
            }

            moveView();
            }
            }

            FlipAnimationHandler mAnimationHandler;
            int ovv=40;
            private void moveView()
            {
            final int count = views.size();

            if(offset!=0)
            {
            int ov=0;
            if(offset>0)
            {
            ov=ovv;
            }
            else
            {
            ov=-1*ovv;
            }
            ovv=ovv-3;
            if(ovv<1)
            {
            ovv=3;
            }
            if(Math.abs(offset)<Math.abs(ov))
            {
            ov=offset;
            offset=0;

            }
            else
            {
            offset=offset-ov;
            }

            //水平從左到右放置
            for (int i = 0; i < count; i++) {

            final View child =views.get(i);
            final int childWidth = child.getMeasuredWidth();
            int childLeft = child.getLeft()+ov;
            child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight());
            childLeft += childWidth;
            }

            if(mAnimationHandler==null)
            {
            mAnimationHandler = new FlipAnimationHandler();
            }
            mAnimationHandler.sleep(1);
            }
            else
            {
            ovv=40;
            touchState=TOUCH_STATE_REST;
            }
            }

            class FlipAnimationHandler extends Handler {
            @Override
            public void handleMessage(Message msg) {
            TouchPageView.this.moveView();
            }

            public void sleep(long millis) {
            this.removeMessages(0);
            sendMessageDelayed(obtainMessage(0), millis);
            }
            }

            整個自定義控件核心的思路和代碼就上面這些了,實現效果請參看我的微讀效果。

            完整的代碼:

             

            package xx.weidu;
             
            import java.util.ArrayList;
            import java.util.List;
             
            import android.content.Context;
            import android.graphics.Canvas;
            import android.graphics.Color;
            import android.os.Handler;
            import android.os.Message;
            import android.util.Log;
            import android.view.MotionEvent;
            import android.view.VelocityTracker;
            import android.view.View;
            import android.view.ViewConfiguration;
            import android.view.ViewGroup;
            import android.widget.LinearLayout;
            import android.widget.TextView;
             
            public class TouchPageView extends ViewGroup{
             
                private LinearLayout view1;
                private LinearLayout view2;
                private LinearLayout view3;
                 
             
                //速度跟蹤
                private VelocityTracker mVelocityTracker;
                private int mMaximumVelocity;
                 
                //手勢臨界速度,當速度超過這個時切換到下一屏
                private static final int SNAP_VELOCITY = 100;
                 
                //停止狀態
                private final static int TOUCH_STATE_REST = 0;
                //滾動狀態
                private final static int TOUCH_STATE_MOVING = 1;
                //減速停止狀態
                private final static int TOUCH_STATE_SLOWING = 2;
                 
                //當前觸摸狀態
                private int touchState = TOUCH_STATE_REST;
                 
                private boolean lock=false;
                 
                private float lastMotionX;
                private float lastMotionY;
                 
                private Context context;
                private List<LinearLayout> views;
                //是否移動了
                private boolean isMoved;
                //長按的runnable
                private Runnable mLongPressRunnable;
                //移動的閾值
                private static final int TOUCH_SLOP=10;
                 
                public int width;
                 
                public int height;
                 
                public TouchPageView(Context context) {
                    super(context);
                    this.context=context;
                    init();
                }
                 
                private void init()
                {
                    views= new ArrayList<LinearLayout>();
                    view1=new LinearLayout(context);
                    view1.setBackgroundColor(Color.YELLOW);
                    this.addView(view1);
                    TextView tv=new TextView(context);
                    tv.setText("測試");
                    view1.addView(tv);
                    views.add(view1);
                     
                     
                    view2=new LinearLayout(context);
                    view2.setBackgroundColor(Color.RED);
                    this.addView(view2);
                    views.add(view2);
                     
                    view3=new LinearLayout(context);
                    view3.setBackgroundColor(Color.GREEN);
                    this.addView(view3);
                    views.add(view3);
                     
                    final ViewConfiguration configuration = ViewConfiguration.get(getContext());
                    mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
                }
                 
                 
                @Override
                protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
                    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
                    final int count = views.size();
                    for (int i = 0; i < count; i++) {
                        final View child =views.get(i);
                        child.measure(widthMeasureSpec,heightMeasureSpec);
                    }
                     
                    int finalWidth, finalHeight;
                    finalWidth = measureWidth(widthMeasureSpec);
                    finalHeight = measureHeight(heightMeasureSpec);
             
                    this.width=finalWidth;
                    this.height=finalHeight;
             
                }
                 
                private int measureWidth(int measureSpec) {
                    int result = 0;
                    int specMode = MeasureSpec.getMode(measureSpec);
                    int specSize = MeasureSpec.getSize(measureSpec);
             
                    if (specMode == MeasureSpec.EXACTLY) {
                        result = specSize;
                    } else {
                        result = specSize;
                    }
             
                    return result;
                }
                 
                private int measureHeight(int measureSpec) {
                    int result = 0;
                    int specMode = MeasureSpec.getMode(measureSpec);
                    int specSize = MeasureSpec.getSize(measureSpec);
             
                    if (specMode == MeasureSpec.EXACTLY) {
                        result = specSize;
                    } else {
                        result = specSize;
                    }
                    return result;
                }
             
                @Override
                protected void onLayout(boolean changed, int l, int t, int r, int b) {
                    int childLeft = -1;
                    final int count = views.size();
                    //水平從左到右放置
                    for (int i = 0; i < count; i++) {
                        final View child =views.get(i);
                        if (child.getVisibility() != View.GONE) {
                            final int childWidth = child.getMeasuredWidth();
                            if(childLeft==-1)
                            {
                                childLeft=-childWidth;
                            }
                            child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight());
                            childLeft += childWidth;
                        }
                    }
                     
                }
                 
                //繪制子元素
                @Override
                protected void onDraw(Canvas canvas) {
                    //水平從左到右放置
                    int count = views.size();
                    for (int i = 0; i < count; i++) {
                        View child =views.get(i);
                        drawChild(canvas, child, getDrawingTime());
                    }
                }
             
                @Override
                public boolean onTouchEvent(MotionEvent ev){
                     
                    if(!lock)
                    {
                        if (mVelocityTracker == null) {
                            mVelocityTracker = VelocityTracker.obtain();
                        }
                        mVelocityTracker.addMovement(ev);
                         
                        final int action = ev.getAction();
                        final float x = ev.getX();
                        final float y = ev.getY();
                         
                        switch (action) {
                        case MotionEvent.ACTION_DOWN://按下去
                            if(touchState==TOUCH_STATE_REST)
                            {
                                //記錄按下去的的x坐標
                                lastMotionX = x;
                                touchState=TOUCH_STATE_MOVING;
                                 
                                isMoved=false;
                            }
                             
                            break;
                        case MotionEvent.ACTION_MOVE://拖動時
                            if(touchState==TOUCH_STATE_MOVING)
                            {
                                float offsetX=x-lastMotionX;
                                float offsetY=y-lastMotionY;
                                 
                                if(isMoved)
                                {
                                    lastMotionX=x;
                                    lastMotionY=y;
             
                                    final int count = views.size();
                                    //水平從左到右放置
                                    for (int i = 0; i < count; i++) {
                                        final View child =views.get(i);
                                        if (child.getVisibility() != View.GONE) {
                                            final int childWidth = child.getMeasuredWidth();
                                            int childLeft = child.getLeft()+(int)offsetX;
                                            child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight());
                                            childLeft += childWidth;
                                        }
                                    }
                                }
                                else if(Math.abs(offsetX)>TOUCH_SLOP||Math.abs(offsetY)>TOUCH_SLOP)
                                {
                                    //移動超過閾值,則表示移動了
                                    isMoved=true;
                                    removeCallbacks(mLongPressRunnable);
                                }
                            }
                             
                            break;
                        case MotionEvent.ACTION_UP://放開時
                            //釋放了
                            removeCallbacks(mLongPressRunnable);
                             
                            if(isMoved)
                            {
                                if(touchState==TOUCH_STATE_MOVING)
                                {
                                    touchState=TOUCH_STATE_SLOWING;
                                    int sign=0;
                                    final VelocityTracker velocityTracker = mVelocityTracker;
                                    //計算當前速度
                                    velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
                                    //x方向的速度
                                    int velocityX = (int) velocityTracker.getXVelocity();
                                    if(velocityX > SNAP_VELOCITY)//足夠的能力向左
                                    {
                                        sign=1;
                                        Log.e("enough to move left", "true");
                                    }
                                    else if (velocityX < -SNAP_VELOCITY)//足夠的能力向右
                                    {
                                        sign=-1;
                                        Log.e("enough to move right", "right");
                                    }
                                    else
                                    {
                                        sign=0;
                                    }
                                    moveToFitView(sign);
                                    if (mVelocityTracker != null) {
                                        mVelocityTracker.recycle();
                                        mVelocityTracker = null;
                                    }
                                     
                                }
                            }
                             
                             
                            break;
                        }
                    }
                    return true;
                }
                 
                int offset=0;
                private void moveToFitView(int sign)
                {
                    boolean b=swapView(sign);
                    if(true)
                    {
                        View view1=views.get(1);
                        int left=view1.getLeft();
                        //int offset=0;
                        if(left!=0)
                        {
                            offset=-1*left;
                        }
                         
                        moveView();
                    }
                }
                 
                FlipAnimationHandler mAnimationHandler;
                int ovv=40;
                private void moveView()
                {
                    final int count = views.size();
                     
                    if(offset!=0)
                    {
                        int ov=0;
                        if(offset>0)
                        {
                            ov=ovv;
                        }
                        else
                        {
                            ov=-1*ovv;
                        }
                        ovv=ovv-3;
                        if(ovv<1)
                        {
                            ovv=3;
                        }
                        if(Math.abs(offset)<Math.abs(ov))
                        {
                            ov=offset;
                            offset=0;
                             
                        }
                        else
                        {
                            offset=offset-ov;
                        }
                         
                        //水平從左到右放置
                        for (int i = 0; i < count; i++) {
                            final View child =views.get(i);
                            final int childWidth = child.getMeasuredWidth();
                            int childLeft = child.getLeft()+ov;
                            child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight());
                            childLeft += childWidth;
                        }
                         
                        if(mAnimationHandler==null)
                        {
                            mAnimationHandler = new FlipAnimationHandler();
                        }
                        mAnimationHandler.sleep(1);
                    }
                    else
                    {
                        ovv=40;
                        touchState=TOUCH_STATE_REST;
                    }
                }
                 
                class FlipAnimationHandler extends Handler {
                    @Override
                    public void handleMessage(Message msg) {
                        TouchPageView.this.moveView();
                    }
             
                    public void sleep(long millis) {
                        this.removeMessages(0);
                        sendMessageDelayed(obtainMessage(0), millis);
                    }
                }
                 
                private boolean swapView(int sign)
                {
                    boolean b=false;
                    if(sign==-1)//向左
                    {
                        View view0=views.get(0);
                        if(view0.getLeft()<=-1*view0.getMeasuredWidth())
                        {
                            swapViewIndex(sign);
                             
                            View view2=views.get(1);
                            View view3=views.get(2);
                            int childWidth=view2.getMeasuredWidth();
                            int childLeft=view2.getLeft()+childWidth;
                            view3.layout(childLeft, 0, childLeft + view3.getMeasuredWidth(), view3.getMeasuredHeight());
                            b=true;
                        }
                    }
                    else if(sign==1)//向右
                    {
                        View view3=views.get(2);
                        if(view3.getLeft()>view3.getMeasuredWidth())
                        {
                            swapViewIndex(sign);
                             
                            View view1=views.get(0);
                            View view2=views.get(1);
                            int childRight=view2.getLeft();
                            int childLeft=childRight-view1.getMeasuredWidth();
                            view1.layout(childLeft, 0, childRight, view1.getMeasuredHeight());
                            b=true;
                        }
                    }
                     
                    return b;
                }
                 
                private void swapViewIndex(int sign)
                {
                    if(sign==-1)//向左
                    {
                        LinearLayout v=views.remove(0);
                        views.add(v);
                    }
                    else if(sign==1)//向右
                    {
                        LinearLayout v=views.remove(views.size()-1);
                        views.add(0, v);
                    }
                }
            }
            posted on 2012-03-01 17:06 小果子 閱讀(685) 評論(0)  編輯 收藏 引用 所屬分類: Android & Ios
            欧美性大战久久久久久| 亚洲国产婷婷香蕉久久久久久| 久久综合伊人77777| 99久久免费国产精品| 精品永久久福利一区二区| 精品伊人久久大线蕉色首页| 久久久久av无码免费网| 成人午夜精品无码区久久| 久久福利资源国产精品999| 久久免费观看视频| 伊人久久五月天| 国产精品美女久久久久| 久久久久夜夜夜精品国产| 国产精品欧美久久久久无广告 | 久久人妻少妇嫩草AV无码专区| 亚洲精品无码久久久影院相关影片 | 国产国产成人精品久久| 久久不见久久见免费影院www日本| 久久99久久99小草精品免视看| 久久免费香蕉视频| 久久精品黄AA片一区二区三区| 久久精品天天中文字幕人妻| 国产精品成人无码久久久久久| 亚洲午夜无码久久久久小说| 777米奇久久最新地址| 无码国内精品久久综合88| 国产精品久久久久久吹潮| 99热成人精品免费久久| 久久中文骚妇内射| 久久久国产99久久国产一| 国产精品九九久久精品女同亚洲欧美日韩综合区 | 久久精品国产69国产精品亚洲| 欧美精品福利视频一区二区三区久久久精品| 久久久一本精品99久久精品88| 久久人人爽人爽人人爽av| 国产欧美久久久精品| 婷婷综合久久狠狠色99h| 99久久人妻无码精品系列| 人妻无码精品久久亚瑟影视| 久久精品国产一区| 国産精品久久久久久久|