Canvas在android 4.2.2上不清楚

时间:2015-01-05 11:04:05

标签: android canvas fade

我有一个自定义视图,在其中,我有一个视图上下滑动,当幻灯片我画这样的淡化背景:

 @Override
        protected void dispatchDraw(Canvas canvas) {
            canvas.drawARGB(alpha, 0, 0, 0);
             super.dispatchDraw(canvas);
         }

它与我的设备android 4.2.2一起使用但是使用android 4.4.2或谷歌nexus一个android 2.3.7,它是如此糟糕。 下面的2张图片显示在我的设备4.2.2中(滑入和滑出):

http://imgur.com/p6i9gw8

http://imgur.com/9Sdzy7v

和下面的2张图片显示在google nexus one android 2.3.7(滑入并滑出):

http://imgur.com/ZGKiRJi

http://imgur.com/Uf3vRdb

正如你所看到的,在2张图像中,淡入淡出是正确的,而在另一张图片中看起来很糟糕。 此视图的完整代码是:

public class SlideView extends ViewGroup {
    private static final int MAXDURATIONSLIDE = 500;
    protected View content;
    private int childHeight;
    private int childOffset;
    private int childWidth;
    private int alpha;
    private Fillinger fillinger;

    public ISlide getSlideChangeListener() {
        return slideListener;
    }

    public void setSlideChangeListener(ISlide slideChangeListener) {
        this.slideListener = slideChangeListener;
    }

    private ISlide slideListener;

    public SlideView(Context context) {
        super(context);
        init(context, null);
    }

    private void init(Context context, AttributeSet attrs) {
        if(attrs!=null){
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SlideView);
            try {
                int contentLayoutId = a.getResourceId(R.styleable.SlideView_slideView, 0);
                DebugLog.d(contentLayoutId);
                setContent(contentLayoutId);
            } finally {
                a.recycle();
            }
        }
        fillinger = new Fillinger(context);
    }

    public SlideView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context,attrs);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int width = r - l;
        final int height = b - t;
        DebugLog.d("width "+width+" height "+height);
        childOffset = height;
        content.layout(0, childOffset, childWidth, childOffset + childHeight);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = getDefaultSize(0, widthMeasureSpec);
        int height = getDefaultSize(0, heightMeasureSpec);
        measureChild(content, widthMeasureSpec, height);
        childHeight = content.getMeasuredHeight();
        childWidth = content.getMeasuredWidth();
        DebugLog.d("childWidth "+childWidth+" childHeight "+childHeight);
        setMeasuredDimension(width, height);
    }

    public void setContent(int resId) {
        View view = LayoutInflater.from(getContext()).inflate(resId, this,false);
        setContent(view);
    }

    public void setContent(View v) {
        if (content != null)
            removeView(content);
        content = v;
        addView(content);
    }

    private void moveViewByY(int diffY) {
        childOffset += diffY;
        alpha = (int) (Math.abs((getHeight()-childOffset)*255/(childHeight))*0.5f);
        content.layout(0, childOffset, childWidth, childOffset + childHeight);
        if(slideListener!=null){
            slideListener.onSlide(childOffset,childHeight);
        }
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        canvas.drawARGB(alpha, 0, 0, 0);
        super.dispatchDraw(canvas);

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if(isIn()&&touchOutSide(event)){
            toogle();
            return true;
        }
        return false;
    }

    private boolean touchOutSide(MotionEvent event) {
        final float x = event.getX();
        final float y = event.getY();
        if(x<content.getLeft()||x>content.getRight()||y<content.getTop()||y>content.getBottom()){
            return true;
        }
        return false;
    }

    public void hide(){
        if(isIn()){
            fillinger.startScroll(content.getTop(),getHeight(),childHeight,MAXDURATIONSLIDE);
        }
    }

    public void show(){
        if(!isIn()){
            fillinger.startScroll(content.getTop(),getHeight()-childHeight,childHeight,MAXDURATIONSLIDE);
        }
    }

    public void toogle(){
        fillinger.cancleAnimation();

        if(isIn()){
            hide();
        }else{
            show();
        }
    }

    public boolean isIn(){
        return content.getTop()<getHeight();
    }

    public class Fillinger implements Runnable {
        private static final String tag = "Fillinger";
        private Scroller mScroller;
        private int lastY;
        private boolean more;
        private int currentY;
        private int diffY;

        public Fillinger(Context context) {
            mScroller = new Scroller(context);
        }

        public void startScroll(float startY, float endY, float maxDistance, int maxDurationForFling) {
            int duration = (int) Math.min(Math.abs((endY - startY)) / maxDistance * maxDurationForFling, maxDurationForFling);
            lastY = (int) startY;
            if(slideListener!=null){
                slideListener.onStartSlide();
            }
            mScroller.startScroll(0, (int) startY, 0, -(int) (endY - startY), duration);
            setDrawingCacheEnabled(true);
            post(this);
        }

        public void cancleAnimation(){
            removeCallbacks(this);
        }

        @Override
        public void run() {
            more = mScroller.computeScrollOffset();
            currentY = mScroller.getCurrY();
            diffY = lastY - currentY;
            moveViewByY(diffY);
            lastY = currentY;
            if (more) {
                post(this);
            }else{
                setDrawingCacheEnabled(false);
                if(slideListener!=null){
                    slideListener.onSlideFinish(isIn());
                }
            }
        }
    }
}

我错过了什么? 对不起,我的英语不好。 谢谢大家。

编辑:最后,我必须在moveViewByY方法中调用invalidate,如下所示

private void moveViewByY(int diffY) {
        childOffset += diffY;
        alpha = (int) (Math.abs((getHeight()-childOffset)*255/(childHeight))*0.5f);
        content.layout(0, childOffset, childWidth, childOffset + childHeight);
        invalidate();
        if(slideListener!=null){
            slideListener.onSlide(childOffset,childHeight);
        }
    }

我不知道为什么,可能无效,查看树重绘和旧画布清除。 期待最佳解决方案,谢谢。

0 个答案:

没有答案