无效方法仅在放入 'onDraw' 时有效
invalidate method only working when put in 'onDraw'
我正在尝试通过在 class 的 setter 之一中使用 invalidate 来刷新漏壶的显示。但是,它似乎没有被调用。另一方面,如果我将 invalidate 放入 onDraw 方法中,它就会起作用。文档中是否缺少某些内容。
到目前为止,我已经尝试以各种方式编写 invalidate :
- this.invalidate()
- 无效化()
public void setFillRatio(double fillRatio) {
if (this.fillRatio != fillRatio){
this.fillRatio = fillRatio;
this.invalidate();
Log.i("je suis passée", fillRatio + "");
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint p = new Paint();
Paint p2 = new Paint();
p.setColor(Color.GRAY);
p2.setColor(Color.BLUE);
Log.i("filll ratio on draw",canvas.getHeight() - (canvas.getHeight() * fillRatio) + "");
canvas.drawRect(new Rect(0,0, canvas.getWidth(), canvas.getHeight()), p);
canvas.drawRect(new Rect(0, (canvas.getHeight() - (int)(canvas.getHeight() * fillRatio)), canvas.getWidth(), canvas.getHeight()), p2);
}
奇怪的是,它确实记录了 setFillRatio() 中 invalidate 方法下的内容,但未调用 onDraw 中的日志。
编辑 1:
如果有人想测试该项目,请随时通过 google 驱动器 url 下载它:drive url of the project
问题: 根据您的代码,在 activity_count_down.xml
中,您已经有一个名为 Clepsydra
.
的自定义视图
<com.example.countdown.Clepsydra
android:id="@+id/view_clepsydra"
android:layout_width="363dp"
android:layout_height="379dp"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.615"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button4" />
但在 CountDownActivity.java
中,您声明了自定义视图的新实例 class
c = new Clepsydra(this);
因为完全不同,所以看不到onDraw
才叫
解决方案: 修改您的代码以在布局 xml 文件中引用自定义视图。
CountDownActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_count_down);
// Comment-out this line.
// c = new Clepsydra(this);
// Add this line instead
c = findViewById(R.id.view_clepsydra);
h = new Handler();
pi = PendingIntent.getActivity(this, 1, new Intent(this, EndOfCountDownActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
refreshRunnable = new Runnable() {
@Override
public void run() {
if (isActive){
long val = countdown - (SystemClock.elapsedRealtime() - startTime);
TextView cd = findViewById(R.id.textView4);
cd.setText(String.format("%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(val),
TimeUnit.MILLISECONDS.toMinutes(val) -
TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(val)),
TimeUnit.MILLISECONDS.toSeconds(val) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(val))));
c.setFillRatio((double)val/countdown);
// Comment-out this line as well.
// c.invalidate();
h.postDelayed(refreshRunnable, 500);
}
}
};
}
我正在尝试通过在 class 的 setter 之一中使用 invalidate 来刷新漏壶的显示。但是,它似乎没有被调用。另一方面,如果我将 invalidate 放入 onDraw 方法中,它就会起作用。文档中是否缺少某些内容。
到目前为止,我已经尝试以各种方式编写 invalidate :
- this.invalidate()
- 无效化()
public void setFillRatio(double fillRatio) {
if (this.fillRatio != fillRatio){
this.fillRatio = fillRatio;
this.invalidate();
Log.i("je suis passée", fillRatio + "");
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint p = new Paint();
Paint p2 = new Paint();
p.setColor(Color.GRAY);
p2.setColor(Color.BLUE);
Log.i("filll ratio on draw",canvas.getHeight() - (canvas.getHeight() * fillRatio) + "");
canvas.drawRect(new Rect(0,0, canvas.getWidth(), canvas.getHeight()), p);
canvas.drawRect(new Rect(0, (canvas.getHeight() - (int)(canvas.getHeight() * fillRatio)), canvas.getWidth(), canvas.getHeight()), p2);
}
奇怪的是,它确实记录了 setFillRatio() 中 invalidate 方法下的内容,但未调用 onDraw 中的日志。
编辑 1:
如果有人想测试该项目,请随时通过 google 驱动器 url 下载它:drive url of the project
问题: 根据您的代码,在 activity_count_down.xml
中,您已经有一个名为 Clepsydra
.
<com.example.countdown.Clepsydra
android:id="@+id/view_clepsydra"
android:layout_width="363dp"
android:layout_height="379dp"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.615"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button4" />
但在 CountDownActivity.java
中,您声明了自定义视图的新实例 class
c = new Clepsydra(this);
因为完全不同,所以看不到onDraw
才叫
解决方案: 修改您的代码以在布局 xml 文件中引用自定义视图。
CountDownActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_count_down);
// Comment-out this line.
// c = new Clepsydra(this);
// Add this line instead
c = findViewById(R.id.view_clepsydra);
h = new Handler();
pi = PendingIntent.getActivity(this, 1, new Intent(this, EndOfCountDownActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
refreshRunnable = new Runnable() {
@Override
public void run() {
if (isActive){
long val = countdown - (SystemClock.elapsedRealtime() - startTime);
TextView cd = findViewById(R.id.textView4);
cd.setText(String.format("%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(val),
TimeUnit.MILLISECONDS.toMinutes(val) -
TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(val)),
TimeUnit.MILLISECONDS.toSeconds(val) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(val))));
c.setFillRatio((double)val/countdown);
// Comment-out this line as well.
// c.invalidate();
h.postDelayed(refreshRunnable, 500);
}
}
};
}