我遇到了很多问题,这些问题都是相关的。有些问题我已经解决了,但我找到的解决方案可能会阻止我生产最终产品。我会在这里提到所有的问题和解决方案,因为我相信这将是一个相当常见的问题,很多人都会遇到。
最终结果我有一个基础图像,上面有3层(透明的png)。显示的层由用户决定。每一层都会为基础图像添加更多信息。在我的情况下,基本图像是恒星的图像。当用户添加额外的层时,他们可以看到星座边界、恒星名称和网格。用户还需要能够放大某个区域,以获得更清晰的天空图像。
第一期图像大小为两个大(1324×1872)导致OutOfMemory错误。
通过使用缩放图像来解决
/**
* This method scales an image in the assets directory and returns a
* BitmapDrawable object that can be passed to an images setImageBitmap or a
* views setBackgroundDrawable by passing this method into the constructor
* of BitmapDrawable.
* eg ViewGroup.setBackgroundDrawable(
* new BitmapDrawable(getScaledBitMap(this, imagePath, 2)));
*
* @param context
* @param imgFullPath
* @param imageSize
* @return
* @throws IOException
*/
public static Bitmap getScaledBitMap(Context context, String imgFullPath,
int imageSize) throws IOException
{
InputStream instream;
instream = context.getAssets().open(imgFullPath);
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize = imageSize;
Bitmap bitmap=BitmapFactory.decodeStream(instream, null, options);
return bitmap;
}
尽管这段代码有所帮助,但在加载3层时,我仍然会出现OutOfMemory错误。我还认为缩放图像将是一个问题,因为质量已经降低。
第二个问题。据我所知,你不能在其中一个图像不透明的地方对png进行分层。不会显示任何透明图像,只显示不透明的图像(基本图像)。
通过将FrameLayout的背景设置为基础图像并仅将3层作为该布局的子层来解决此问题。
第三期放大图像。我在这里找到了一个解决方案。我如何获得图像的缩放功能?,但我还没有测试它,因为模拟器没有多点触摸功能,而且我带它去游泳时,我的设备不喜欢它。我目前没有其他设备可以测试。
加载所有4个图像(基本+3层)而不获取outOfMemoryError并具有缩放图像功能的最佳方法是什么。
我已经创建了一个项目,这里有所需的代码
我找到了一些解决方案。问题一:完成代码并使用此处的TouchImageView之后。我不再得到内存不足的错误。我可以毫无问题地加载所有层。
第二个和第三个问题也通过使用TouchImageView解决。虽然我对此感到高兴,但我希望课堂上有更多的评论,因为我花了很多时间试图弄清楚它是如何工作的以及为什么工作的,但最终失败了。
我遇到的最后一个大问题是,当缩放时,它只会缩放顶层(正如预期的那样)。解决方法是稍微更改TouchImageview类,并添加矩阵更改侦听器的功能。现在,当矩阵发生变化时,矩阵将返回给监听器,监听器随后更新包括基础图像在内的所有层中的矩阵。这使得所有图像同时缩放,无论缩放如何,标签都指向基本图像上的相同位置。
这是一个非常简单的接口,用于通知听众矩阵更改
public interface IOnMatixChangedListener
{
public void onMatrixChanged(Matrix matrix);
}