欢迎访问:[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
分享到:
相关推荐
本文将深入探讨如何基于ImageView实现一个“高仿微信图片放大拖动浏览”的功能,包括支持双击缩放以及在ViewPager中嵌套使用。 首先,我们需要创建一个新的自定义控件,命名为XlhZoomImageView,它继承自Android...
在处理大量图片时,我们需要谨慎使用Bitmap,避免内存泄漏和oom问题,可能需要使用到Bitmap的配置和复用策略。 6. **动画效果**:为了提升用户体验,源码可能会包含一些过渡动画,如淡入淡出、平移等。这些可以通过...
因此,我们需要确保图片在各种设备上都能正确显示,这可能涉及到布局适配和尺寸单位的使用。 总的来说,Andriod图片查看案例涵盖了Android开发中的图片加载、显示、手势识别、内存管理和用户体验优化等多个方面,...
在图片阅读器V1.2中,考虑到图片可能会占用大量内存,开发者可能采用了内存优化策略,如使用Bitmap的高效加载和复用机制,以及及时回收不再使用的Bitmap对象,防止内存泄漏。此外,可能还利用了软引用和弱引用等内存...
在Android开发中,`Gallery`组件是用于展示图像的一个旧版控件,它允许用户以横向滑动的方式浏览多张图片。然而,由于性能和功能的限制,`Gallery`已经在API 16(Android 4.1)之后被废弃,取而代之的是更现代的`...
高斯模糊是图像处理中常见的滤波技术,它通过模拟高斯函数对图像进行平滑处理,可以降低图像中的噪声,同时保留边缘信息。在Android中,我们可以通过Java或Kotlin来实现这一效果。 高斯模糊主要涉及到以下几个关键...
3. **GestureDetector与ScaleGestureDetector**:在Android中,为了处理用户的触摸事件,通常会使用GestureDetector来识别滑动、点击等基本手势,而ScaleGestureDetector则可以识别缩放手势。这些类可以帮助我们监听...
在这个项目中,ViewPager用于展示图片,允许用户左右滑动切换不同的图片,提供了平滑的过渡效果和高效的内存管理。 2. **图片加载库**:在Android应用开发中,处理图片加载和缓存是非常常见且重要的任务。由于项目...
在这个项目中,ViewPager可能被用来展示一系列图片,并且在切换图片时保持手势操作的连贯性。 3. **自定义ImageView**: - **SimpleTouchImageView**:这个名称可能表示项目中自定义了一个ImageView子类,以支持更...
3. **PageTransformer**:在Android的ViewPager组件中,可以使用PageTransformer接口来自定义页面滑动时的变换效果。通过重写`transformPage()`方法,可以控制每个页面在滑动过程中的视觉变化,实现翻页效果。 4. *...
在Android开发中,图片的展示是非常重要的一环,特别是在当今移动应用中,动态图像是吸引用户注意力和增强用户体验的有效手段。本资料包“android gif模式和图片展现模式 图片展现神器.zip”显然聚焦于如何在Android...
在使用微信 SDK 分享图片的过程中,发现图片过大会导致微信拉起失败。为了解决这个问题,我们可以将图片压缩至原来的一半,以减少图片占用内存。压缩图片可以使用 Matrix 对象的 setScale 方法将图片缩放到原来的...
此外,还要考虑性能优化,如使用异步处理避免UI卡顿,以及权限管理,确保应用在请求访问相册或相机等敏感资源时有正确的权限。 总结起来,微信风格的图片上传功能在Android中实现涉及到多个环节,包括图片选择、...
同时,`Canvas`用于绘制页面,通过`drawBitmap()`或`drawRect()`等方法在画布上绘制页面图像。 4. **透视效果**: 真实的翻页效果需要考虑到透视,即离观察者近的页面部分看起来更大。可以通过调整Matrix中的透视...
- 使用模拟位置进行测试:了解如何在开发过程中使用模拟位置进行测试。 #### 七、Android可穿戴应用 - **赋予Notification可穿戴特性** - 创建Notification:学习如何创建适应于可穿戴设备的Notification。 - ...
Android系统提供了丰富的API来处理图像,例如Bitmap类用于加载和显示图片,ImageView则是展示图片的主要组件。在实际开发中,我们通常会结合使用这两个核心元素。然而,直接加载大图可能会导致内存溢出(OOM),因此...
因此,源码可能包含了Bitmap的优化策略,如使用inSampleSize减小图片大小,或者使用LruCache进行内存缓存。 7. **数据持久化**: 如果相册有收藏或者排序功能,那么数据持久化是必要的。除了SQLite,还可以使用...
- **使用模拟位置进行测试:** 在开发过程中使用模拟位置进行测试。 #### 七、Android可穿戴应用 **1. 赋予Notification可穿戴特性** - **创建Notification:** 在可穿戴设备上创建通知。 - **在Notification中...
在早期版本的Android SDK中,有一个叫做Gallery的视图类,但在后来的版本中被废弃,取而代之的是更现代、功能更强大的RecyclerView或ViewPager等组件。因此,这个项目可能展示了如何利用这些新组件来实现类似的功能...
使用`RelativeLayout`或`LinearLayout`来组合这些元素,并确保布局能在不同屏幕尺寸下正确显示。 5. **触摸事件处理**:为了实现滑动浏览图片,我们需要监听用户的触摸事件,处理滑动、缩放和旋转手势。可以重写`...