• <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 小果子 閱讀(688) 評論(0)  編輯 收藏 引用 所屬分類: Android & Ios
            久久人人爽人人人人爽AV| 久久93精品国产91久久综合| 无码人妻少妇久久中文字幕 | 欧美日韩精品久久久免费观看| 香蕉久久AⅤ一区二区三区| 久久久久久久免费视频| 久久久精品国产sm调教网站| 久久99精品久久久久久| 久久中文字幕视频、最近更新| 99久久国产宗和精品1上映| 青青青青久久精品国产| 亚洲午夜久久久久久噜噜噜| 久久精品国产亚洲沈樵| 亚洲欧美国产日韩综合久久 | 国产亚州精品女人久久久久久 | AV无码久久久久不卡蜜桃| 久久综合综合久久97色| 久久99国产精品久久99小说| 久久99久久99小草精品免视看| 国产免费久久精品99re丫y| 91精品国产91久久| 久久人爽人人爽人人片AV | 九九久久自然熟的香蕉图片| 久久婷婷五月综合成人D啪| 91精品观看91久久久久久| 久久亚洲美女精品国产精品| 午夜精品久久久久| 久久精品成人欧美大片| 国产亚洲婷婷香蕉久久精品| 亚洲va中文字幕无码久久不卡| 欧美成a人片免费看久久| 欧美亚洲国产精品久久蜜芽| 精品蜜臀久久久久99网站| 国产69精品久久久久APP下载| 久久精品99无色码中文字幕| 日本精品久久久中文字幕| 99久久这里只有精品| 久久久无码精品亚洲日韩按摩 | 97久久久久人妻精品专区| 色欲综合久久躁天天躁蜜桃| 国产激情久久久久久熟女老人|