常用自定义控件

常用自定义控件

  1. 仿QQ控件的头部拉伸Listview

    没有增加放大效果

package com.hu.glmenu.wight;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.ImageView;
import android.widget.ListView;

import com.hu.glmenu.R;

/**
 * Created by TT on 2017/5/25.
 */

public class QqListView extends ListView {

    private int mImageViewHeigth;
    private ImageView mIv;

    public QqListView(Context context) {
        this(context, null);
    }

    public QqListView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public QqListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mImageViewHeigth = context.getResources().getDimensionPixelOffset(R.dimen.head_img_defualt_size_dp);
    }

    //在添加头布局时候,随便找到 ImageView 并传递过来
    public void setImageBig(ImageView iv) {
        if(iv==null){
            Log.e("TAG","夭寿了,iv为空");
        }else{
            mIv = iv;
        }

    }

    //重写overscrllBy

    /**
     * 当滑动的超出上,下,左,右最大范围时回调
     *
     * @param deltaX         x方向的瞬时偏移量,左边到头,向右拉为负,右边到头,向左拉为正
     * @param deltaY         y方向的瞬时偏移量,顶部到头,向下拉为负,底部到头,向上拉为正
     * @param scrollX        水平方向的永久偏移量
     * @param scrollY        竖直方向的永久偏移量
     * @param scrollRangeX   水平方向滑动的范围
     * @param scrollRangeY   竖直方向滑动的范围
     * @param maxOverScrollX 水平方向最大滑动范围
     * @param maxOverScrollY 竖直方向最大滑动范围
     * @param isTouchEvent   是否是手指触摸滑动, true为手指, false为惯性
     * @return
     */
    @Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX,
                                   int scrollY, int scrollRangeX, int scrollRangeY,
                                   int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
        //当下拉的时候
        if (deltaY < 0) {
//这里将图片的高度变大  为什么deltaY要除2呢? 是因为防止用户从头拉到底部 图片高度过大不好看,可以自己设定
            mIv.getLayoutParams().height = mIv.getHeight() - deltaY / 2;
            //requestLayout()方法会触发measure过程和layout过程,不会调用draw过程,也不会重新绘制任何View包括该调用者本身
            //这个方法一定要调用,他会重新放置位置
            mIv.requestLayout();
        } else {
//这里的代码是当你上滑的时候缩放图片的
            if (mIv.getHeight() > mImageViewHeigth) {
                mIv.getLayoutParams().height = mIv.getHeight() + deltaY / 2;
                mIv.requestLayout();
            }
        }


        return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        //让Imageview上滑时放大监听

        View head = (View) mIv.getParent();
        //拿到父容器与顶部的高度
        if (head.getTop() < 0 && mIv.getHeight() > mImageViewHeigth) {
            mIv.getLayoutParams().height = mIv.getHeight() + head.getTop();
            head.layout(head.getLeft(), 0, head.getRight(), head.getHeight());
            mIv.requestLayout();
        }
        super.onScrollChanged(l, t, oldl, oldt);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_UP:
                ResetAnimation animation = new ResetAnimation(mIv, mImageViewHeigth);
                animation.setDuration(300);
                mIv.startAnimation(animation);

                break;
        }

        return super.onTouchEvent(ev);
    }

    class ResetAnimation extends Animation {

        private ImageView iv;
        private int targetHeigth; //最终恢复的高度
        private final int height;
        private final int endHeigth;

        public ResetAnimation(ImageView iv, int targetHeigth) {
            this.iv = iv;
            this.targetHeigth = targetHeigth;
            this.height = mIv.getHeight();
            this.endHeigth = height - targetHeigth;
        }

        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            //不断调用
            mIv.getLayoutParams().height = (int) (height - endHeigth * interpolatedTime);
            mIv.requestLayout();
            super.applyTransformation(interpolatedTime, t);
        }
    }
}

效果也就这样吧
2. 一个loading动画

