9

由于GalleryView已弃用,我们应该迁移到一些替代小部件,在我的情况下ViewFlipper是最好的,但我遇到了几个问题,正如您在以下屏幕截图中看到的那样,我设计了一个轮ImageGalleryGalleryView

在此处输入图像描述

一切都按我的预期ViewFlipper工作,但我无法实现两件事:

1-ViewFlipper始终显示一项;但是我需要一次显示三个项目(甚至更多)。

2-ViewFlipper是不可触摸的小部件,这不是我想要的!


正如 FlávioFaria 在下一篇文章中提到ViewPager的,这也是一个很好的案例,但我无法将放大动画传递给它!

我已经完成了一切ViewPager,现在它工作得很好,但我错过了一个功能,那就是无限滚动!

添加了我的PagerAdapter课程

public class CarouselAdapter extends PagerAdapter  
{  
    private Context mContext;
    private ImageLoader imageLoader;
    private String[] bannerUri;

    public CarouselAdapter (Context c, String[] bannerArray) 
    { 
        this.mContext = c; 
        this.bannerUri = bannerArray;
        // Setup image loader
        this.imageLoader = ImageLoader.getInstance();
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(c)
            .threadPoolSize(2) 
            .memoryCache(new WeakMemoryCache())
            .discCacheFileNameGenerator(new Md5FileNameGenerator())
            .build();
        this.imageLoader.init(config);
    } 

    @Override
    public Object instantiateItem(ViewGroup container, int position)
    {
        if (position >= bannerUri.length) 
            position %= bannerUri.length;

        ImageView i = new ImageView(mContext);
        displayImage(i, bannerUri[position]);
        i.setScaleType(ScaleType.FIT_XY); 
        container.addView(i);
        return i;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) 
    {
        container.removeView((View)object);
    }

    @Override
    public int getCount() 
    {
        return Integer.MAX_VALUE;
    }

    @Override
    public boolean isViewFromObject(View view, Object object)
    {
         return (view == object);
    }

    private void displayImage(final ImageView mImage, String ImageUri)
    {
        DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
            .showStubImage(R.drawable.border)
            .showImageForEmptyUri(R.drawable.border)
            .imageScaleType(ImageScaleType.EXACTLY)
            .bitmapConfig(Bitmap.Config.RGB_565)
            .resetViewBeforeLoading()
            .cacheOnDisc() 
            .displayer(new FadeInBitmapDisplayer(740))
            .build();

        imageLoader.loadImage(ImageUri, defaultOptions, new SimpleImageLoadingListener() 
        {
            public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage)
            {
                mImage.setImageDrawable(new BitmapDrawable(mContext.getResources()
                        , getDesiredBitmap(loadedImage, 12)));
            }
        });
    }

    private Bitmap getDesiredBitmap(Bitmap originalImage, int roundValue)
    {
        // Create required bitmaps
        Bitmap shadowBitmap = BitmapFactory.decodeResource(mContext.getResources()
                , R.drawable.samsungapps_thumb_shadow);
        Bitmap outputBitmap = Bitmap.createBitmap(originalImage.getWidth()
                , originalImage.getHeight() + 80, Bitmap.Config.ARGB_8888);
        // Create canvas and pass bitmap to it 
        Canvas mCanvas = new Canvas(outputBitmap);
        // And finally draw the shaodw
        mCanvas.drawBitmap(Bitmap.createScaledBitmap(shadowBitmap, originalImage.getWidth()
                , (int)(shadowBitmap.getHeight() / 2.3), false), 0, originalImage.getHeight(), null);

        mCanvas.drawBitmap(originalImage, 0, 0, null);

        return outputBitmap;
    }
}

关于如何完成这两件事的任何想法?

4

3 回答 3

2

在浏览了您的代码后,我发现 CarouselAdapter 以循环方式(无限滚动)的方式运行,部分代码导致这是:-

@Override
    public int getCount() 
    {
        return Integer.MAX_VALUE;
    }

@Override
    public Object instantiateItem(ViewGroup container, int position)
    {
        if (position >= bannerUri.length) 
            position %= bannerUri.length;
       .
       . 
       .
    }

但是你在做什么

        ImageView i = new ImageView(mContext);
        displayImage(i, bannerUri[position]);
        i.setScaleType(ScaleType.FIT_XY); 
        container.addView(i);
        return i;

在 instanceiteItem 中,因此对于 ViewPager 中的每个页面,您都在为 ImageView 分配内存,而 ViewPager 正因此而耗尽内存。ViewPager 具有public void setOffscreenPageLimit (int limit)通过销毁视图层次结构中的空闲页面来限制分配的内存的方法。 请参阅下面的 android 文档

设置应保留到处于空闲状态的视图层次结构中当前页面的任一侧的页面数。超出此限制的页面将在需要时从适配器重新创建。

这是作为优化提供的。如果您事先知道需要支持的页面数量或在页面上设置了延迟加载机制,则调整此设置可以提高分页动画和交互的感知流畅度。如果您有少量页面 (3-4) 可以同时保持活动状态,那么在用户页面来回切换时,新创建的视图子树的布局将花费更少的时间。

您应该将此限制保持在较低水平,尤其是在您的页面具有复杂布局的情况下。此设置默认为 1。

如上所述,如果不为其指定任何值,它将使用默认值 1,并且 ViewPager 将从视图层次结构中销毁空闲页面。因此,您需要根据您的内存要求(图像数量和平均图像大小)将优化值传递给它,这将解决您的内存不足问题。

于 2013-04-19T20:04:55.293 回答
1

考虑使用具有多个页面的 ViewPager:

http://commonsware.com/blog/2012/08/20/multiple-view-viewpager-options.html

于 2013-04-17T21:55:54.833 回答
1

好的,这是您可以做的一件事:

  1. 使用水平列表视图解决方案(此处为示例

  2. 确保每个项目占据屏幕宽度的 1/3 左右。也许更多一点。

  3. 对于中心项目的粘性,处理触摸事件,使其平滑滚动到中间项目,例如三星的示例“圆形启动器”所示。

  4. 要获得更多花哨的效果,请使视图的大小/位置属性更改类似于我在 #3 上写过的示例。

于 2013-04-18T12:06:33.570 回答