Viewpager具有大位图

问题描述 投票:0回答:4

嗨,我正在尝试构建类似水平图库的东西,我可以使用我的图库/相机中的图像添加或删除页面。

我正在尝试使用大型位图,所以我使用算法来缩放位图并将其设置为每个页面的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;
}

你有什么建议?

谢谢。

android android-viewpager android-imageview
4个回答
3
投票

缩放图像客户端:

如果图像已经在您的设备上,则您不需要自己的算法来缩放图像。一个ImageView有一个ScaleType,你可以像这样设置:

imageView.setScaleType(ImageView.ScaleType.CENTER_CROP)

(或使用android:scaleType属性的XML)。

剩下的问题是如何从您的URL中获取图像以显示在ImageView中。使用诸如SmartImageViewAndroid-Query(更强大)之类的库以异步方式实现(即不阻塞UI线程)。

例如,使用SmartImageView,您可以使用以下内容:

myImageView.setImageUrl("http://www.awesomeimages.com/myawesomeimage.jpg");

只需阅读该页面上的示例,就会有更多选择。

扩展服务器端

如果您有某种触发的调整大小算法,例如通过某些URL参数,使用this solution并根据需要传递宽度和高度(可能使用上述库之一)。

正如你所说getWidth()getHeight()返回0,请查看你为layout_width设置的layout_heightImageView。如果它是fill_parent,应该没有问题,但如果必须是wrap_content,请考虑使用与最终图像具有相同宽高比的本地透明虚拟图像(直到“真实图像”已设置)。


0
投票

将bitmap factory与justInbounds选项一起使用。因此它只返回位图的维度而不将位图加载到ram。

  options.inJustDecodeBounds = true;

0
投票

尝试将位图采样到屏幕的大小(使用inJustDecodeBounds以获得位图的分辨率,并使用displayMatrics以获得屏幕的分辨率)。

如果没有透明度,您可能还希望使用位图解码的RGB 565 format而不是8888。这将节省大约1/4的内存使用量。

在任何情况下,我建议处理位图的reading this tutorial


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这样的任意数字并稍后进行测试,但你不能保证应用程序对所有设备的行为都相同,因为一个可以快速,而另一个可能需要你不知道,为了准备好看的时间长一点。

© www.soinside.com 2019 - 2024. All rights reserved.