package com.hu.glmenu.wight;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.CornerPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.PorterDuffXfermode;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;

/**
 * 仿守望先锋的loading加载
 * Created by zhangyu on 2016/11/28.
 */

public class OWLoadingView extends SurfaceView {
    private static final String TAG = "OWLoadingView";
    //view的宽度和高度
    private int viewWidth, viewHeight;
    //view的中心点
    private Point center = new Point();
    //六边形的中心点
    private Point[] hexagonCenters = new Point[6];
    //六边形实例
    private Hexagon[] hexagons = new Hexagon[7];
    //六边形之间的间距
    private float space;
    //六边形的半径
    private float hexagonRadius;
    private int color = Color.parseColor("#ff9900");//默认橙色
    private Paint paint;
    private float sin30 = (float) Math.sin(30f * 2f * Math.PI / 360f);
    private float cos30 = (float) Math.cos(30f * 2f * Math.PI / 360f);
    //进行显示动画和进行隐藏动画的标志常量
    private final int ShowAnimatorFlag = 0x1137, HideAnimatorFlag = 0x1139;
    private int nowAnimatorFlag = ShowAnimatorFlag;
    //触发下一个动画开始的缩放临界点值
    private final float scaleCritical = 0.7f;
    //控制动画运行的标示位
    private boolean runAnim = false;
    private SurfaceHolder surfaceHolder;
    //基准数据是否已初始化
    private boolean baseDataInited = false;
    //是否自动开始动画
    private boolean autoStartAnim = false;

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

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

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

    }

    private void init() {
        surfaceHolder = getHolder();
        setZOrderOnTop(true);
        surfaceHolder.setFormat(PixelFormat.TRANSLUCENT);//背景透明
        initPaint();
    }

    /**
     * 绘制图案
     */
    private void draw() {
        Canvas canvas = surfaceHolder.lockCanvas();
        if(canvas == null)
            return;
        paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.CLEAR));
        canvas.drawPaint(paint);
        paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.DST_OVER));

        for (int i = 0; i < 7; i++) {
            hexagons[i].drawHexagon(canvas, paint);
        }
        surfaceHolder.unlockCanvasAndPost(canvas);
    }

    private Runnable animRunnable = new Runnable() {
        @Override
        public void run() {
            try {
                while (runAnim) {
                    Thread.sleep(2);
                    flush();
                    draw();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };

    //重置六边形数据
    private void resetHexagons() {
        for (int i = 0; i < hexagons.length; i++) {
            hexagons[i].setScale(0);
            hexagons[i].setAlpha(0);
        }
    }

    private void initPaint() {
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(color);
    }

    /**
     * 设置颜色
     *
     * @param color
     */
    public void setColor(int color) {
        this.color = color;
        paint.setColor(color);
    }

    /**
     * 开始动画
     *
     * @return 动画是否启动成功,true 启动成功;false 启动失败
     */
    public boolean startAnim() {
        if (runAnim || !baseDataInited)
            return false;
        runAnim = true;
        new Thread(animRunnable).start();
        setVisibility(View.VISIBLE);
        return true;
    }

    /**
     * 中止动画
     */
    public void stopAnim() {
        runAnim = false;
        nowAnimatorFlag = ShowAnimatorFlag;
        resetHexagons();
        draw();
        setVisibility(View.GONE);
    }

    /**
     * 设置初始化完成后是否自动开始动画。
     * 如果开启,建议在页面onStop()时调用{@link #stopAnim}()方法中止动画,节约内存开销
     * @param autoStartAnim
     */
    public void setAutoStartAnim(boolean autoStartAnim) {
        this.autoStartAnim = autoStartAnim;
    }

    /**
     * 初始化六边形中心店坐标
     */
    private void initHexagonCenters() {
        //1.5*r 加上竖直方向space 等于R*cos30(博客里画的图是不匹配的)
        float bigR = (float) ((1.5 * hexagonRadius + space) / cos30);
        hexagonCenters[0] = new Point(center.x - bigR * sin30, center.y - bigR * cos30);
        hexagonCenters[1] = new Point(center.x + bigR * sin30, center.y - bigR * cos30);
        hexagonCenters[2] = new Point(center.x + bigR, center.y);
        hexagonCenters[3] = new Point(center.x + bigR * sin30, center.y + bigR * cos30);
        hexagonCenters[4] = new Point(center.x - bigR * sin30, center.y + bigR * cos30);
        hexagonCenters[5] = new Point(center.x - bigR, center.y);

        for (int i = 0; i < 6; i++) {
            hexagons[i] = new Hexagon(hexagonCenters[i], hexagonRadius);
        }
        hexagons[6] = new Hexagon(center, hexagonRadius);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        viewHeight = getMeasuredHeight();
        viewWidth = getMeasuredWidth();
        if (viewWidth != 0 && viewHeight != 0) {
            center.x = viewWidth / 2f;
            center.y = viewHeight / 2f;
            float spaceRate = 1 / 100f;
            space = viewWidth <= viewHeight ? viewWidth * spaceRate : viewHeight * spaceRate;
            hexagonRadius = (float) ((viewWidth - 2 * space) / (3 * Math.sqrt(3)));
            initHexagonCenters();
            //圆角处理
            paint.setPathEffect(new CornerPathEffect(hexagonRadius * 0.1f));
            baseDataInited = true;
        }
    }

    /**
     * 刷新数据
     */
    private void flush() {
        if (nowAnimatorFlag == ShowAnimatorFlag) {//逐个显示出来
            hexagons[0].addScale();
            hexagons[0].addAlpha();
            for (int i = 0; i < hexagons.length - 1; i++) {
                if (hexagons[i].getScale() >= scaleCritical) {
                    hexagons[i + 1].addScale();
                    hexagons[i + 1].addAlpha();
                }
            }

            if (hexagons[6].getScale() == 1) {//当最后一个六边形都完全显示时,切换模式,下一轮逐个消失
                nowAnimatorFlag = HideAnimatorFlag;
            }

        } else {//逐个消失
            hexagons[0].subScale();
            hexagons[0].subAlpha();
            for (int i = 0; i < hexagons.length - 1; i++) {
                if (hexagons[i].getScale() <= 1 - scaleCritical) {
                    hexagons[i + 1].subScale();
                    hexagons[i + 1].subAlpha();
                }
            }
            if (hexagons[6].getScale() == 0) {//当最后一个六边形都完全消失时,切换模式,下一轮逐个开始显示
                nowAnimatorFlag = ShowAnimatorFlag;
            }
        }
    }

    /**
     * 六边形
     */
    private class Hexagon {

        //缩放值
        private float scale = 0;
        //透明度
        private int alpha = 0;
        public Point centerPoint;
        public float radius;
        //六个顶点
        private Point[] vertexs = new Point[6];
        //缩放程度每次改变量 变化范围为[0,1]
        private final float scaleChange = 0.07f;
        //透明度每次改变量 变化范围为[0,255]
        private final int alpahChange = 18;

        public Hexagon(Point centerPoint, float radius) {
            this.centerPoint = centerPoint;
            this.radius = radius;
            calculatePointsPosition();
        }

        public void drawHexagon(Canvas canvas, Paint paint) {
            paint.setAlpha(alpha);
            canvas.drawPath(getPath(), paint);
        }

        private int calculatePointsPosition() {
            if (centerPoint == null) {
                return -1;
            }
            //从最上方顺时针数1-6给各顶点标序号 共6个点
            vertexs[0] = new Point(centerPoint.x, centerPoint.y - radius * scale);
            vertexs[1] = new Point(centerPoint.x + radius * cos30 * scale, centerPoint.y - radius * sin30 * scale);
            vertexs[2] = new Point(centerPoint.x + radius * cos30 * scale, centerPoint.y + radius * sin30 * scale);
            vertexs[3] = new Point(centerPoint.x, centerPoint.y + radius * scale);
            vertexs[4] = new Point(centerPoint.x - radius * cos30 * scale, centerPoint.y + radius * sin30 * scale);
            vertexs[5] = new Point(centerPoint.x - radius * cos30 * scale, centerPoint.y - radius * sin30 * scale);
            return 1;
        }


        private Path getPath() {
            Path path = new Path();
            for (int i = 0; i < 6; i++) {
                if (i == 0)
                    path.moveTo(vertexs[i].x, vertexs[i].y);
                else
                    path.lineTo(vertexs[i].x, vertexs[i].y);
            }
            path.close();
            return path;
        }

        /**
         * 设置透明度
         *
         * @param alpha
         */
        public void setAlpha(int alpha) {
            this.alpha = alpha;
        }

        public int getAlpha() {
            return alpha;
        }


        /**
         * 设置缩放比例
         *
         * @param scale
         */
        public void setScale(float scale) {
            this.scale = scale;
            calculatePointsPosition();
        }

        public void addScale() {
            if (scale == 1)
                return;

            scale += scaleChange;
            scale = scale > 1 ? 1 : scale;
            calculatePointsPosition();
        }

        public void subScale() {
            if (scale == 0) {
                return;
            }
            scale -= scaleChange;
            scale = scale < 0 ? 0 : scale;
            calculatePointsPosition();
        }

        public void addAlpha() {
            if (alpha == 255) {
                return;
            }
            alpha += alpahChange;
            alpha = alpha > 255 ? 255 : alpha;
        }

        public void subAlpha() {
            if (alpha == 0) {
                return;
            }
            alpha -= alpahChange;
            alpha = alpha < 0 ? 0 : alpha;
        }

        /**
         * 获取当前缩放比例
         *
         * @return
         */
        public float getScale() {
            return scale;
        }
    }

    private class Point {
        public float x, y;

        public Point(float x, float y) {
            this.x = x;
            this.y = y;
        }

        public Point() {
        }
    }

    @Override
    public void onWindowFocusChanged(boolean hasWindowFocus) {
        super.onWindowFocusChanged(hasWindowFocus);
        Log.d(TAG,"onWindowFocusChanged  "+hasWindowFocus);
        if(hasWindowFocus && autoStartAnim){
            startAnim();
        }
    }

}

直接在布局中添加view就行了,对外属性:

setColor(int color) 设置颜色

startAnim()开始动画

stopAnim() 停止动画

  1. 一个viewpager的轮播图
package com.hu.test.wight;

import android.content.Context;
import android.os.Handler;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.facebook.drawee.view.SimpleDraweeView;
import com.hu.test.R;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 广告图片自动轮播控件</br>
 * <p/>
 * <pre>
 *   集合ViewPager和指示器的一个轮播控件,主要用于一般常见的广告图片轮播,具有自动轮播和手动轮播功能
 *   使用:只需在xml文件中使用{@code <com.ehan.com.ehan.hmwis.view.ImageCycleView/>} ,
 *   然后在页面中调用  {@link #( ArrayList , ImageCycleViewListener) }即可!
 *
 *   另外提供{@link #startImageCycle() } \ {@link #pushImageCycle() }两种方法,用于在Activity不可见之时节省资源;
 *   因为自动轮播需要进行控制,有利于内存管理
 * </pre>
 *
 * @author minking
 */
public class ImageCycleView extends LinearLayout {

    /**
     * 上下文
     */
    private Context mContext;

    /**
     * 图片轮播视图
     */
    private ViewPager mAdvPager = null;

    /**
     * 滚动图片视图适配器
     */
    private ImageCycleAdapter mAdvAdapter;

    /**
     * 图片轮播指示器控件
     */
    private ViewGroup mGroup;

    /**
     * 图片轮播指示器-个图
     */
    private ImageView mImageView = null;

    /**
     * 滚动图片指示器-视图列表
     */
    private ImageView[] mImageViews = null;

    /**
     * 图片滚动当前图片下标
     */
    private int mImageIndex = 0;

    /**
     * 手机密度
     */
    private float mScale;

    private AtomicInteger what = new AtomicInteger(4000);

    private ViewGroup.LayoutParams params;

    /**
     * @param context
     */
    public ImageCycleView(Context context) {
        super(context);
    }

    /**
     * @param context
     * @param attrs
     */
    public ImageCycleView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        mScale = context.getResources().getDisplayMetrics().density;
        LayoutInflater.from(context).inflate(R.layout.ad_cycle_view, this);
        mAdvPager = (ViewPager) findViewById(R.id.adv_pager);
        mAdvPager.setOnPageChangeListener(new GuidePageChangeListener());
        mAdvPager.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_UP:
                        // 开始图片滚动
                        startImageTimerTask();
                        break;
                    default:
                        // 停止图片滚动
                        stopImageTimerTask();
                        break;
                }
                return false;
            }
        });
        // 滚动图片右下指示器视图
        mGroup = (ViewGroup) findViewById(R.id.viewGroup);
    }


    /**
     * 装填图片数据
     *
     * @param imageUrlList
     * @param imageCycleViewListener
     */
