Android开发 之 图片浏览

本文详述了如何在Android应用中实现高效图片浏览,包括使用RecyclerView展示小图,自定义GridlayoutManager调整滑动速度,利用Bitmap和LruCache进行内存缓存,以及在大图浏览时实现平滑的页面切换和内存管理。通过监听触摸事件和自定义Adapter,确保图片加载的流畅性和性能优化。
摘要由CSDN通过智能技术生成

1.简介

图片浏览在app中是很常见的,本文使用android的recyclerView ,viewPager, Bitmap,等一系列组件开发的一个浏览器;

实现大图无损加载,大图压缩成小图浏览;

2.开发要点:

使用recycleview显示小图浏览,使用自定义的GridlayoutManager,设置了滑动速度;

    @Override
    public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
        int a = super.scrollVerticallyBy((int)(speedRatio*dy), recycler, state);//屏蔽之后无滑动效果,证明滑动的效果就是由这个函数实现
        if(a == (int)(speedRatio*dy)){
            //Log.e("speed",dy+"---"+a);
            return dy;
        }
        return a;
    }

    /**
     * 设置滑动速度因子;
     * @param speedRatio
     */
    public void setSpeedRatio(float speedRatio){
        this.speedRatio = speedRatio;
    }

上面的dy就是滑动速度实时变化值,通过滑动因子改变它;监听recycleView的onTouchListener,返回false不拦截事件,继续想上层传递;

这里做到了不抬起手的时候滑动速度不变,当抬起手指的时候滑动因为为原来速度的0.3倍;

为什么要设置滑动速度?因为速度太快的话,突然滑到底部的时候,图片加载很慢的话会卡顿;

        recycleview.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                if(motionEvent.getAction()==MotionEvent.ACTION_UP)
                {
                    myGridLayoutManager.setSpeedRatio(0.3f);
                }else{
                    myGridLayoutManager.setSpeedRatio(1f);
                }
                return false;
            }
        });



数据:使用相册的mediastota数据库中保存的图片路径; 通过内容解析者去获取,存到一个list中,刷新adapter显示数据;

        Cursor cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, null);

        while (cursor.moveToNext())
        {
            int index = cursor
                    .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            String path = cursor.getString(index); // 文件地址
            //Log.e("address",path);
            list.add(path);
        }
        pictureAdapter.notifyDataSetChanged();


至于适配器中的优化是recycleView的适配器这里不多讲;直接看代码:

    public class PictureAdapter extends RecyclerView.Adapter
    {
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            ImageView inflate = (ImageView) LayoutInflater.from(MainActivity.this).inflate(R.layout.item_picture, parent,false);
            inflate.setLayoutParams(new RecyclerView.LayoutParams(bianchang,bianchang));
            return new MyViewHolder(inflate);
        }

        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            MyViewHolder myViewHolder= (MyViewHolder) holder;
            myViewHolder.setData(position);
        }

        @Override
        public int getItemCount() {
            return list.size();
        }
    }
    public class MyViewHolder extends RecyclerView.ViewHolder
    {

        private ImageView imageView;
        private String picturePath;
        private int position;

        public MyViewHolder(View itemView) {
            super(itemView);
            imageView = itemView.findViewById(R.id.iv);
            imageView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    float x = imageView.getX();
                    float y = imageView.getY();
                    Bundle bundle=new Bundle();
                    bundle.putFloat("x",x);
                    bundle.putFloat("y",y);
                    scroolPosition = position;
                    bundle.putInt("position",position);
                    bundle.putString("picturepath",picturePath);
                    Intent intent = new Intent(MainActivity.this, PictureInfoActivity.class);
                    intent.putExtra("positon",bundle);
                    startActivity(intent);
                    overridePendingTransition(0,0);
                }
            });
        }

        public void setData(final int data) {
            imageView.setImageBitmap(null);
            position = data;
            picturePath = list.get(data);
            LoadPictureUtils.loadPicture(bianchang,picturePath,imageView);
        }
    }

上面的代码中,加载图片使用线程池异步加载图片,而且进行缩放成360*360的尺寸;所以这里要进行大量的计算必须放在子线程中;线程中执行的是Runable类对象的任务;所以我们要继承runable类,重写run方法:下面有一个复用bitmap技术,从一个set集合中取出可以复用的bitmap对象,这个set是当bitmap缓存LruCache中移除多余的bitmap放到set中的,使用的是弱引用的bitmap;

当图片

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值