美文网首页
移动的小船

移动的小船

作者: 菜鸟何时起飞 | 来源:发表于2020-04-19 18:39 被阅读0次
    列表.gif
    public class PathView extends View {
        public static final String TAG = "PathView";
    
        //取值范围0-100
        private float animationProgress = 0;
        //取值范围100-400 每秒钟动画改变量
        private float animationSpeed = 20;
    
        private long lastTime = System.currentTimeMillis();
        @SuppressLint("HandlerLeak")
        private Handler mHandler = new Handler() {
            @Override
            public void handleMessage(@NonNull Message msg) {
                super.handleMessage(msg);
                long currentTimeMillis = System.currentTimeMillis();
                int dtime = (int) (currentTimeMillis - lastTime);
                animationProgress += dtime * animationSpeed / 1000;
    //            Log.e(TAG, "handleMessage: dtime " + dtime);
    //            Log.e(TAG, "handleMessage: animationProgress " + animationProgress);
                animationProgress = animationProgress % 100;
                lastTime = currentTimeMillis;
                invalidate();
            }
        };
    
        private Path mPath;
        private Paint mPaint;
        private int mProgress = -1;
        private Bitmap mShipBitmap;
        private Bitmap mQuantBitmap;
        private Bitmap mPeopleBitmap;
        private Rect mShipRect;
        private Rect mPeopleRect;
        private float[] pos = new float[2];
        private float[] tan = new float[2];
        private PathMeasure mPathMeasure;
        private float mLength;
        private float mMax = 100f;
    
        public PathView(Context context) {
            this(context, null);
        }
    
        public PathView(Context context, @Nullable AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public PathView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initPaint();
            initShip();
        }
    
        private void initShip() {
            mShipBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.rowing_01_a);
            mQuantBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.rowing_02);
            mPeopleBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.rowing_04);
            mShipRect = getBitmapRect(mShipBitmap);
            mPeopleRect = getBitmapRect(mPeopleBitmap);
    
        }
    
        private Rect getBitmapRect(Bitmap bitmap) {
            int width = bitmap.getWidth();
            int height = bitmap.getHeight();
            return new Rect(-width / 2, -height / 2, width / 2, height / 2);
        }
    
        private void initPaint() {
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaint.setColor(0xff123456);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(40);
            mPaint.setStrokeJoin(Paint.Join.ROUND);
        }
    
        public void setPath(Path path) {
            mPath = path;
            mPathMeasure = new PathMeasure(mPath, false);
            mLength = mPathMeasure.getLength();
            postInvalidate();
        }
    
        public void setMax(int max) {
            mMax = max;
        }
    
        public void setProgress(int progress) {
            mProgress = progress;
            if (mPath != null) {
                mPathMeasure.getPosTan(progress / mMax * mLength, pos, tan);
                Log.e(TAG, "pos " + pos[0] + " " + pos[1] + " " + "tan " + tan[0] + " " + tan[1]);
            }
            invalidate();
        }
    
        public void setAnimationSpeed(float animationSpeed) {
            this.animationSpeed = animationSpeed + 50;
            if (animationSpeed > 400) {
                animationSpeed = 400f;
            }
    
        }
    
        Matrix peopleMatrix = new Matrix();
        Matrix quantMatrix1 = new Matrix();
        Matrix quantMatrix2 = new Matrix();
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.drawPath(mPath, mPaint);
            if (mProgress >= 0) {
                canvas.save();
                canvas.translate(pos[0], pos[1]);
                double atan = Math.atan(tan[1] / tan[0]);
                float degrees = (float) (atan * 180 / Math.PI);
                Log.e(TAG, "degrees " + degrees);
                if (tan[0] < 0) {
                    degrees += 180;
                }
                canvas.rotate(degrees);
                canvas.drawBitmap(mShipBitmap, null, mShipRect, mPaint);
    
                /*绘制小人 以及前后 晃动的帆*/
                float abs = Math.abs(animationProgress - 50);
                peopleMatrix.setTranslate(abs / 50 * -20 - mPeopleBitmap.getWidth() / 2, -mPeopleBitmap.getHeight() / 2);
    //            Log.e(TAG, "onDraw:matrix " + peopleMatrix);
    //            Log.e(TAG, "onDraw:animationProgress " + animationProgress);
                canvas.drawBitmap(mPeopleBitmap, peopleMatrix, mPaint);
    
                quantMatrix1.setTranslate(-mQuantBitmap.getWidth() / 2 - 10, -mQuantBitmap.getHeight() / 2);
                quantMatrix1.postRotate(45 + 90 * abs / 50);
                quantMatrix1.postTranslate(-20, 0);
                canvas.drawBitmap(mQuantBitmap, quantMatrix1, mPaint);
                quantMatrix2.setTranslate(-mQuantBitmap.getWidth() / 2 - 10, -mQuantBitmap.getHeight() / 2);
                quantMatrix2.postRotate(-45 - 90 * abs / 50);
                quantMatrix2.postTranslate(-20, 0);
                canvas.drawBitmap(mQuantBitmap, quantMatrix2, mPaint);
    
                canvas.restore();
            }
            mHandler.sendEmptyMessage(1);
        }
    
    }
    
    
     RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
            recyclerView.setLayoutManager(new LinearLayoutManager(this));
            int screenWidthDp = getResources().getConfiguration().screenWidthDp;
            final float scale = getResources().getDisplayMetrics().density;
            recyclerView.setAdapter(new PathAdapter(this, (int) (screenWidthDp * scale + 0.5f)));
    
            /*是否允许子view绘制到父view设置的padding中,或者父view的边界之外 false 是允许*/
            recyclerView.setClipChildren(false);
    
            recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);
                    Log.e(TAG, "" + dy);
                    int childCount = recyclerView.getChildCount();
                    for (int i = 0; i < childCount; i++) {
                        PathView child = (PathView) recyclerView.getChildAt(i);
                        float line = (getResources().getConfiguration().screenHeightDp * scale + 0.5f) / 3;
                        Log.e(TAG, "i " + i + " child.getTop() " + child.getTop());
                        if (child.getTop() > line) {
    
                            int progress = (int) ((child.getTop() - line) / child.getHeight() * 100);
                            Log.e(TAG, "progress " + progress);
                            if (progress < 0 || progress > 100) {
                                Log.e(TAG, "onScrolled: error progress " + progress);
                            }
                            if (child != currentPathView) {
                                if (currentPathView != null) {
                                    child.setProgress(100 - progress);
    
                                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                                        currentPathView.setZ(0);
                                    }
                                    currentPathView.setProgress(-1);
                                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                                        child.setZ(1);
                                    }
    
                                } else {
                                    child.setProgress(100 - progress);
                                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                                        child.setZ(1);
                                    }
                                }
                                currentPathView = child;
                            } else {
                                child.setProgress(100 - progress);
                            }
                            return;
                        }
                    }
    
                }
            });
    
    public class PathAdapter extends RecyclerView.Adapter<PathAdapter.PathViewHolder> {
        private Context mContext;
        private Path mLeftPath;
        private Path mRightPath;
    
        public PathAdapter(Context context, int width) {
            mContext = context;
            initLeftPath(width);
            initRightPath(width);
        }
    
        @NonNull
        @Override
        public PathViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            PathView pathView = new PathView(mContext);
            pathView.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 300));
            if (viewType == 0) {
                pathView.setPath(mLeftPath);
                pathView.setBackgroundColor(0xff134334);
            } else {
                pathView.setPath(mRightPath);
                pathView.setBackgroundColor(0xff752397);
            }
    //        pathView.setImage(R.mipmap.airplane2);
            return new PathViewHolder(pathView);
        }
    
        private void initLeftPath(int width) {
            mLeftPath = new Path();
            mLeftPath.moveTo(width / 3, 0);
            mLeftPath.lineTo(width / 3, 250);
            mLeftPath.lineTo(width / 3 * 2, 250);
            mLeftPath.lineTo(width / 3 * 2, 300);
        }
    
        private void initRightPath(int width) {
            mRightPath = new Path();
            mRightPath.moveTo(width / 3 * 2, 0);
            mRightPath.lineTo(width / 3 * 2, 250);
            mRightPath.lineTo(width / 3, 250);
            mRightPath.lineTo(width / 3, 300);
        }
    
        @Override
        public void onBindViewHolder(@NonNull PathViewHolder holder, int position) {
    
        }
    
        @Override
        public int getItemViewType(int position) {
            return position % 2;
        }
    
        @Override
        public int getItemCount() {
            return 100;
        }
    
        class PathViewHolder extends RecyclerView.ViewHolder {
    
            public PathViewHolder(@NonNull View itemView) {
                super(itemView);
            }
        }
    }
    
    

    相关文章

      网友评论

          本文标题:移动的小船

          本文链接:https://www.haomeiwen.com/subject/tzhbbhtx.html