//  android.view.ViewGroup.LayoutParams params1;
//  params1 = home_viewpager.getLayoutParams();
//  params1.width = Utils.getScreenWidth(getActivity());
//  params1.height = (int) (params1.width / 2.3);
//  home_viewpager.setLayoutParams(params1);
    public void setImageResources(List<String> imageUrlList, ImageCycleViewListener imageCycleViewListener) {
        // 清除所有子视图
        mGroup.removeAllViews();
        // 图片广告数量
        final int imageCount = imageUrlList.size();
        mImageViews = new ImageView[imageCount];


        for (int i = 0; i < imageCount; i++) {
            mImageView = new ImageView(mContext);
//          int imageParams = (int) (mScale * 20 + 0.5f);// XP与DP转换,适应不同分辨率
            int imagePadding = (int) (mScale * 3 + 0.5f);
            int iconWidth = (int) (mScale * 12 + 0.5f);
            mImageView.setLayoutParams(new LayoutParams(iconWidth, LayoutParams.WRAP_CONTENT));
//          params=mImageView.getLayoutParams();
//          params.width=30;
//          params.height=params.width;
//          mImageView.setLayoutParams(params);
            mImageView.setPadding(imagePadding, 0, 0, 0);

            mImageViews[i] = mImageView;
            if (i == 0) {
                mImageViews[i].setImageResource(R.mipmap.lunboyuan);
            } else {
                mImageViews[i].setImageResource(R.mipmap.lunboyuan_nor);
            }
            mGroup.addView(mImageViews[i]);
        }
        mAdvAdapter = new ImageCycleAdapter(mContext, imageUrlList, imageCycleViewListener);
        mAdvPager.setAdapter(mAdvAdapter);
        startImageTimerTask();
    }

    /**
     * 开始轮播(手动控制自动轮播与否,便于资源控制)
     */
    public void startImageCycle() {
        startImageTimerTask();
    }

    /**
     * 暂停轮播——用于节省资源
     */
    public void pushImageCycle() {
        stopImageTimerTask();
    }

    /**
     * 开始图片滚动任务
     */
    private void startImageTimerTask() {
        stopImageTimerTask();
        // 图片每3秒滚动一次
        mHandler.postDelayed(mImageTimerTask, 3000);

    }

    /**
     * 停止图片滚动任务
     */
    private void stopImageTimerTask() {
        mHandler.removeCallbacks(mImageTimerTask);
    }

    private Handler mHandler = new Handler();

    /**
     * 图片自动轮播Task
     */
    private Runnable mImageTimerTask = new Runnable() {

        @Override
        public void run() {
            if (mImageViews != null) {
                // 下标等于图片列表长度说明已滚动到最后一张图片,重置下标
                if ((++mImageIndex) == mImageViews.length) {
                    mImageIndex = 0;
                }
                mAdvPager.setCurrentItem(mImageIndex);
            }
        }
    };

    /**
     * 轮播图片状态监听器
     *
     * @author minking
     */
    private final class GuidePageChangeListener implements OnPageChangeListener {


        @Override
        public void onPageScrollStateChanged(int state) {
            if (state == ViewPager.SCROLL_STATE_IDLE)
                startImageTimerTask(); // 开始下次计时

        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {

        }

        @Override
        public void onPageSelected(int index) {
            mImageIndex = index;


            for (int i = 0; i < mImageViews.length; i++) {
                mImageViews[index].setImageResource(R.mipmap.lunboyuan);
                if (index != i) {
                    mImageViews[i].setImageResource(R.mipmap.lunboyuan_nor);
                }
            }


        }

    }

    private class ImageCycleAdapter extends PagerAdapter {

        /**
         * 图片视图缓存列表
         */
        private ArrayList<SimpleDraweeView> mImageViewCacheList;

        /**
         * 图片资源列表
         */
        private List<String> mAdList = new ArrayList();

        /**
         * 广告图片点击监听器
         */
        private ImageCycleViewListener mImageCycleViewListener;

        private Context mContext;

        public ImageCycleAdapter(Context context, List<String> adList, ImageCycleViewListener imageCycleViewListener) {
            mContext = context;
            mAdList = adList;
            mImageCycleViewListener = imageCycleViewListener;
            mImageViewCacheList = new ArrayList<SimpleDraweeView>();
        }

        @Override
        public int getCount() {
            return mAdList.size();
        }

        @Override
        public boolean isViewFromObject(View view, Object obj) {
            return view == obj;
        }

        @Override
        public Object instantiateItem(ViewGroup container, final int position) {

            String imageUrl = mAdList.get(position);
            SimpleDraweeView imageView = null;
            if (mImageViewCacheList.isEmpty()) {
                imageView = new SimpleDraweeView(mContext);
                imageView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
                imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);

            } else {
                imageView = mImageViewCacheList.remove(0);
            }
            // 设置图片点击监听
            imageView.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    mImageCycleViewListener.onImageClick(position, v);
                }
            });
            container.addView(imageView);
            mImageCycleViewListener.displayImage(imageUrl, imageView);
            return imageView;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            SimpleDraweeView view = (SimpleDraweeView) object;
            container.removeView(view);
            mImageViewCacheList.add(view);
        }


    }

    /**
     * 轮播控件的监听事件
     *
     * @author minking
     */
    public  interface ImageCycleViewListener {

        /**
         * 加载图片资源
         *
         * @param imageURL
         * @param imageView
         */
       void displayImage(String imageURL, SimpleDraweeView imageView);

        /**
         * 单击图片事件
         *
         * @param position
         * @param imageView
         */
        void onImageClick(int position, View imageView);
    }

}



