`
AndroidLL
  • 浏览: 74868 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

viewPager实现动态加载图片,附带大图片处理方式

 
阅读更多

viewPager实现动态加载图片,并且附带大图片的处理。

1.实现动态加载图片数量

  将图片放在assets下这样就可以动态读取图片的数量,当图片的内容和数量改变的时候程序不需要修改。

 

 private void initImage(){
	        try {
                pics = this.getResources().getAssets().list("guide");
                LinearLayout.LayoutParams mParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                        LinearLayout.LayoutParams.WRAP_CONTENT);
                
                //初始化引导图片列表
                for(int i=0; i<pics.length; i++) {
                    ImageView iv = new ImageView(this);
                    iv.setLayoutParams(mParams);
                    GetBitMap.instance().add(this, mHandler,"guide/"+pics[i], UPDATEDATA,iv);
                    views.add(iv);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
	    }

 2.当图片过大的时候,如果放在UI线程去读取图片很容易造成ANR,下面介绍一种异步线程加载图片并进行图片处理的方式

 

下面是异步加载图片的处理方式,而且不会开启很多子线程。

 

public void add(Context context,Handler handler,String path, int mCode,ImageView imageView){
		BitMapMsg msg = new BitMapMsg();
		msg.mConext = context;
		msg.mHandler = handler;
		msg.path = path;
		msg.mCode = mCode;
		msg.mImgView = imageView;
		mQueue.add(msg);
		if(!running){
		    new Thread(this).start();
		}
	}
	
	public void run() {
		running = true;
		while(mQueue.size() > 0 ){
			BitMapMsg msg = null;
			synchronized (mQueue) {
				msg = mQueue.remove(0);
			}
			if(msg != null && !msg.path.equals("")){
			    Message message = new Message();
                message.what = msg.mCode;
                if(msg.mImgView != null){
                    BitmapData bitmapData = new BitmapData(getBitmap(msg,msg.path),msg.mImgView);
                    message.getData().putParcelable("bitmap", bitmapData);
                    msg.mHandler.sendMessage(message);
                }
			}
		}
		running = false;
	}

 3 当图片过大的时候,加载图片的时候相信大家都遇到过内存溢出的问题,下面介绍一下处理bitmap的方式

 

 

尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图,因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存。

因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的 source,decodeStream最大的秘密在于其直接调用JNI>>nativeDecodeAsset()来完成decode,无需再使用java层的createBitmap,从而节省了java层的空间。

如果在读取时加上图片的Config参数,可以跟有效减少加载的内存,从而跟有效阻止抛out of Memory异常
另外,decodeStream直接拿的图片来读取字节码了, 不会根据机器的各种分辨率来自动适应,所以请大家注意适配的问题。

 

下面介绍一下Config的参数

其实这都是色彩的存储方法:我们知道ARGB指的是一种色彩模式,里面A代表Alpha,R表示red,G表示green,B表示blue,其实所有的可见色都是右红绿蓝组成的,所以红绿蓝又称为三原色,每个原色都存储着所表示颜色的信息值

Bitmap.Config  ALPHA_8    图形参数应该由一个字节来表示,应该是一种8位的位图 
Bitmap.Config  ARGB_4444  图形的参数应该由两个字节来表示 分别用4个bit来记录每个像素的A、R、G、B数据,16色位图 
Bitmap.Config  ARGB_8888  图形的参数应该由四个字节来表示 分别用8个bit来记录每个像素的A、R、G、B数据,就是常说的32bit位图、256色位图(这个也可能是RGB888这种24bit位图)   
Bitmap.Config  RGB_565 图形的参数应该由两个字节来表示 分别用5个、6个和5个bit记录像素的R、G、B数据,其中G的6个bit中一个是无效保留的,32色位图 

位图位数越高代表其可以存储的颜色信息越多,当然图像也就越逼真

 

下面介绍下BitmapFactory.Options

设置恰当的inSampleSize是解决该问题的关键之一。BitmapFactory.Options提供了另一个成员inJustDecodeBounds。
BitmapFactory.Options opts = new BitmapFactory.Options();

opts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(imageFile, opts);
设置inJustDecodeBounds为true后,decodeFile并不分配空间,但可计算出原始图片的长度和宽度,即opts.width和opts.height。
有了这两个参数,再通过一定的算法,即可得到一个恰当的inSampleSize。
查看Android源码,Android提供了一种动态计算的方法。

 

/**
     * 动态计算inSampleSize
     * @param options
     * @param minSideLength
     * @param maxNumOfPixels
     * @return
     */
    public static int computeSampleSize(BitmapFactory.Options options,
            int minSideLength, int maxNumOfPixels) {
        int initialSize = computeInitialSampleSize(options, minSideLength,
                maxNumOfPixels);

        int roundedSize;
        if (initialSize <= 8) {
            roundedSize = 1;
            while (roundedSize < initialSize) {
                roundedSize <<= 1;
            }
        } else {
            roundedSize = (initialSize + 7) / 8 * 8;
        }

        return roundedSize;
    }

    private static int computeInitialSampleSize(BitmapFactory.Options options,
            int minSideLength, int maxNumOfPixels) {
        double w = options.outWidth;
        double h = options.outHeight;

        int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math
                .sqrt(w * h / maxNumOfPixels));
        int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(Math
                .floor(w / minSideLength), Math.floor(h / minSideLength));

        if (upperBound < lowerBound) {
            // return the larger one when there is no overlapping zone.
            return lowerBound;
        }

        if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
            return 1;
        } else if (minSideLength == -1) {
            return lowerBound;
        } else {
            return upperBound;
        }
    }

 

 

分享到:
评论
1 楼 u010024805 2015-09-08  
很感谢你的分享!

相关推荐

    viewpager+fragment实现界面滑动,里面附带说明和截图

    在Android开发中,`ViewPager`和`Fragment`的结合使用是一种常见的实现界面滑动效果的方法。这种方式被广泛应用于创建如微信、支付宝等应用中的多页面滑动浏览功能。本教程将详细讲解如何利用`ViewPager`和`Fragment...

    Viewpager底部菜单,取消预加载

    使用viewpager实现的底部可滑动菜单,取消了viewpager本身自带的预加载机制,对应博文地址:http://blog.csdn.net/diyangxia/article/details/40348765;附带使用fragmentTabhost实现的底部菜单

    Android实现ViewPager中item之间的数据通信

    以下是一种实现方式: 1. **创建BroadcastReceiver**:首先,我们需要在每个ViewPager的item(Fragment)中创建一个BroadcastReceiver,用于接收其他Fragment发送的数据。在Fragment的onCreate方法中注册...

    android HorizontalScrollView和ViewPager联动效果

    而ViewPager则更进一步,它设计用于展示一系列全屏视图,通常用于实现滑动页面的效果,如图片轮播、页面切换等。ViewPager内部已经实现了平滑滚动,因此通常比HorizontalScrollView更适合创建这种交互体验。 在实现...

    MD风格的上拉刷新的两种实现,并附带下拉加载的demo

    这里我们提到的两种实现方式分别基于`utltra-pull-to-refresh`框架和Android自带的`SwipeRefreshLayout`组件。 1. `utltra-pull-to-refresh`框架实现: `utltra-pull-to-refresh`是一个强大的开源库,它提供了多种...

    一个好的架构附带ImageView手势缩放和下载图片

    这些库能自动处理网络错误,优化图片质量,甚至支持动态占位符和加载动画。在没有使用第三方库的情况下,开发者需要手动实现网络请求(如使用OkHttp或Retrofit),并结合内存和磁盘缓存策略来提高性能。 5. **多...

    Indicator.7z

    在Android应用开发中,Banner通常指的是轮播图或者滑动广告栏,它是应用程序中常见的一种展示多张图片或信息的方式,常用于推广、展示产品特色或者更新内容。"Indicator"在这里可能指的是轮播图下方的指示器,用来...

    gallery重叠特效源码+注释.zip

    - 在Android应用中加载网络或本地的大图时,通常会使用第三方图片加载库,如Glide、Picasso或Fresco,它们能有效地管理内存,防止OOM异常,并提供缓存机制。 6. **布局管理**: - 源码可能包含对LinearLayout、...

    android 用ViewStub实现Tab选项卡效果

    ViewStub是一个不可见的、没有大小的View,它的主要作用是在运行时动态加载XML布局。你可以通过设置`layout="@layout/layout_to_inflate"`属性来指定需要加载的布局文件,并通过`inflate()`方法将其加载到当前视图中...

    android 桌面源代码

    3. PagerAdapter:适配ViewPager,负责加载和管理页面,这里可能是加载应用快捷方式和小部件的布局。 二、创建桌面快捷方式 在Android中,创建桌面快捷方式主要通过Intent的ACTION_CREATE_SHORTCUT动作来完成。...

    Android编程滑动效果之Gallery+GridView实现图片预览功能(附demo源码下载)

    `ViewPager`通常配合`FragmentPagerAdapter`或`FragmentStatePagerAdapter`使用,每个页面代表一个图片,这样可以在滑动时加载或销毁相应的Fragment,优化性能。 总的来说,这个示例展示了如何使用Android的基础...

    View Pager

    在Android开发中,ViewPager是一个非常重要的组件,因为它提供了优雅的方式来展示大量数据或内容。 在描述中提到的`SplashActivity`是一个启动屏幕( Splash Screen),通常用于应用程序首次打开时显示品牌标识或...

    Android 上下滚动条、轮训滚动、广告条,附带源码及apk

    为了提升用户体验,通常会添加广告加载状态监听,以便在广告加载失败时做出相应处理。 **4. 源码分析** 在提供的文件列表中,"ADBarDemo"可能是实现广告条功能的示例代码。开发者可以通过阅读这个示例源码,了解...

    android页面横向滑动

    首先,我们要知道的是Android提供了多种实现横向滑动的方式,其中最常用的是使用ViewPager和RecyclerView。ViewPager是Android SDK中的一个组件,它可以显示多个Fragment或布局,并允许用户通过滑动手势在它们之间...

    android-support-v4 附带源码

    - **ViewPager**:ViewPager允许用户水平滑动浏览多个页面,常用于实现滑动Tab布局或图片轮播。Support Library v4中的ViewPager可以更好地支持更早版本的Android系统。 - **AppCompat**:AppCompat库是v4支持库的...

    Android应用源码gallery重叠特效源码+注释.zip

    7. **性能优化**:由于Gallery会一次性加载多个视图,所以源码可能涉及到性能优化,比如使用View Holder模式减少视图的创建和复用,或者使用异步加载图片技术避免UI阻塞。 8. **兼容性问题**:由于Gallery是旧组件...

    smartTabLayout

    开发者可以参考官方文档或社区分享的教程,了解如何配置SmartTabLayout的属性,设置标签内容,以及与ViewPager等组件协同工作,实现动态加载页面。 8. **性能优化**: 考虑到性能,SmartTabLayout在设计时进行了...

    neihan:内涵段子的大部分功能源代码实现

    能够实现显示:广告、图片、动画、视频、段子、登录 能够显示:各种段子的详情,详情附带评论,转发、分享、赞、踩 ##技术要点 Listview相关知识点: Listview的优化(viewholder、view的复用) Listview的多布局...

    Android 开源的下拉刷新 Eclipse版本

    通过设置监听器和处理回调,开发者可以实现数据的刷新逻辑,如重新加载网络数据。 总的来说,这个开源项目为Eclipse用户提供了一个方便的下拉刷新解决方案,涵盖了ViewPager和ListFragment等多种场景,且附带了示例...

Global site tag (gtag.js) - Google Analytics