一种利用ImageView做轮播的尝试Demo2_逐步完善

      其实就是把文章《一种利用ImageView做轮播的尝试Demo》中的代码加上可以添加照片列表实现了图片轮播,而且只要轮播速度不是很快,我这个控件可以确保不会有图片残留出来的内存泄漏,都是加载一张过完之后再释放一张。做这个系列的目的是想试试在不看别人的代码的情况下自己空闲下实现的控件可以到什么程度。

     GalleryView的最新代码如下:

     

package com.project.views;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by cjz on 2019/4/3.
 * 图片轮播View
 */

public class GalleryView extends FrameLayout {
    /**未来扩充为可以添加图片做轮播预留的数组表**/
    private List<String> photoList = new ArrayList<>();
    /**两个ImageView做轮播**/
    private ImageView imageViewA, imageViewB;
    /**宏:触发滑动**/
    private final int IMAGEVIEW_SWEEP = 0;
    /**是否保持轮播**/
    private boolean run = true;
    /**轮播线程**/
    private Loop loop = null;

    /**轮播线程**/
    private class Loop extends Thread {
        @Override
        public void run() {
            super.run();
            while(run){
                try {
                    Thread.sleep(80);
                    handler.sendEmptyMessage(IMAGEVIEW_SWEEP);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            loop = null;
        }
    }

    /**间接操作UI,匿名内部类覆盖重写一下就够用**/
    private class UIHandler extends Handler {
        private ImageView currentImageView = null;
        /**每次步进的像素量**/
        private int step = 10;
        /**选择了哪张图作为当前轮播图**/
        public int picIndex = 0;
        /**当前使用的位图**/
        public Bitmap currentBitmapYoung = null,
                currentBitmapOld = null;

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case IMAGEVIEW_SWEEP:
                    if(photoList == null || photoList.isEmpty()){
                        return;
                    }
                    if(currentImageView == null){
                        currentImageView = imageViewA;
                    }
                    /*A、B首尾相连,首尾在到达左边框后互为交换*/
                    if(currentImageView != null){
                        if(currentImageView.getX() + currentImageView.getWidth() <= 0){
//                            Log.i("picIndex", picIndex + "");
                            //移到屏幕外部ImageView的位图清理掉
                            if(currentBitmapOld != null){
                                currentBitmapOld.recycle();
                            }
                            //正在显示的图设为旧图
                            currentBitmapOld = currentBitmapYoung;
                            //加载新的图
                            currentBitmapYoung = BitmapFactory.decodeFile(photoList.get(picIndex));

                            if(currentImageView == imageViewA){
                                currentImageView = imageViewB;
                                currentImageView.setX(0);
                                //被移除左边框的ImageView移动到右侧,和左侧还没出去ImageView尾部相接
                                imageViewA.setX(currentImageView.getX() + currentImageView.getWidth());
//                                Log.i("使用","使用ImageViewB");
                                //右侧即将进入的ImageView加载最新的图
                                imageViewA.setImageBitmap(currentBitmapYoung);
                            } else {
                                currentImageView = imageViewA;
                                currentImageView.setX(0);
                                //被移除左边框的ImageView移动到右侧,和左侧还没出去ImageView尾部相接
                                imageViewB.setX(currentImageView.getX() + currentImageView.getWidth());
//                                Log.i("使用","使用ImageViewA");
                                //右侧即将进入的ImageView加载最新的图
                                imageViewB.setImageBitmap(currentBitmapYoung);
                            }
                            //图片轮选
                            picIndex ++;
                            if(picIndex >= photoList.size()){
                                picIndex = 0;
                            }
                        }
                        imageViewA.setX(imageViewA.getX() - step);
                        imageViewB.setX(imageViewB.getX() - step);
                    }
                    break;
            }
        }
    }
    private UIHandler handler = new UIHandler();

    public GalleryView(Context context) {
        super(context);
        init(context);
    }

    public GalleryView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public GalleryView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //需要等View的大小都在onMeasure中确定完毕,才能getWidth等,不然在构造函数那里就调用getWidth根本测不出宽度等数据
        //两个ImageView首尾相接
        imageViewA.setX(0);
        imageViewB.setX(imageViewA.getX() + imageViewA.getWidth());
        startLoop();
        //检测本控件的依附情况
        this.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {

            //重新被依附就启动轮播线程
            @Override
            public void onViewAttachedToWindow(View v) {
                run = true;
                startLoop();
            }

            //脱离依附则关闭循环线程
            @Override
            public void onViewDetachedFromWindow(View v) {
                run = false;
                if(loop != null && loop.isAlive()){
                    try {
                        loop.interrupt();
                    } catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    /**轮播触发**/
    private void startLoop(){
        //初始化第一批图片
        if(photoList.size() == 1){
            handler.picIndex = 0;
            handler.currentBitmapYoung = BitmapFactory.decodeFile(photoList.get(0));
            handler.currentBitmapOld = BitmapFactory.decodeFile(photoList.get(0));
            imageViewA.setImageBitmap(handler.currentBitmapOld);
            imageViewB.setImageBitmap(handler.currentBitmapYoung);
        } else if(photoList.size() >= 2){
            handler.picIndex = 0;
            handler.currentBitmapYoung = BitmapFactory.decodeFile(photoList.get(1));
            handler.currentBitmapOld = BitmapFactory.decodeFile(photoList.get(0));
            imageViewA.setImageBitmap(handler.currentBitmapOld);
            imageViewB.setImageBitmap(handler.currentBitmapYoung);
        }
        //初始化循环
        if(loop == null){
            loop = new Loop();
        }
        if(!loop.isAlive()) {
            loop.start();
        }
    }

    /**初始化,加载图像等等**/
    private void init(Context context){
        imageViewA = new ImageView(context);
        imageViewB = new ImageView(context);
        imageViewA.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        imageViewB.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        //imageViewA.setImageResource(R.mipmap.ic_launcher);
        //imageViewB.setImageResource(R.mipmap.ic_launcher_round);
        this.addView(imageViewA);
        this.addView(imageViewB);
    }


    public void addPhoto(String filePath){
        if(filePath != null){
            photoList.add(filePath);
        }
    }

    public void addPhoto(List<String> filePaths){
        if(filePaths != null) {
            photoList.addAll(filePaths);
        }
    }

    public void addPhoto(File[] files){
        if(files != null){
            for(File item : files){
                photoList.add(item.getAbsolutePath());
//                Log.i("addPhoto", item.getAbsolutePath());
            }
        }
    }


}

      

使用方法:

1、在Layout文件中嵌入:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/fl_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="cjz.project.viewgallery.MainActivity">

    <cjz.project.viewgallery.GalleryView
        android:id="@+id/gv"
        android:layout_width="match_parent"
        android:layout_height="300dp">

    </cjz.project.viewgallery.GalleryView>
</FrameLayout>

 

2、给对象导入要轮播的图片路径地址:

package cjz.project.viewgallery;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;

import java.io.File;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        GalleryView gv = findViewById(R.id.gv);
        File file = new File(Environment.getExternalStorageDirectory() + "/Movies/ADPagePhoto");
        File[] files = file.listFiles();
        gv.addPhoto(files);
    }
}

 

我弄在了一个广告机页面上进行测试,上面图片缓慢轮播,下面播视频,效果不错而且占用内存量很低(因为没做任何缓存,而且立即释放,本就打算用在内存很小很小的安卓板上,代码效率反而不要紧,内存要精打细算)。

效果如下,图片严重压缩:

 

PS:其实同样的思路,也可以加上触摸事件,做个自己的ViewPager来玩,例如做个轮播切页机制,快要加载新页面的时候,回调用户的接口实现对象,让用户自己填空输入要换页时显示的对应View。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值