奇怪的行为与Android view.invalidate() [英] Strange behavior with Android view.invalidate()

查看:153
本文介绍了奇怪的行为与Android view.invalidate()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个的LinearLayout垂直放置3自定义视图,它们被用来显示不同​​的动态信息,因此他们应该是无效的,并在不同的时间重绘。但我发现的看法失效超出通常的期望,那就是:如果你无效顶视图,所有3次都在同一时间无效,如果无效,中间看,中部和底部的观点是无效的,顶一个是不是,如果无效底视图,只有底部视图本身是无效的,这就是我想要的东西,所以发生了什么与前2个个案?我搜索,得到了类似的问题,如:

<一个href=\"http://stackoverflow.com/questions/26192491/invalidate-one-view-force-other-views-invalidate-too-how-separating-that\">Invalidate一种观点认为力等意见无效吗?如何分离的

的Andr​​oid的Invalidate()只单一视图

但似乎没有确切的答案。我在这里发布我的code,任何的评论是AP preciated。


TestView.java

 包com.vrb.myview;进口android.app.Activity;
进口android.os.Bundle;
进口android.view.View;
公共类TestView延伸活动{    @覆盖
    保护无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.main);
    }    公共无效onTest(查看视图){
        MyView1 MV1 =(MyView1)findViewById(R.id.mv1);
        MyView1 MV2 =(MyView1)findViewById(R.id.mv2);
        MyView1 MV3 =(MyView1)findViewById(R.id.mv3);        mv1.invalidate(); //所有3次都无效
    // mv2.invalidate(); // MV2和MV3被无效
    // mv3.invalidate(); //只有MV3是无效的,这就是我想要的
    }
}

MyView1.java

 包com.vrb.myview;进口了java.util.Random;进口android.content.Context;
进口android.graphics.Canvas;
进口android.graphics.Color;
进口android.graphics.Paint;
进口android.graphics.Rect;
进口android.util.AttributeSet;
进口android.util.Log;
进口android.view.View;公共类MyView1扩展视图{
    矩形RC = NULL;
    涂料P = NULL;
    随机ř;
    公共MyView1(上下文CTX){
        超(CTX);
        RC =新的矩形();
        P =新的油漆();
        R =新的随机();
    }
    公共MyView1(上下文CTX,AttributeSet中的集合){
        超(CTX,设置);
        RC =新的矩形();
        P =新的油漆();
        R =新的随机();
    }    公共无效的onDraw(帆布油画){
        如果(canvas.getClipBounds(RC)){
            Log.d(MyView1,ID =+的getId()+矩形:+ rc.left +,+ rc.top +,+ rc.right +,+ rc.bottom);
            p.setColor(Color.argb(0xff的,Math.abs(r.nextInt())%255,Math.abs(r.nextInt())%255,Math.abs(r.nextInt())%255)) ;
            canvas.drawRect(RC,P);
        }其他{
            Log.d(MyView1,ID =+的getId()+矩形=空);
        }
    }
}

的main.xml

 &LT; LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    的xmlns:工具=htt​​p://schemas.android.com/tool​​s
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent
    机器人:ID =@ + ID /根
    机器人:方向=垂直
    工具:上下文=com.vrb.myview.TestView&GT;    &LT; com.vrb.myview.MyView1
        机器人:layout_width =match_parent
        机器人:layout_height =100px的
        机器人:ID =@ + ID / MV1/&GT;    &LT; com.vrb.myview.MyView1
        机器人:layout_width =match_parent
        机器人:layout_height =100px的
        机器人:ID =@ + ID / MV2/&GT;    &LT; com.vrb.myview.MyView1
        机器人:layout_width =match_parent
        机器人:layout_height =100px的
        机器人:ID =@ + ID / MV3/&GT;    &LT;按钮
        机器人:layout_width =WRAP_CONTENT
        机器人:layout_height =WRAP_CONTENT
        机器人:layout_gravity =中心
        机器人:文字=无效
        安卓的onClick =onTest
        机器人:ID =@ + ID / BTN/&GT;&LT; / LinearLayout中&GT;


解决方案

