正确的在ViewPager中使用Bitmap图像

Android ImageView高级实战:从相框堆叠到交互游戏开发 在Android应用开发中,ImageView作为核心UI控件,不仅是静态图片的容器,更是实现动态交互和复杂视觉效果的基础。其scaleType、alpha等属性控制着图片的显示方式,而FrameLayout、ViewPager2等现代布局容器则决定了视图的层级与交互逻辑。理解视图堆叠(Z-order)原理和适配器模式,能够高效管理大量图片资源,构建流畅的相册浏览体验。通过事件监听与图形属性动态控制,开发者可以将简单的图片展示升级为丰富的交互应用,例如实现图片切换动画或构建完整的猜牌小游戏。这些技术广泛应用 阅读详情
欢迎访问:[http://www.3body.tk/iblog/](http://www.3body.tk/iblog/)

在实现image gallery的详情查看时使用swipe view模式是很好的选择,你可以使用ViewPager和对应的PagerAdapter来实现这个模式。不过对于adapter你还有更好的选择:FragmentStatePagerAdapter,当屏幕关闭的时候这个子类可以自动的销毁和保存ViewPager的Fragments状态,以节省内存。

注意:如果你只需要使用很少的图片,并确定其不会超出程序内存的限制的话,使用PagerAdapter或者FragmentPagerAdapter对于你来说是最适合的。

下面是一个ViewPager的实现,他里面包含了数个ImageView。在main activity中使用ViewPager和adapter:

public class ImageDetailActivity extends FragmentActivity {
    public static final String EXTRA_IMAGE = "extra_image";

    private ImagePagerAdapter mAdapter;
    private ViewPager mPager;

    // A static dataset to back the ViewPager adapter
    public final static Integer[] imageResIds = new Integer[] {
            R.drawable.sample_image_1, R.drawable.sample_image_2, R.drawable.sample_image_3,
            R.drawable.sample_image_4, R.drawable.sample_image_5, R.drawable.sample_image_6,
            R.drawable.sample_image_7, R.drawable.sample_image_8, R.drawable.sample_image_9};

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.image_detail_pager); // Contains just a ViewPager

        mAdapter = new ImagePagerAdapter(getSupportFragmentManager(), imageResIds.length);
        mPager = (ViewPager) findViewById(R.id.pager);
        mPager.setAdapter(mAdapter);
    }

    public static class ImagePagerAdapter extends FragmentStatePagerAdapter {
        private final int mSize;

        public ImagePagerAdapter(FragmentManager fm, int size) {
            super(fm);
            mSize = size;
        }

        @Override
        public int getCount() {
            return mSize;
        }

        @Override
        public Fragment getItem(int position) {
            return ImageDetailFragment.newInstance(position);
        }
    }
}

下面是使用Fragment和ImageView的一个实现,看上去是十分合理的,你能发现它的缺点吗?并且如何进行改进?

public class ImageDetailFragment extends Fragment {
    private static final String IMAGE_DATA_EXTRA = "resId";
    private int mImageNum;
    private ImageView mImageView;

    static ImageDetailFragment newInstance(int imageNum) {
        final ImageDetailFragment f = new ImageDetailFragment();
        final Bundle args = new Bundle();
        args.putInt(IMAGE_DATA_EXTRA, imageNum);
        f.setArguments(args);
        return f;
    }

    // Empty constructor, required as per Fragment docs
    public ImageDetailFragment() {}

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mImageNum = getArguments() != null ? getArguments().getInt(IMAGE_DATA_EXTRA) : -1;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // image_detail_fragment.xml contains just an ImageView
        final View v = inflater.inflate(R.layout.image_detail_fragment, container, false);
        mImageView = (ImageView) v.findViewById(R.id.imageView);
        return v;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        final int resId = ImageDetailActivity.imageResIds[mImageNum];
        mImageView.setImageResource(resId); // Load image into ImageView
    }
}

希望你已经注意到了这个问题:所有的图片都是在UI线程中处理的,这样将导致程序挂掉,强制退出。这时需要使用AsyncTask(在“Processing Bitmaps Off the UI Thread”这一篇文章中介绍过的)来处理,直接将图片的加载和处理放在后台线程中去做。

public class ImageDetailActivity extends FragmentActivity {
    ...

    public void loadBitmap(int resId, ImageView imageView) {
        mImageView.setImageResource(R.drawable.image_placeholder);
        BitmapWorkerTask task = new BitmapWorkerTask(mImageView);
        task.execute(resId);
    }

