列表.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);
}
}
}
网友评论