Java 视图';s invalidate也会重新绘制以前的纹理

Java 视图';s invalidate也会重新绘制以前的纹理,java,android,android-view,android-custom-view,custom-view,Java,Android,Android View,Android Custom View,Custom View,我想实现这样的目标 但不是这样,我得到的是这样的东西 我正在使用invalidate重新绘制自定义视图。但每次多边形的边发生变化时,它都会创建另一个视图。我哪里做错了 这是我的密码 PolygonView.Java public class PolygonView extends View { public float polygonRadius; public int polygonSides; public int polygonColor; priv

我想实现这样的目标

但不是这样,我得到的是这样的东西

我正在使用
invalidate
重新绘制自定义视图。但每次多边形的边发生变化时,它都会创建另一个视图。我哪里做错了

这是我的密码

PolygonView.Java

public class PolygonView extends View {

    public float polygonRadius;
    public int polygonSides;
    public int polygonColor;

    private Paint paint;
    private Path path;
    public PolygonView(Context context) {
        super(context);
        init(null);
    }

    public PolygonView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(attrs);
    }

    public PolygonView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(attrs);

    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public PolygonView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(attrs);
    }

    private void init(AttributeSet attrs)
    {
        polygonColor = ContextCompat.getColor(getContext(),R.color.polygonColor);
        polygonSides = 5;

        if (attrs!=null){
            TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(attrs,R.styleable.PolygonView,0,0);
            polygonColor = typedArray.getColor(R.styleable.PolygonView_polygon_color,polygonColor);
            polygonRadius = typedArray.getDimension(R.styleable.PolygonView_polygon_radius,polygonRadius);
            polygonSides = typedArray.getInteger(R.styleable.PolygonView_polygon_sides,polygonSides);
        }

        paint = new Paint();
        paint.setColor(polygonColor);
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(5);

        path = new Path();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        double angle = 2.0*Math.PI/polygonSides;
        int cx = getWidth()/2;
        int cy = getHeight()/2;
        path.moveTo(
                (float) (cx +polygonRadius*Math.cos(0.0)),
                (float) (cy +polygonRadius*Math.sin(0.0))
        );
        for(int i=1;i<=polygonSides;i++){
            path.lineTo(
                    (float) (cx + polygonRadius*Math.cos(angle*i)),
                    (float) (cy + polygonRadius*Math.sin(angle*i))
            );
        }

        path.close();

        canvas.drawPath(path,paint);

    }
}
public class Fragment2 extends Fragment {


public Fragment2() {
    // Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View v =  inflater.inflate(R.layout.fragment_polygon, container, false);

    final PolygonView polygonView = v.findViewById(R.id.polygonView);
    SeekBar seekBarRadius = v.findViewById(R.id.seekBarRadius);
    SeekBar seekBarSides = v.findViewById(R.id.seekBarSides);

    seekBarSides.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            int p = progress/10;
            if(p<1){
                polygonView.polygonSides = 1;
            }else if (p>10){
                polygonView.polygonSides = 10;
            }
            else {
                polygonView.polygonSides = p;
            }

            polygonView.invalidate();

        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    });


    return v;
}

}
公共类PolygonView扩展了视图{
公共浮动多边形半径;
公共多配偶;
公共int多色;
私人油漆;
专用路径;
公共多边形视图(上下文){
超级(上下文);
初始化(空);
}
公共PolygonView(上下文上下文,@Nullable AttributeSet attrs){
超级(上下文,attrs);
init(attrs);
}
公共PolygonView(上下文上下文,@Nullable AttributeSet attrs,int defStyleAttr){
super(上下文、attrs、defStyleAttr);
init(attrs);
}
@TargetApi(Build.VERSION\u code.LOLLIPOP)
公共PolygonView(上下文上下文,@Nullable AttributeSet attrs,int-defStyleAttr,int-defStyleRes){
super(context、attrs、defStyleAttr、defStyleRes);
init(attrs);
}
私有void init(属性集属性)
{
polygonColor=ContextCompat.getColor(getContext(),R.color.polygonColor);
多糖苷=5;
如果(属性!=null){
TypedArray TypedArray=getContext().getTheme().ActainStyledAttributes(attrs,R.styleable.PolygonView,0,0);
polygonColor=typedArray.getColor(R.styleable.PolygonView\u polygon\u color,polygonColor);
polygonRadius=typedArray.getDimension(R.styleable.PolygonView\u polygon\u radius,polygonRadius);
polygonSides=typedArray.getInteger(R.styleable.PolygonView\u polygon\u sides,polygonSides);
}
油漆=新油漆();
油漆。设置颜色(多色);
paint.setAntiAlias(真);
绘制.设置样式(绘制.样式.笔划);
油漆。设置行程宽度(5);
路径=新路径();
}
@凌驾
受保护的void onDraw(画布){
super.onDraw(帆布);
双角度=2.0*Math.PI/多边形;
int cx=getWidth()/2;
int cy=getHeight()/2;
path.moveTo(
(浮点)(cx+polygonRadius*数学cos(0.0)),
(浮动)(cy+多边形半径*数学sin(0.0))
);

对于(int i=1;i您总是在改变路径,但从不重置它。在
onDraw()
方法中,选择
path
,然后对其应用新操作:


    public void onDraw() {
        path.reset();
        ...
    }

不要调用
path.lineTo
onDraw内部
onDraw
-只需调用
drawPath
并将
lineTo
stuff移动到
setPolygonSides
方法,也不要忘了先调用
path重置
方法,然后在
onDraw内部
只应调用
Canvas\35; drawPath
-设置路径还有一个是@pskink,这是一个应该进行的优化,但与问题本身无关。谢谢。这样OP将被迫引入一些
setPolygonSides
方法,而不是丑陋的:
polygonView.polygonSides=p;polygonView.invalidate()
但我同意这是一种优化,不是绝对需要的
设置路径应该在其他地方进行
-具体在哪里?@pskinkas我在
setPolygonSides
方法中说