    ... // include BitmapWorkerTask class
}

public class ImageDetailFragment extends Fragment {
    ...

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (ImageDetailActivity.class.isInstance(getActivity())) {
            final int resId = ImageDetailActivity.imageResIds[mImageNum];
            // Call out to ImageDetailActivity to load the bitmap in a background thread
            ((ImageDetailActivity) getActivity()).loadBitmap(resId, mImageView);
        }
    }
}

任何多余的处理(比如调整图像大小,从网络获取图片)都移到BitmapWorkerTask中,这样就不会影响到UI主线程。如果后台线程除了在硬盘中直接读取图片之外还有其他处理,在内存或硬盘中加入一个缓存是十分有用的(在“Caching Bitmaps”这篇文章中有介绍)。下面是一个内存缓存的实现:

public class ImageDetailActivity extends FragmentActivity {
    ...
    private LruCache<String, Bitmap> mMemoryCache;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        ...
        // initialize LruCache as per Use a Memory Cache section
    }

    public void loadBitmap(int resId, ImageView imageView) {
        final String imageKey = String.valueOf(resId);

        final Bitmap bitmap = mMemoryCache.get(imageKey);
        if (bitmap != null) {
            mImageView.setImageBitmap(bitmap);
        } else {
            mImageView.setImageResource(R.drawable.image_placeholder);
            BitmapWorkerTask task = new BitmapWorkerTask(mImageView);
            task.execute(resId);
        }
    }

    ... // include updated BitmapWorkerTask from Use a Memory Cache section
}

现在将上面的代码片段整理一下,就是一个完美的ViewPager,它实现了最小化的图片资源加载延迟,可以在后台线程中实现尽量多或尽量少的处理(根据你的需求)。

下面一篇文章会介绍如何在GridView中做类似的处理。

翻译自:Displaying Bitmaps in Your UI

Arduino MEGA驱动ILI9341显示SD卡BMP图片:硬件连接、SPI冲突与性能优化 在嵌入式系统开发中,SPI总线是连接微控制器与外围设备(如存储卡和显示屏)的常用高速串行通信接口。其工作原理基于主从模式,通过时钟线同步数据,实现高效的双向数据传输。这项技术的核心价值在于能够以较少的引脚资源,管理多个共享数据线的设备,是构建紧凑型嵌入式系统的关键技术。在物联网设备、智能家居中控和工业仪表盘等应用场景中,经常需要将存储在SD卡中的图像、字体等资源动态显示到TFT屏幕上,以构建丰富的用户界面。本文以Arduino MEGA平台为例,深入探讨如何解决ILI9341 TFT屏幕与SD卡模块共享SP 阅读详情

相关推荐

八年复盘:2017欢聚时代Android校招笔试全解析

Android开发基础是移动端技术栈的基石,而校招笔试正是检验这些核心知识的最佳试金石。从Java集合到Handler消息机制,从Binder IPC到性能优化,这些底层原理贯穿于Android应用开发的始终,也是直播等高实时性场景的技术保障。深入理解这些概念,不仅有助于应对面试中的高频考点,更能为工程实践中的卡顿排查、内存治理提供理论支撑。随着行业向精细化发展,无论是传统App开发还是车载、音视频等新方向,扎实的底层功底仍是技术成长的关键。本文以2017年欢聚时代Android工程师校招C卷为样本,回顾其

weixin_33858485的博客 632

PagerAdapter 普通写法