您应该不依赖于数或呼叫到的onDraw()的时间您查看的内部状态。移动 p.setColor()打电话给一个独立的公共方法,并调用无效()在它的结束。例如:

 公共类MyView1扩展视图{
    ...
    公共无效changePaint(){
        p.setColor(Color.argb(0xff的,Math.abs(r.nextInt())%255,Math.abs(r.nextInt())%255,Math.abs(r.nextInt())%255)) ;
        无效();
    }
}

然后在你的 onTest()方法:

 公共无效onTest(查看视图){
    MyView1 MV1 =(MyView1)findViewById(R.id.mv1);
    ...
    mv1.changePaint();
    ...
}

I have 3 custom views placed vertically in a LinearLayout, they are used to display different dynamic info, so they're supposed be invalidated and redrawn at different time. But I found the view invalidation is out of usual expectation, that is: if you invalidate the top view,all 3 views are invalidated at the same time, if you invalidate the middle view, the middle and bottom views are invalidated, the top one is not, if you invalidate the bottom view, only the bottom view itself is invalidated, this is what I want, so what happened with the first 2 cases ? I searched and got similar questions like:

Invalidate one view force other views Invalidate too? how separating that

Android Invalidate() only single view

but it seems no exact answer. I post my code here, any comment is appreciated.


TestView.java

package com.vrb.myview;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;


public class TestView extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    public void onTest(View view){
        MyView1 mv1 = (MyView1)findViewById(R.id.mv1);
        MyView1 mv2 = (MyView1)findViewById(R.id.mv2);
        MyView1 mv3 = (MyView1)findViewById(R.id.mv3);

        mv1.invalidate(); // all 3 views are invalidated
    //  mv2.invalidate(); // mv2 and mv3 are invalidated
    //  mv3.invalidate(); // only mv3 is invalidated,this is what I want
    }
}

MyView1.java

package com.vrb.myview;

import java.util.Random;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

public class MyView1 extends View {
    Rect rc=null;
    Paint p=null;
    Random r;
    public MyView1(Context ctx){
        super(ctx);
        rc = new Rect();
        p = new Paint();
        r = new Random();
    }
    public MyView1(Context ctx, AttributeSet set){
        super(ctx, set);
        rc = new Rect();
        p = new Paint();
        r = new Random();
    }

    public void onDraw(Canvas canvas){
        if(canvas.getClipBounds(rc)){
            Log.d("MyView1","id="+getId()+" Rect: "+rc.left+","+rc.top+","+rc.right+","+rc.bottom);
            p.setColor(Color.argb(0xff, Math.abs(r.nextInt())%255, Math.abs(r.nextInt())%255, Math.abs(r.nextInt())%255));
            canvas.drawRect(rc, p);
        }else{
            Log.d("MyView1","id="+getId()+" Rect=null");        
        }       
    }
}

main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/root"
    android:orientation="vertical"
    tools:context="com.vrb.myview.TestView" >

    <com.vrb.myview.MyView1
        android:layout_width="match_parent"
        android:layout_height="100px"
        android:id="@+id/mv1" />

    <com.vrb.myview.MyView1
        android:layout_width="match_parent"
        android:layout_height="100px"
        android:id="@+id/mv2" />

    <com.vrb.myview.MyView1
        android:layout_width="match_parent"
        android:layout_height="100px"
        android:id="@+id/mv3" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Invalidate"
        android:onClick="onTest"
        android:id="@+id/btn" />

</LinearLayout>

解决方案

You shouldn't rely on the count or the time of the calls to onDraw() for the internal state of your View. Move the p.setColor() call to a separate public method, and call invalidate() at the end of it. For example:

public class MyView1 extends View {
    ...
    public void changePaint() {
        p.setColor(Color.argb(0xff, Math.abs(r.nextInt()) % 255, Math.abs(r.nextInt()) % 255, Math.abs(r.nextInt()) % 255));
        invalidate();
    }
}

Then in your onTest() method:

public void onTest(View view) {
    MyView1 mv1 = (MyView1)findViewById(R.id.mv1);
    ...
    mv1.changePaint();
    ...
}

这篇关于奇怪的行为与Android view.invalidate()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