部分重绘 - >无效(矩形RECT) [英] Partial redraw -> invalidate (Rect rect)
问题描述
在我的onDraw我要建立我的整个视图所需要的所有code,但我怎么能检测到,如果我想只执行部分重绘。
我想部分重绘应该调用canvas.invalidate(矩形RECT)被触发;
对?
在我的设备开发商设置我启用了显示屏幕更新,但是这总是告诉我,我的整个屏幕重绘...
In my onDraw I have all code needed to build my entire view but how can I detect if I want to perform only a partial redraw. I guess a partial redraw should be triggered by calling canvas.invalidate(Rect rect); Right? In developer settings of my device I enabled "Show screen updates" but this always tells me that my entire screen is redrawn…
下面你看到我的应用程序的截图:
Below you see a screenshot of my app:
正如你可以看到它是一个日历,我想给用户点击一个条目时,视觉反馈(比方说,一个红色边框)...
As you can see it is a calendar and I want to give the user a visual feedback when an entry is clicked (let’s say a red border around)…
我已经看到一些样品,但他们要么使用位图或许多成员变量的执行需要在...的onDraw
I’ve already seen some samples but they either use a bitmap or lots of member variables to execute just the code needed for redrawing specific region in onDraw…
谁能告诉我什么是实现这种功能的最佳方法是什么?
Can anyone tell me what’s the best way to implement such a feature?
更新:
在我的第一次抽签 Canvas.getClipBounds()
返回以下RECT:
On my first draw Canvas.getClipBounds()
returns the following rect:
Rect(0, 0 - 1200, 1800)
当我打电话无效(新矩形(304,748 - 529,902))
和检查 getClipBounds()
再次的onDraw()
它仍然具有相同的值。
when I call invalidate(new Rect(304, 748 - 529, 902))
and check getClipBounds()
again in onDraw()
it still has the same value.
UPDATE2(我的code):
UPDATE2 (my code):
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
_pTouchDown = new PointF(event.getX(), event.getY());
downX = event.getX();
downY = event.getY();
entrySelected = hasTimeRecordAt(downX, downY);
if (entrySelected != null) {
Rect rInvalidate = new Rect((int) entrySelected.get_Selected().left, (int) entrySelected.get_Selected().top, (int) entrySelected.get_Selected().right,
(int) entrySelected.get_Selected().bottom);
invalidate(rInvalidate);
}
return false;
}
更新3(我的布局):
UPDATE 3 (my Layout):
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MultiDayCalendarActivity" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical" >
<RelativeLayout
android:id="@+id/rlStatusline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/tvStatusline1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:text="asdf" >
</TextView>
<TextView
android:id="@+id/tvStatusline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="1234" >
</TextView>
</RelativeLayout>
<com.mxp.time.calendar.DayHeader
android:id="@+id/dayHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<ScrollView
android:id="@+id/m_svMultiRoot1"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" >
<com.mxp.time.calendar.Calendar
android:id="@+id/calendar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</ScrollView>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="1dp"
android:background="@color/brushBackgroundLight" >
</LinearLayout>
<RelativeLayout
android:id="@+id/rlMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true" >
<ImageButton
android:id="@+id/ibtCreateNewTimeRecord"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/menu" />
<ImageButton
android:id="@+id/ibtCalendarStopwatch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/stopwatch" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:orientation="horizontal" >
<ImageButton
android:id="@+id/ibtCalendarBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/previous" />
<ImageButton
android:id="@+id/ibtCalendarForward"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/next" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true" >
<ImageButton
android:id="@+id/ibtCalendarToday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/today" />
<ImageButton
android:id="@+id/ibtGotoJobs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/jobs" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
<FrameLayout
android:id="@+id/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start" >
</FrameLayout>
</android.support.v4.widget.DrawerLayout>
UPDATE4:
UPDATE4:
setContentView(R.layout.test_calendar);
// _cal = (Calendar) findViewById(R.id.calendar);
_cal = new Calendar(this);
_dayHeader = (DayHeader) findViewById(R.id.dayHeader);
final ScrollView sv = (ScrollView) findViewById(R.id.m_svMultiRoot1);
sv.addView(_cal);
同样的结果:
我onTouch我通过矩形(172,748 - 265,902)和onDraw有我得到的矩形(0,0 - 720,1800)
I in onTouch I pass Rect(172, 748 - 265, 902) and in onDraw I get Rect(0, 0 - 720, 1800)
更新5:
package com.example.testclip;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
class V extends View {
private static final String TAG = "null";
Rect clip = new Rect();
public V(Context context) {
super(context);
int[] colors = { 0xff000000, 0xffff0000, 0xffffffff };
Drawable d = new android.graphics.drawable.GradientDrawable(android.graphics.drawable.GradientDrawable.Orientation.TOP_BOTTOM, colors);
setBackgroundDrawable(d);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
StringBuilder sb = new StringBuilder();
sb.append("left: ");
sb.append(x);
sb.append(", top: ");
sb.append(y);
sb.append("right: ");
sb.append(x + 10);
sb.append(", bottom: ");
sb.append(y + 10);
Log.d(TAG, "onTouchEvent clip rect: " + sb.toString());
invalidate(x, y, x + 10, y + 10);
return false;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int w = MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(w, w * 4);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.getClipBounds(clip);
StringBuilder sb = new StringBuilder();
sb.append("left: ");
sb.append(clip.left);
sb.append(", top: ");
sb.append(clip.top);
sb.append("right: ");
sb.append(clip.right);
sb.append(", bottom: ");
sb.append(clip.bottom);
Log.d(TAG, "onDraw clip rect: " + sb.toString());
}
}
活动:
package com.example.testclip;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.ScrollView;
public class TestClipMainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_test_clip_main);
ScrollView sv = new ScrollView(this);
V v = new V(this);
sv.addView(v);
setContentView(sv);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.test_clip_main, menu);
return true;
}
}
这code产生以下输出
This code produces the following output
一十月2日至15日:47:54.011:D / OpenGLRenderer(833):启用调试模式0
10月2日至15日:47:54.926:D / dalvikvm(833):主题ID = 1:撤消后仍然暂停(SC = 1 DC = 1)
10月2日至15日:48:03.806:D / null的(833)的onDraw夹RECT:左:0,上:0right:720,底部:2880
10月2日至15日:48:05.381:D / null的(833)的onDraw夹RECT:左:0,上:0right:720,底部:2880
10月2日至15日:48:07.181:D / null的(833):onTouchEvent夹RECT:左:409,最高:358right:419,底部:368
10月2日至15日:48:09.806:D / null的(833)的onDraw夹RECT:左:0,上:0right:720,底部:2880
02-15 10:47:54.011: D/OpenGLRenderer(833): Enabling debug mode 0 02-15 10:47:54.926: D/dalvikvm(833): threadid=1: still suspended after undo (sc=1 dc=1) 02-15 10:48:03.806: D/null(833): onDraw clip rect: left: 0, top: 0right: 720, bottom: 2880 02-15 10:48:05.381: D/null(833): onDraw clip rect: left: 0, top: 0right: 720, bottom: 2880 02-15 10:48:07.181: D/null(833): onTouchEvent clip rect: left: 409, top: 358right: 419, bottom: 368 02-15 10:48:09.806: D/null(833): onDraw clip rect: left: 0, top: 0right: 720, bottom: 2880
推荐答案
您必须做得不对,看到这个定制视图:
you must be doing something wrong, see this custom View:
class V extends View {
Rect clip = new Rect();
private int cnt = 20;
public V(Context context) {
super(context);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
cnt++;
Log.d(TAG, "calling invalidate " + cnt);
invalidate(10, 10, cnt, cnt);
return false;
}
@Override
protected void onDraw(Canvas canvas) {
canvas.getClipBounds(clip);
Log.d(TAG, "onDraw clip " + clip);
}
}
更新:滚动型内自定义视图:
UPDATE: custom view inside a ScrollView:
class V extends View {
Rect clip = new Rect();
public V(Context context) {
super(context);
int[] colors = {0xff000000, 0xffff0000, 0xffffffff};
Drawable d = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, colors);
setBackgroundDrawable(d);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
invalidate(x, y, x + 10, y + 10);
return true;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int w = MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(w, w * 4);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.getClipBounds(clip);
Log.d(TAG, "onDraw clip height: " + clip.height());
}
}
这增加的onCreate:
add this to onCreate:
ScrollView sv = new ScrollView(this);
V v = new V(this);
sv.addView(v);
setContentView(sv);
这篇关于部分重绘 - &GT;无效(矩形RECT)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!