嗨,我正在尝试构建类似水平图库的东西,我可以使用我的图库/相机中的图像添加或删除页面。
我正在尝试使用大型位图,所以我使用算法来缩放位图并将其设置为每个页面的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;
}
你有什么建议?
谢谢。
如果图像已经在您的设备上,则您不需要自己的算法来缩放图像。一个ImageView
有一个ScaleType,你可以像这样设置:
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP)
(或使用android:scaleType
属性的XML)。
剩下的问题是如何从您的URL中获取图像以显示在ImageView
中。使用诸如SmartImageView或Android-Query(更强大)之类的库以异步方式实现(即不阻塞UI线程)。
例如,使用SmartImageView,您可以使用以下内容:
myImageView.setImageUrl("http://www.awesomeimages.com/myawesomeimage.jpg");
只需阅读该页面上的示例,就会有更多选择。
如果您有某种触发的调整大小算法,例如通过某些URL参数,使用this solution并根据需要传递宽度和高度(可能使用上述库之一)。
正如你所说getWidth()
和getHeight()
返回0
,请查看你为layout_width
设置的layout_height
和ImageView
。如果它是fill_parent
,应该没有问题,但如果必须是wrap_content
,请考虑使用与最终图像具有相同宽高比的本地透明虚拟图像(直到“真实图像”已设置)。
将bitmap factory与justInbounds选项一起使用。因此它只返回位图的维度而不将位图加载到ram。
options.inJustDecodeBounds = true;
尝试将位图采样到屏幕的大小(使用inJustDecodeBounds以获得位图的分辨率,并使用displayMatrics以获得屏幕的分辨率)。
如果没有透明度,您可能还希望使用位图解码的RGB 565 format而不是8888。这将节省大约1/4的内存使用量。
在任何情况下,我建议处理位图的reading this tutorial。
我遇到了同样的问题,但我提出了一个解决方案:创建一个函数并从“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这样的任意数字并稍后进行测试,但你不能保证应用程序对所有设备的行为都相同,因为一个可以快速,而另一个可能需要你不知道,为了准备好看的时间长一点。