我实现了一个自定义
SpinNumberView
:它是方形的(比如40x40),它有一个垂直的
LinearLayout
作为子视图,在该线性布局中有一组40x40个垂直堆叠的单元。我想通过改变单元格的偏移来设置单元格垂直滚动的动画
.
但有一个问题:只有边界内(第一个)的初始单元格被渲染,边界外的单元格没有被绘制,因此当我设置线性布局的动画以滚动时,线性布局在旋转,但只有第一个单元格可见,其他单元格是空白。以下是自定义视图的全部代码:
public class SpinNumberView extends RelativeLayout {
private int startNumber;
private int endNumber;
private int number;
private int gridsize;
private int index;
public static final double stepDuration = 0.1;
private boolean inAnimation = true;
ArrayList<Integer> numbers;
public LinearLayout container;
public SpinNumberView(Context context) {
super(context);
}
public SpinNumberView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void dispatchDraw(Canvas canvas) {
// draw the background black solid circle
float radius = (float)(this.gridsize);
Paint p = new Paint();
p.setStyle(Paint.Style.FILL);
p.setARGB(192, 0, 0, 0);
canvas.drawCircle(radius/2, radius/2, radius/2, p);
// draw 1px white border
Paint pp = new Paint();
pp.setStyle(Paint.Style.STROKE);
pp.setStrokeWidth(2.0f);
pp.setARGB(192, 255, 255, 255);
canvas.drawCircle(radius/2, radius/2, radius/2-1, pp);
// clip to the circle
Path path = new Path();
RectF r = new RectF((float)0.0, (float)0.0, radius, radius);
path.addRoundRect(r, radius/2, radius/2, Path.Direction.CW);
canvas.clipPath(path);
super.dispatchDraw(canvas);
}
@Override
protected void onLayout(boolean b, int i, int i1, int i2, int i3) {
super.onLayout(b, i, i1, i2, i3);
}
class AniListener implements Animator.AnimatorListener {
@Override
public void onAnimationStart(Animator animator) {}
@Override
public void onAnimationEnd(Animator animator) {
SpinNumberView.this.animateStep();
}
@Override
public void onAnimationCancel(Animator animator) {}
@Override
public void onAnimationRepeat(Animator animator) {}
}
public void animateStep() {
this.container.setTranslationY(0);
float offset;
TimeInterpolator inter;
if(this.inAnimation) {
offset = (float)this.gridsize * this.numbers.size();
inter = new LinearInterpolator();
} else {
offset = (float)this.gridsize * this.index;
inter = new DecelerateInterpolator();
}
long duration = (long)(SpinNumberView.stepDuration * this.numbers.size() * 1000);
ViewPropertyAnimator ani = this.container.animate().translationYBy(-offset).setDuration(duration);
ani.setInterpolator(inter);
if(this.inAnimation) {
ani.setListener(new AniListener());
} else {
ani.setListener(null);
}
ani.start();
}
public void stopAnimation() {
this.inAnimation = false;
}
public void startAnimation() {
this.inAnimation = true;
float offset = (float)this.gridsize * this.numbers.size();
long duration = (long)(SpinNumberView.stepDuration * this.numbers.size() * 1000);
ViewPropertyAnimator ani = this.container.animate().translationYBy(-offset).setDuration(duration);
TimeInterpolator inter = new AccelerateInterpolator();
ani.setInterpolator(inter);
ani.setListener(new AniListener());
ani.start();
}
public void setup(int number, int start, int end, int gridsize) {
this.setBackgroundColor(Color.TRANSPARENT);
this.setAlpha((float) 0.5);
this.setClipChildren(false);
this.number = number;
this.startNumber = start;
this.endNumber = end;
this.gridsize = gridsize;
this.numbers = new ArrayList<>();
for(int i=start; i<=end;i++) {
this.numbers.add(i);
}
Collections.shuffle(this.numbers);
// Find index of target number within shuffled array
this.index = this.numbers.indexOf(this.number);
this.container = new LinearLayout(this.getContext());
this.container.setOrientation(LinearLayout.VERTICAL);
this.container.setGravity(Gravity.CENTER_HORIZONTAL);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(this.gridsize, this.gridsize * (this.numbers.size()+1));
this.container.setLayoutParams(params);
this.addView(this.container);
int offsety = 0;
// setup all the number views
for(int k=0;k<this.numbers.size()+1;k++) {
String txt;
if(k==this.numbers.size()) {
txt = Integer.toString(this.numbers.get(0));
} else {
txt = Integer.toString(this.numbers.get(k));
}
TextView tv = new TextView(this.getContext());
tv.setLayoutParams(new LayoutParams(this.gridsize, this.gridsize));
tv.setText(txt);
tv.setTextSize(24.0f);
tv.setTextColor(Color.WHITE);
tv.setTextAlignment(TextView.TEXT_ALIGNMENT_CENTER);
tv.setLines(1);
tv.setGravity(Gravity.CENTER_VERTICAL);
this.container.addView(tv);
offsety += this.gridsize;
}
this.invalidate();
}
}
为什么会这样?
顺便说一句:我用
getDrawingCache()
在屏幕内容中,单元格在屏幕截图中可见!