Android如何重绘自定义视图

时间:2012-09-09 13:25:53

标签: android android-layout view invalidation

我知道其他时间已经问过这个问题,但我无法解决我的问题!

我创建了自己的View(RadarView),扩展了View。但是id没有更新!我尝试使用“invalidate()”和“postInvalidate()”,但它们不起作用!

以下是RadarView的代码:

`public class RadarView扩展了View {

    private HashMap<Integer, RadarData> allNodes;
    private int myId;
    private double distance=0.0; //in degree
    private double meeterDistance =0.0; // in meeters
    private Paint paint,node,nodeText;

    public RadarView(Context context, HashMap<Integer,RadarData> allNodes, int myId){
        super(context);
        this.allNodes = allNodes;
        this.myId=myId;
        paint = new Paint();
        paint.setStyle(Paint.Style.STROKE);
        paint.setAntiAlias(true);           
        paint.setColor(Color.GREEN);

        node = new Paint();
        node.setStyle(Paint.Style.FILL);
        node.setAntiAlias(true);            
        node.setColor(Color.GREEN);

        nodeText = new Paint();
        nodeText.setStyle(Paint.Style.STROKE);
        nodeText.setAntiAlias(true);            
        nodeText.setColor(Color.BLACK);
    }

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

        //here we draw the radar
        canvas.drawCircle(canvas.getWidth()/2, canvas.getHeight()/2, canvas.getWidth()/8, paint);
        canvas.drawCircle(canvas.getWidth()/2, canvas.getHeight()/2, canvas.getWidth()/4, paint);
        canvas.drawCircle(canvas.getWidth()/2, canvas.getHeight()/2, canvas.getWidth()/2.7f, paint);
        canvas.drawCircle(canvas.getWidth()/2, canvas.getHeight()/2, canvas.getWidth()/2, paint);
        canvas.drawLine(canvas.getWidth()/2, 0, canvas.getWidth()/2, canvas.getHeight(), paint);
        canvas.drawLine(0, canvas.getHeight()/2, canvas.getWidth(), canvas.getHeight()/2, paint);
        canvas.drawLine(canvas.getWidth() - canvas.getWidth()/4, canvas.getHeight()/10, canvas.getWidth() - canvas.getWidth()/4 +canvas.getWidth()/8, canvas.getHeight()/10, paint);

        //then we add nodes in the view, if at least one exist
        if(allNodes!=null){
            RadarData me = allNodes.get(myId);
            RadarData moreDistant = me;
            Set<Integer> set = allNodes.keySet();
            set.remove(myId);
            for (Integer key : set){
                RadarData element = allNodes.get(key);
                //calculate if it's the more distant, in that case variable "moreDistant" is updated
                if(distance<calculateDistance(element,me)){
                    distance=calculateDistance(element,me);
                    moreDistant=element;
                }
            }
            for (Integer key : set){
                drawNode(canvas,allNodes.get(key), me);
            }
            canvas.drawText("Unit: "+approximateDistance()/4+"degree", canvas.getWidth() - canvas.getWidth()/4, canvas.getHeight()/11,  paint);
        }
}

    private double approximateDistance(){
        int aux=(int) (distance*100);
        return aux/100;
    }
    private void drawNode(Canvas canvas,RadarData element, RadarData me) {
        int radius=canvas.getWidth()/2;
        double x=element.getLongitude()-me.getLongitude();
        double y=element.getLatitude() - me.getLatitude();
        int xInTheView=(int)(radius + x*radius/distance);
        int yInTheView=(int)(canvas.getHeight()/2 -y*radius/distance);

        canvas.drawCircle(xInTheView, yInTheView, radius/10, node);
        canvas.drawText(""+element.getId(), xInTheView, yInTheView, nodeText);
    }

    private double calculateDistance(RadarData element, RadarData me) {
        return Math.hypot(element.getLatitude()-me.getLatitude(), 
                element.getLongitude()-me.getLongitude());
    } 

} `

在主Activity中,我在gps位置发生变化时调用它:

private void updateRadarView(Location location) {
    if(location!=null){
        RadarData newState= new RadarData(myId, location.getLatitude(), location.getLongitude(), RadarData.RUNNING);
        allNodes = connectionHandler.request(newState);
        radarView = new RadarView(this,allNodes,myId);
        setContentView(radarView);
    }

}

正如您所看到的,我重新创建了radarView,然后使用setContentView来更新它,但我不认为这是一个很好的解决方案。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

为什么不在setNodes(HashMap<Integer,RadarData> allNodes)创建RadarView方法并在每次需要设置radarView数据时调用它:我的意思是radarView.setNodes(allNodes)而不是每次都重新创建它?