1,viewPagre的普通写法public ImagePagerAdapter(Context context, List&lt;Photo&gt; imgList) { this.mContext = context;}private void createImageViews() { for (int i = 0; i &lt; 4; i++) { Pho...

bobo的博客 254

2024最新版:MacOS Sonoma系统下CocoaPods安装全攻略(解决Ruby版本冲突)

本文详细介绍了在MacOS Sonoma系统下安装CocoaPods的全过程,重点解决Ruby版本冲突问题。通过HomeBrew安装最新Ruby版本,配置环境变量,并正确安装CocoaPods,帮助iOS开发者顺利管理项目依赖。文章还提供了常见问题的解决方案和优化配置建议,确保开发环境的稳定性和高效性。

lll78的博客 1042

翻页类视图 ViewPager

翻页类视图 ViewPager 用法解析

威威的博客 1840

SAP 物料账前期没有运行的解决方法

If you use the actual costing (material ledger), you must have completely closed all period-end closing operations in the actual costing for the penultimate period prior to the period shift. Use the '...

含笑饮砒霜死后更嚣张 3316

Anthropic API接入指南:连接失败、403鉴权与Claude Code集成排查

在AI应用开发中,API接入与鉴权机制是开发者绕不开的基础工程问题。无论是调用云端模型服务还是自建网关,网络连通性、HTTP状态码语义、模型路由映射都会直接影响服务可用性。本文从通用的网络诊断与鉴权原理出发,梳理了从TCP连接失败到403权限拒绝的典型链路,并深入解析网关模型路由匹配机制。在此基础上,进一步说明如何通过环境变量完成Claude Code与VS Code的本地集成,以及一套基于Python的可复现接入方案。内容涵盖Anthropic API高频报错定位、curl冒烟测试、SDK工程化实践,适合

weixin_28743405的博客 468

PagerAdapter使用说明

PagerAdapter 经过试验,从log中得出: 1、在整个 页面切换过程中,最多只有3个 page被保持 在container里面(ViewPager),中间位当前正在显示的page;         1 初始时 显示 索引为0的page,这时有两个page添加到container中,索引为0、1,此时选中 0;   2 当向左滑动到 索引为1的page时,创建并添加,索引为2page

lcw1987565的专栏 4028

避坑指南:DDR4内存条Margin测试Fail?从Intel RMT工具到PCB Layout的完整排错思路

本文深入探讨了DDR4内存条在Margin测试中Fail的完整排错思路,从Intel RMT工具分析到PCB Layout优化。通过实战案例,详细解析了信号完整性问题的诊断与解决方案,包括拓扑结构影响、传输线参数优化及HyperLynx仿真验证,为硬件设计工程师提供了宝贵的避坑指南。

weixin_42530458的博客 450

【Android 基础知识】翻页类视图 ViewPager

文章目录1、翻页视图 ViewPager2、翻页标题栏 PagerTitleStrip/PagerTabStrip 1、翻页视图 ViewPager 对于 ViewPager 来说,一个页面就是一个项(相当于 ListView 的一个列表项),许多页面组成 ViewPager 的页面项; ViewPager 的适配器使用 PagerAdapter; ViewPager 的监听器使用 OnPageChangeListener,表示监听页面切换事件。 ViewPager 三个常用方法: setAdapte

17902的博客 1368

TC264摄像头循迹进阶:八邻域与逐行遍历在复杂赛道边界提取中的实战对比

本文对比分析了TC264摄像头循迹中八邻域法与逐行遍历法在复杂赛道边界提取中的实战表现。八邻域法在边界连续性方面表现优异,适合处理环岛等复杂元素;逐行遍历法则在计算效率和岔路口识别上更具优势。文章提供了详细的代码实现和优化策略,帮助智能车竞赛选手根据赛道特点选择最佳算法方案。

rainy的博客 937

MEME-CHIP实战:5步搞定ChIP-seq数据中的motif发现与可视化

本文提供了使用MEME-CHIP工具进行ChIP-seq数据motif发现与可视化的完整实战指南。通过5个清晰步骤,从数据准备、环境搭建、命令行执行到结果解读与高级可视化,详细讲解了如何利用MEME-CHIP工作流高效完成从原始peak序列到发表级motif图的分析,并分享了关键的参数调优与避坑经验。

alice7model的博客 508

Android图形处理教程:高效显示Bitmap的最佳实践

Android图形处理教程:高效显示Bitmap的最佳实践 前言 在Android应用开发中,高效地加载和显示Bitmap是一个常见且重要的技术挑战。本教程将深入探讨如何在UI上优雅地显示Bitmap,特别是在ViewPager和GridView这两种常用控件中的实现方案。 为什么需要优化Bitmap显示 Bitmap作为Android中处理图像的基本单位,直接关系到应用的内存使用和界面流畅度。不...

gitblog_00123的博客 489

智元机器人开源具身仿真框架 Genie Sim 入门教程

GenieSim是AgiBot推出的具身智能仿真框架,提供完整闭环开发管道,包括轨迹生成、模型训练和基准测试。框架支持Docker容器化部署,要求Ubuntu 22.04和NVIDIA硬件环境。主要功能涵盖: 支持12种基准测试任务 提供ADER评估框架 集成UniVLA/RDT等基线模型 支持PICO/键盘遥操作 具备轨迹记录回放功能 提供完整API控制接口 开发者可通过Hugging Face获取场景资产,使用标准化ROS主题与仿真环境交互。框架特别优化了碰撞检测和抓取物理模拟,适用于从简单抓取到复杂操

2506_90492529的博客 2542

Android翻页效果原理实现之模拟扭曲

Android翻页效果原理实现之模拟扭曲

qq_44925210的博客 162

EMC意义下的共模(Common Mode)和差模(Differential Mode)

在电子产品中,信号或电源通过两根导线传输。对比维度差模(DM)共模(CM)电流方向一进一出,相等相反同向、相等回流路径两根导线组成的闭合回路地或外壳EMC影响较小容易辐射干扰,重点治理类型定义有用信号干扰信号抑制方法常规滤波器、电感、电容共模电感、磁环、屏蔽、接地技术等。

weixin_43199439的博客 1248

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Android性能优化实战:从工具使用到架构设计的全链路指南

性能优化是软件开发中的核心工程实践,其本质在于通过系统性的方法提升应用运行效率与资源利用率。从技术原理层面看,它涉及算法复杂度分析、内存管理机制、渲染管线优化等基础概念。在移动开发领域,性能优化的技术价值尤为突出,直接关系到用户体验、设备续航与应用稳定性。常见的应用场景包括解决界面卡顿、减少内存占用、提升启动速度及降低能耗等。本文聚焦Android平台,深入探讨如何利用Profiler、Systrace等分析工具定位性能瓶颈,并结合内存泄漏预防、布局渲染优化、网络请求管理等热词,提供从代码编写到架构设计的系

weixin_34032792的博客 331

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

【Android Developers Training】 55. 序言:高效显示位图

注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好。 原文链接:http://developer.android.com/training/displaying-bitmaps/index.html 学习如何使用常规的技术来加载和处理的Bitmap对象,可以让你的UI组件保持响应并避免超...

weixin_30407613的博客 118

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Android 技术文章合集 | Jetpack、Kotlin、Window & View、事件机制、多线程、存储等

代码说」:一个专注于 Android 技术细节拆解的分享号,欢迎关注!

小马快跑的博客 931

Android中ViewPager和PagerAdapter的简单使用

需求 使用ViewPager和PagerAdapter简单的做一个当前界面横向滑动可以切换图片的功能。 布局 activity.xml布局文件只要加入ViewPager和TextView控件即可 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_pa

geniushorse的博客 1619

Android --- PagerAdapter的使用方法详细讲解,面试经历分享

我坚信,坚持学习,每天进步一点,滴水穿石,我们离成功都很近!以下是总结出来的字节经典面试题目,包含:计算机网络,Kotlin,数据结构与算法,Framework源码,微信小程序,NDK音视频开发,计算机网络等。字节高级Android经典面试题和答案本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

ccc6553584的博客 1517

安卓开发之关于如何用viewPager实现三种不同效果的轮播图

还是因为课程设计的缘故,想美化一下界面就想着实现一个轮播图。本文展示了三种效果的轮播图供大家交流,话不多说,直接上代码。

w17319185551的博客 1569

Android:万能框架——universal-image-loader——ViewPager异步加载图片

import android.graphics.Bitmap; import android.os.Bundle; import android.os.Parcelable; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.view.Layou

1714

轮播图-------------PagerAdapter适配器

//此集合为网络获取集合 List list; //传送上下文 Context ctx; public Mybase(List list, Context ctx, Handler handler) { this.list = list; this.ctx = ctx; } //此方法为可无限轮播的长度 @Override public int getCount() {

Mrzhaoplus的博客 363

高级控件——翻页类视图——翻页视图ViewPager

================================================================================ 页面布局: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="matc...

小白龙白龙马的博客 403

ViewPager与PagerAdapter实现图片左右滑动效果

PagerAdapter主要是viewpager的适配器,该适配器能填充页面内容到ViewPager中。它也是android.support.v4包中的类,PagerAdapter需要重写四个方法public int getCount() { return this.views.size(); } /**初始化position界面*/ @Override public Object i...

leng15183596537的博客 1845
上一篇: JavaScript初学者最容易犯的错误(一)
下一篇: 正确的在GridView中使用Bitmap图像
凄凄迷人
博客等级 码龄21年 58粉丝 58原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值