Android invalidateDrawable()不工作

Android invalidateDrawable()不工作,android,android-drawable,statelistdrawable,android-view-invalidate,Android,Android Drawable,Statelistdrawable,Android View Invalidate,我有一个自定义视图中的一堆可绘制元素。我希望用户能够按下一个或多个绘图,它会改变颜色。当前,每个可绘制文件都只是一个具有两种状态的StateListDrawable:state\u pressed和not pressed。每次我按下一个可绘制图像,setState返回true,所以我假设它实际上已更改,但我看不到可绘制图像的更改。invalidatedRavable什么都不做吗?我做错了什么?如何在按下时重新绘制一个可绘制的图形,而不需要调用customView.invalidate()并每次重

我有一个自定义视图中的一堆可绘制元素。我希望用户能够按下一个或多个绘图,它会改变颜色。当前,每个可绘制文件都只是一个具有两种状态的
StateListDrawable
state\u pressed
和not pressed。每次我按下一个可绘制图像,
setState
返回true,所以我假设它实际上已更改,但我看不到可绘制图像的更改。
invalidatedRavable
什么都不做吗?我做错了什么?如何在按下时重新绘制一个可绘制的图形,而不需要调用
customView.invalidate()
并每次重新绘制整个图形?我本来是这样做的,但发现我的应用程序运行得非常慢/效率低下。谢谢

流程:

Custom View (contains set of our custom class - TouchKey)
- Custom class TouchKey containing drawable and info
- Upon press or release, custom class finds which drawable to change
下面是
TouchKey
类中按钮触摸的代码(MyTouch是一个自定义类,跟踪android设备上的所有触摸):

如何在自定义视图中绘制my
StateListDrawable

public class CustomView extends View {

    private TreeMap<Integer, TouchKey> keymap;

    /* Initialization Code Stuff Here - call drawKey */

    // StateListDrawable Creation
    private StateListDrawable drawKey(Canvas canvas, int bounds_l, 
                                  int bounds_t, int bounds_r, int bounds_b) 
        throws Resources.NotFoundException, XmlPullParserException, IOException {

        StateListDrawable key = new StateListDrawable();
        key.addState(new int[]{android.R.attr.state_pressed}, 
                     ContextCompat.getDrawable(mContext, R.drawable.key_pressed));
        key.addState(new int[]{-android.R.attr.state_pressed}, 
                     ContextCompat.getDrawable(mContext, R.drawable.key_released));    

        key.setBounds(bound_l, bounds_t, bounds_r, bounds_b);
        key.draw(canvas);

        return key;
    }
}
公共类CustomView扩展了视图{
私有树映射键图;
/*这里的初始化代码-调用drawKey*/
//StateListDrawable创建
private StateListDrawable drawKey(画布、整数边界、,
int-bounds_t,int-bounds_r,int-bounds_b)
抛出Resources.NotFoundException、XmlPullParserException、IOException{
StateListDrawable键=新的StateListDrawable();
key.addState(新int[]{android.R.attr.state_pressed},
ContextCompat.getDrawable(mContext,R.drawable.key_按下));
key.addState(新int[]{-android.R.attr.state_pressed},
ContextCompat.getDrawable(mContext,R.drawable.key_已发布));
键.设置边界(边界l,边界t,边界r,边界b);
键。绘制(画布);
返回键;
}
}
我本来是这样做的,但发现我的应用程序运行得非常慢/效率低下

如果这样做,您在代码的某些地方会有很大的优势,或者(我想)在绘制之前不会缩放图像。所以,试着在代码中找到一个对系统有巨大优势的逻辑。因为
View.invalidate()
so-fast方法

其他0,02$:

我想你应该开发一些类似键盘的东西。对于这种情况,您需要使画布的某个区域无效

View.invalidate(new Rect(0, 0, 49, 49));

我也有这个问题,但我最终还是解决了。出现此问题的原因是,您在上下文中使用的
Drawable
对象没有通过调用
setBounds(Rect)
设置它的
Bounds
,因此默认情况下它的
Bounds
Rect(0,0,0,0)
。这导致
视图的
invalidateDrawable()

请参阅
视图。invalidateDrawable()

查看检查是否可绘制。getDirtyBounds():


嗨,宋承宪,你的第一句话是什么意思,只是理解起来有点困难。我试图使rect无效,但我仍然很慢times@yun.cloud我的意思是,你有一个长期的工作,在UI线程。可能是对话框,或者progressbar或者类似的东西。花一点时间检查代码,问“此方法/类中的硬逻辑是什么?”如果确定问题不在这里,请尝试通过DDMS工具检查代码,并查看系统中发生了什么。为什么会出现延迟?我确实有一个音频线程在应用程序运行的整个过程中运行,所以很可能就是这样?我想这是很重要的,所以每次按下一个可拖动按钮时,都会播放正弦波。当我不必每次都重新绘制时,多点触摸就可以了。但是,尝试重新绘制每个按下的可绘制文件会减慢跟踪速度-有时,当同时按下3个可绘制文件时,两个可绘制文件会立即更改/播放,而第三个可绘制文件的播放/更改颜色会花费更长的时间。我猜这种延迟对我来说更重要,因为音频处理会减慢速度?@yun.cloud若你们准备好每一个声音或者从文件系统加载它,它可能会产生延迟。我想你是在UI线程中这样做的。我正在开放SLES中运行我的音频线程,所以可能是这样吗?我只是在没有运行音频线程的情况下测试了它,触摸仍然滞后(同样的问题,但没有声音)
View.invalidate(new Rect(0, 0, 49, 49));
@Override
public void invalidateDrawable(@NonNull Drawable drawable) {
    if (verifyDrawable(drawable)) {
        final Rect dirty = drawable.getDirtyBounds();
        final int scrollX = mScrollX;
        final int scrollY = mScrollY;

        invalidate(dirty.left + scrollX, dirty.top + scrollY,
                dirty.right + scrollX, dirty.bottom + scrollY);
        rebuildOutline();
    }
}
  /**
 * Return the drawable's dirty bounds Rect. Note: for efficiency, the
 * returned object may be the same object stored in the drawable (though
 * this is not guaranteed).
 * <p>
 * By default, this returns the full drawable bounds. Custom drawables may
 * override this method to perform more precise invalidation.
 *
 * @return The dirty bounds of this drawable
 */
@NonNull
public Rect getDirtyBounds() {
    return getBounds();
}
@Override
public void draw(@NonNull Canvas canvas) {
    Rect localRect = canvas.getClipBounds();
    this.setBounds(localRect);
    ...
}