简体   繁体   English

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

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

I want to rotate an image often (multiple times a second) and display it. 我想经常旋转 图像 (每秒多次)并显示它。 In preparation to this, the image must be scaled to fit the View. 为此,必须缩放图像以适合视图。

What I first did, was defining a Drawable, loading it into a ImageView and calling setRotation() . 我首先要做的是定义一个Drawable,将其加载到ImageView中并调用setRotation() But it's only supportet since API level 11 and not 9. 但这是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" />

This gives a very bad perfomance (as expected), but what is the most effcient/suitable way to do this? 这会导致性能很差(如预期),但是最有效/最合适的方法是什么? The image contains transparent areas, if that is important. 图像包含透明区域(如果重要)。 Should I use hardware acceleration? 我应该使用硬件加速吗?

This answer is somehow related to this topic. 这个答案在某种程度上与此主题相关。 But in my case, the rotation has to be done multiple times while the scaling has to be done only once. 但是在我的情况下,旋转必须执行多次,而缩放仅需要执行一次。

I am stuck at this point after I worked on it for quite a while, and seek assistance here. 在工作了一段时间之后,我被困在这一点上,并在这里寻求帮助。 Please comment if you have further questions, I will happily answer them. 如果您还有其他问题,请发表评论,我会很乐意为您解答。

I'll assume your sensor reading is a push model, where you set up a listener for changes to the sensor, as opposed to a pull (polling) model. 我假设您的传感器读数是模型,在该模型中您设置了一个侦听器来更改传感器,而不是 (轮询)模型。 I'll also assume that the callback happens on an off-UI thread (if it isn't, it should). 我还将假设回调发生在非UI线程上(如果不是,则应该)。

Since you are rotating the image I'll also assume that your source bitmap is a circular image like a needle on a dial, etc. 由于要旋转图像,因此我还将假设源位图是圆形图像,例如表盘上的针等。

  • Create a View subclass. 创建一个View子类。 I'll call it SensorView . 我称它为SensorView You will be doing the drawing yourself, so you don't really need an ImageView . 您将自己绘制图形,因此实际上不需要ImageView
  • Your sensor callback will need a reference to the activity or have some way to run the update on the UI thread. 您的传感器回调将需要对活动的引用,或者具有某种方法可以在UI线程上运行更新。
  • When your sensor fires, get the reading and set it on the view. 当传感器触发时,获取读数并将其设置在视图上。

     actviity.runOnUiThread(new Runnable() { @Override public void run() { mSensorView.setReading(val); } }); 
  • The SensorView will have a value for the reading, a Bitmap for the image, and a Matrix for transforming the bitmap. 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); } } 

[edited after a bit of testing] [经过一点测试后编辑]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM