在 Android UI 中旋转和显示图像的最有效方法是什么?

What is the most efficient way to rotate and display an image in an Android UI?

我想经常旋转 图像(每秒多次)和显示它。为此,必须缩放图像以适合视图。

我首先做的是定义一个 Drawable,将其加载到 ImageView 中并调用 setRotation()。但它仅支持 API 级别 11 而不是 9。

<ImageView
    android:id="@+id/image"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:adjustViewBounds="true"
    android:scaleType="fitCenter"
    android:src="@drawable/image" />

这给出了非常糟糕的性能(正如预期的那样),但是最 effcient/suitable 的方法是什么?图像包含透明区域(如果这很重要)。我应该使用硬件加速吗?

This 答案与此主题有某种关联。但就我而言,旋转必须进行多次,而缩放只需进行一次。

弄了半天卡在这了,求助。如果您还有其他问题,请发表评论,我会很乐意回答。

我假设你的传感器读数是一个 push 模型,你在其中设置一个侦听器以更改传感器,而不是 pull(轮询)模型。我还假设回调发生在一个关闭的 UI 线程上(如果不是,它应该)。

由于您正在旋转图像,我还假设您的源位图是圆形图像,如表盘上的针等。

  • 创建一个 View 子类。我称之为 SensorView。你会自己画画,所以你真的不需要 ImageView.
  • 您的传感器回调将需要对 activity 的引用或有某种方式 运行 UI 线程上的更新。
  • 当您的传感器触发时,获取读数并将其设置在视图上。

    actviity.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            mSensorView.setReading(val);
        }
    });
    
  • SensorView 将有一个用于读取的值,一个用于图像的 Bitmap,以及一个用于转换位图的 Matrix

    public class SensorView extends View {
    
        private float mReading;  // I use float as an example; use whatever your sensor device supports
        private Bitmap mBitmap;
        private Matrix mMatrix;
        private RectF mBitmapRect;
        private RectF mViewRect;
    
        public SensorView(Context context) {
            this(context, null);
        }
    
        public SensorView(Context context, AttributeSet attrs) {
            super(context, attrs);
    
            // set up your Bitmap here; don't worry about scaling it yet
            mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.sensor_bitmap);
    
            mMatrix = new Matrix();
            mBitmapRect = new RectF(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
            mViewRect = new RectF();
        }
    
        public void setReading(float reading) {
            mReading = reading;
            postInvalidate();   // refresh the display
        }
    
        @Override
        public void onDraw(Canvas canvas) {
    
            mViewRect.right = getWidth();
            mViewRect.bottom = getHeight();
            mMatrix.reset();
    
            // center and scale the image
            mMatrix.setRectToRect(mBitmapRect, mViewRect, ScaleToFit.CENTER);
    
            // do the rotation
            float theta = ... // compute angle based on mReading
            mMatrix.preRotate(theta, mBitmapRect.centerX(), mBitmapRect.centerY());
    
            // draw the bitmap with the matrix
            canvas.drawBitmap(mBitmap, mMatrix, null);
        }
    }
    

[经过一些测试后编辑]