2014-02-11 2 views
0

В моем onDraw У меня есть весь код, необходимый для создания всего моего представления, но как я могу определить, хочу ли я выполнять только частичное перерисовку. Я предполагаю, что частичное перерисовывание должно быть вызвано вызовом canvas.invalidate (Rect rect); Справа? В настройках разработчика моего устройства я включил «Показывать обновления экрана», но это всегда говорит мне, что весь мой экран перерисовывается ...Частичное перерисовка -> invalidate (Rect rect)

Ниже вы видите скриншот моего приложения:

Screenshot of app

Как вам может видеть, что это календарь, и я хочу дать пользователю визуальную обратную связь при нажатии на кнопку (скажем, красную рамку вокруг) ...

Я уже видел несколько образцов, но они либо используют растровое изображение, либо много переменные-члены для выполнения только кода, необходимого для перерисовки spe в области onDraw ...

Может ли кто-нибудь сказать мне, что является лучшим способом реализации такой функции?

UPDATE:

На моем первом розыгрыше Canvas.getClipBounds() возвращает следующий прямоугольник:

Rect(0, 0 - 1200, 1800) 

, когда я звоню invalidate(new Rect(304, 748 - 529, 902)) и проверить getClipBounds() снова в onDraw() он все еще имеет то же значение.

UPDATE2 (мой код):

@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; 
    } 

UPDATE 3 (мой макет):

<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:

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 Я передаю Rect (172, 748 - 265, 902) и в OnDraw я получаю 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; 
} 

} 

Этот код производит следующий вывод

02- 15 10: 47: 54.011: D/OpenGLRenderer (833): включение режима отладки 0 02-15 10: 47: 54.926: D/dalvikvm (833): threadid = 1: все еще приостановлено после отмены (sc = 1 dc = 1) 0 2-15 10: 48: 03.806: D/null (833): onDraw clip rect: left: 0, top: 0 right: 720, bottom: 2880 02-15 10: 48: 05.381: D/null (833): onDraw clip rect: left: 0, top: 0 right: 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/нуль (833): OnDraw клип Прямоугольник: левый: 0, верхний: 0right: 720, внизу: 2880

+0

Брус у просто получить позицию выбранного Уре прямоугольника и нарисуйте прямоугольник под ним под углом ниже 10 пикселей на каждой стороне, так что это выглядит как граница? –

+0

Canvas.getClipBounds? – pskink

+0

@iQue: это именно то, что я делаю. Фактически я вычисляю все мои прямоугольники вне метода onDraw, поэтому мне не нужно выделять какие-либо объекты внутри моего onDraw. У меня есть три прямоугольника: Border (черный), Inner (цвет записи) и выбран (красный). В касании я проверяю, находятся ли координаты в любом прямоугольнике, и если это так, я выполняю перерисовку и использую «выбранный» прямоугольник, а не мой «по умолчанию» черный прямоугольник. Я просто не хочу каждый раз перерисовывать все ... – stefan

ответ

3

вы должны делать что-то неправильно, см этот обычай Вид:

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 : настраиваемый вид внутри 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:

ScrollView sv = new ScrollView(this); 
    V v = new V(this); 
    sv.addView(v); 
    setContentView(sv); 
+0

Точно так, как я это делаю. Собираюсь попробовать другое устройство ... – stefan

+0

Нет, извините! Я вызываю super.onDraw до getClipBounds(). Может быть, это проблема? Идти тестировать это – stefan

+1

Нет. Я переключился на свой Samsung Note2 и вызвал -> invalidate (Rect (172, 1219 - 265, 1383)), и первая строка моего onDraw: Rect rCLip = canvas.getClipBounds(); и этот rCLip -> Rect (0, 0 - 720, 1800). Я расширил свой вопрос с помощью кода из моего onTouch mehtod – stefan

Смежные вопросы