一種利用ImageView做輪播的嘗試Demo

輪播插件GitHub什麼的很多,很多都是用ViewPager來做的。但是我想試試ImageView或者OpenGL來做試試,今天想使用ImageView加X軸的移動來做了一個試試水,下次再用OpenGL做個高性能的的:

 

首先是View文件,做法是使用切牌的方式輪播兩張ImageView產生輪播效果,當然大家也可以加一點點東西改成列表圖片。一些關於自定義控件的設計思路可以參考源代碼中的註釋:

package cjz.project.viewgallery;

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

import java.util.ArrayList;
import java.util.List;

/**
 * Created by cjz on 2019/4/3.
 */

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(3);
                    handler.sendEmptyMessage(IMAGEVIEW_SWEEP);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            loop = null;
        }
    }

    /**間接操作UI,匿名內部類覆蓋重寫一下就夠用**/
    private Handler handler = new Handler(){
        private ImageView currentImageView = null;
        private int step = 10;
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case IMAGEVIEW_SWEEP:
                    if(currentImageView == null){
                        currentImageView = imageViewA;
                    }
                    /*A、B首尾相連,首尾在到達左邊框後互爲交換*/
                    if(currentImageView != null){
                        if(currentImageView.getX() + currentImageView.getWidth() <= 0){
                            if(currentImageView == imageViewA){
                                currentImageView = imageViewB;
                                currentImageView.setX(0);
                                imageViewA.setX(currentImageView.getX() + currentImageView.getWidth());
                                //Log.i("使用","使用ImageViewB");
                            } else {
                                currentImageView = imageViewA;
                                currentImageView.setX(0);
                                imageViewB.setX(currentImageView.getX() + currentImageView.getWidth());
                                //Log.i("使用","使用ImageViewA");
                            }
                        }
                        imageViewA.setX(imageViewA.getX() - step);
                        imageViewB.setX(imageViewB.getX() - step);
                    }
                    break;
            }
        }
    };

    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(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);
        }
    }


}

然後是調用時的XML文件,大小是可以調節的。

<?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:layout_width="match_parent"
        android:layout_height="match_parent">

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

 

效果如圖:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章