**通过ViewFlipper实现垂直跑马灯实现:**

public class VMarqueeView extends ViewFlipper {

private Context mContext;
/**
 *翻转时间间隔
 */
private int interval = 2000;
/**
 * 是否设置了动画时间
 */
private boolean isSetAnimDuration = false;

public boolean isSetAutoPlay() {
    return isSetAutoPlay;
}

public void setSetAutoPlay(boolean setAutoPlay) {
    isSetAutoPlay = setAutoPlay;
}

/**
 * 是否设置了自动轮播跑马灯
 */
private boolean isSetAutoPlay = true;

public int getAnimDuration() {
    return animDuration;
}

public void setAnimDuration(int animDuration) {
    this.animDuration = animDuration;
}

/**
 * 设置动画时间,默认为500ms
 */
private int animDuration = 500;

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

private void init(Context context, AttributeSet attrs, int defStyleAttr) {
    this.mContext = context;
    setFlipInterval(interval);
    //是否自动播放
    setAutoStart(isSetAutoPlay);
    Animation animIn = AnimationUtils.loadAnimation(mContext,  R.anim.anim_marquee_in);
    if(isSetAnimDuration){
        animIn.setDuration(animDuration);
    }
    setInAnimation(animIn);

    Animation animOut = AnimationUtils.loadAnimation(mContext, R.anim.anim_marquee_out);
    if(isSetAnimDuration){
        animOut.setDuration(animDuration);
    }
    setOutAnimation(animOut);

}

/**
 * 点击
 */
private OnItemClickListener onItemClickListener;

/**
 * 设置监听接口
 * @param onItemClickListener
 */
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
    this.onItemClickListener = onItemClickListener;
}

/**
 * item_view的接口
 */
public interface OnItemClickListener {
    void onItemClick(int position, View view);
}


/**
 * 由外部设置数据
  * @param views
 */
public void  setViews(final List<View> views){
    if(views == null || views.size() == 0){
        return;
    }
    removeAllViews();
    int length = views.size();
    for (int i = 0; i < length; i++) {
        final int position=i;
        //设置监听回调
        views.get(i).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (onItemClickListener != null) {
                    onItemClickListener.onItemClick(position, views.get(position));
               }
            }
        });

        ViewGroup viewGroup = (ViewGroup) views.get(i).getParent();
        if (viewGroup != null) {
            viewGroup.removeAllViews();
        }
        addView(views.get(i));
    }
    startFlipping();

}

}


设置了点击监听事件

在对于布局的activity中调用如下:
初始化数据
这里设置data的数据就行了
不同泛型可以自己选择
List<String> data = new ArrayList<>();
List<View> views = new ArrayList<>();

初始化View

/**
* 初始化需要循环的View
* 为了灵活的使用滚动的View,所以把滚动的内容让用户自定义
* 假如滚动的是三条或者一条,或者是其他,只需要把对应的布局,和这个方法稍微改改就可以了,
*/
private void setView() {
for (int i = 0; i < data.size(); i = i + 2) {
final int position = i;
//设置滚动的单个布局
LinearLayout moreView = (LinearLayout) LayoutInflater.from(this).inflate(R.layout.item_marquee, null);
//初始化布局的控件
TextView tv1 = (TextView) moreView.findViewById(R.id.tv1);
TextView tv2 = (TextView) moreView.findViewById(R.id.tv2);

        /**
         * 设置监听
         */
        moreView.findViewById(R.id.rl).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(StoreActivity.this, position + "你点击了" + data.get(position).toString(), Toast.LENGTH_SHORT).show();
            }
        });
        /**
         * 设置监听
         */
        moreView.findViewById(R.id.rl2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(StoreActivity.this, position + "你点击了" + data.get(position + 1).toString(), Toast.LENGTH_SHORT).show();
            }
        });
        //进行对控件赋值
        tv1.setText(data.get(i).toString());
        if (data.size() > i + 1) {
            //因为淘宝那儿是两条数据,但是当数据是奇数时就不需要赋值第二个,所以加了一个判断,还应该把第二个布局给隐藏掉
            tv2.setText(data.get(i + 1).toString());
        } else {
            moreView.findViewById(R.id.rl2).setVisibility(View.GONE);
        }

        //添加到循环滚动数组里面去
        views.add(moreView);
    }
}

设置数据:
 upMarqueeView = (UPMarqueeView) holder.itemView.findViewById(R.id.upview);
                setView();//获取数据
                upMarqueeView.setViews(views);//填充数据
                upMarqueeView.setSetAutoPlay(true);//设置是否自动播放
                upMarqueeView.setFocusable(false);//不要获取焦点
                upMarqueeView.setAnimDuration(520);//设置跳跃时间

“`

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值