您好我正在尝试构建类似水平图库的内容,我可以使用图库/相机中的图像添加或删除页面。
我正在尝试使用大位图,所以我使用算法来缩放位图并将其设置为每个页面的imageview。 该算法需要ImageView的宽度/高度(缩小)。
我遇到的问题是,当我执行自定义的PagerAdapter方法时,ImageView的宽度/高度尚未知晓(getWidth / getHeight返回0),因此它不起作用:
public Object instantiateItem(ViewGroup collection, int position) {
LayoutInflater inflater = (LayoutInflater) collection.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.document_page, null);
((ViewPager) collection).addView(view, 0);
ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
// Obtain the image file URI
// Call algorithm to get scaled bitmap using ImageView width and height --> PROBLEM: imageView.getWidth()/Height() return 0!!
// Set ImageView with scaled bitmap to avoid OutOfMemory Exception
return view;
}
你有什么建议?
感谢。
答案 0 :(得分:3)
如果图像已经在您的设备上,则您无需使用自己的算法来缩放图像。 ImageView
有ScaleType,您可以这样设置:
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP)
(或带有android:scaleType
属性的XML。)
剩下的问题是如何让您的网址中的图片显示在ImageView
中。使用SmartImageView或Android-Query(更强大)等库以异步方式实现(即不阻止UI线程)。
例如,使用SmartImageView,您可以使用以下内容:
myImageView.setImageUrl("http://www.awesomeimages.com/myawesomeimage.jpg");
只需阅读该页面上的示例,就会有更多选择。
如果您有某种触发的调整大小算法,例如通过某些网址参数,使用this solution并根据需要传递宽度和高度(可能使用上述库中的一个)。
正如您所说,getWidth()
和getHeight()
返回0
,请查看您为layout_width
设置的layout_height
和ImageView
}。如果它是fill_parent
,则应该没有问题,但如果 为wrap_content
,请考虑使用与最终图像具有相同宽高比的本地透明虚拟图像(直到“真实图像”已经设置好。)
答案 1 :(得分:0)
将bitmap factory与justInbounds选项一起使用。因此它只返回位图的维度而不将位图加载到ram。
options.inJustDecodeBounds = true;
答案 2 :(得分:0)
尝试将位图采样到屏幕大小(使用inJustDecodeBounds以获得位图的分辨率,并使用displayMatrics以获得屏幕的分辨率。)
如果没有透明度,您可能还希望使用RGB 565 format位图解码而不是8888。这将节省大约1/4的内存使用量。
无论如何,我建议reading this tutorial处理位图。
答案 3 :(得分:0)
我遇到了同样的问题,但是我想出了一个解决方案:创建一个函数,然后从“ public Object InstantiateItem(ViewGroup collection,int position)”中调用它。
诀窍是:将创建的函数设置为在几毫秒后执行(这样做将使用Handler对象)
通过这种方式,“ instantiateItem”将已经完成,并且视图元素将设置宽度和高度值。
下面是一些有关如何进行的示例代码:
@Override
public Object instantiateItem(ViewGroup container, int position)
{
View view = inflater.inflate(R.layout.pager_list_item,container,false);
TextView textView= (TextView) view.findViewById(R.id.pagerTextView);
ImageView imageView = (ImageView)view.findViewById(R.id.pagerImageView);
... //stuff that don't need the width and height
Handler handle = new Handler();
handle.postDelayed(new Runnable()
{
//here the widths and heights values should be already set
//now you can test the view.getWidth() and view.getHeight()
if(view.getWidth()!=0 && view.getHeight()!=0)
{
//now you sare safe to call the android algorithm for scaling large bitmaps
}
}, 100); //it will wait 100 miliseconds to execute
return view;
}
100毫秒是一个任意数字,可能太多了!
我建议您使用循环或递归函数来确保“ if”语句中的块将被执行,这样您就可以使用更小的毫秒数。
在我的项目中,我使用了一个递归函数,该函数在执行“ if”块之前会自行调用,并将其设置为5毫秒。
它应该没有循环或递归方法,仅通过设置任意数字(如100)并稍后进行测试即可工作,但是您无法确保该应用在所有设备上的行为都一样,因为一个设备可以快速运行,而其他设备则可以您可能还不知道,可能需要更长的时间才能准备好视图。