自定义跑马灯,可以绑定任意布局

package com.biyao.ui;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ViewFlipper;

import java.util.List;

/**
 * 自定义跑马灯,可以绑定任意布局
 * 继承ViewFlipper
 * 动画和间隔可以在xml里设置,也可以在代码中设置 具体看ViewFlipper
 * 传统ViewFlipper是有多少个跑马灯item就需要加载多少个布局,这样浪费内存
 * 这个控件经过改进后,只加载两个布局,通过数据的切换绑定,实现跑马灯效果
 * @param <T>
 */
public class MarqueeView<T> extends ViewFlipper {

    //跑马灯单个布局,需要两个,这样才能转起来
    private View itemView1;
    private View itemView2;
    //跑马灯滚动时绑定数据接口
    private IUpDateItemData<T> iUpDateItemData;
    //跑马灯显示数据
    private List<T> list;
    //标记数据的index
    private int index = 0;
    private Context context;

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

    public MarqueeView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
    }

    /**
     * 通过自定义view作为item绑定数据
     * itemView1和itemView2要是相同类型的两个对象,内存地址要不同
     * @param itemView1
     * @param itemView2
     * @param list
     * @param iUpDateItemData
     */
    public void bind(View itemView1, View itemView2, List<T> list,
                     IUpDateItemData iUpDateItemData){
        bind(itemView1,itemView2,list,iUpDateItemData,null);
    }

    /**
     * 通过自定义view作为item绑定数据,
     * itemView1和itemView2要是相同类型的两个对象,内存地址要不同
     * @param itemView1 item的布局
     * @param itemView2 item的布局
     * @param list
     * @param iUpDateItemData
     * @param onItemClickListener
     */
    public void bind(View itemView1, View itemView2, List<T> list,
                     IUpDateItemData iUpDateItemData,
                     IOnItemClickListener onItemClickListener){
        this.itemView1 = itemView1;
        this.itemView2 = itemView2;
        bindPublic(list,iUpDateItemData,onItemClickListener);
    }

    /**
     * 绑定跑马灯数据、布局、监听器
     * 通过加载layout id 作为item绑定数据
     * @param itemLayoutId 自定义布局的layout id
     * @param list
     * @param iUpDateItemData
     */
    public void bind(int itemLayoutId, final List<T> list,
                     IUpDateItemData iUpDateItemData){
        bind(itemLayoutId,list,iUpDateItemData,null);
    }


    /**
     * 绑定跑马灯数据、布局、监听器
     * 通过加载layout id 作为item绑定数据
     * @param itemLayoutId 跑马灯单个布局的 layout地址
     * @param list 跑马灯显示的数据
     * @param iUpDateItemData 滚动时更新数据的接口
     * @param onItemClickListener 点击单个item的点击监听事件
     */
    public void bind(int itemLayoutId, final List<T> list,
                     IUpDateItemData iUpDateItemData,
                     IOnItemClickListener onItemClickListener){
        //得到跑马灯单个布局,需要两个,这样才能转起来
        itemView1 = LayoutInflater.from(context).inflate(itemLayoutId,null);
        itemView2 = LayoutInflater.from(context).inflate(itemLayoutId,null);
        bindPublic(list,iUpDateItemData,onItemClickListener);
    }

    //绑定公共的参数 数据、更新监听、点击监听
    private void bindPublic(final List<T> list,
                           IUpDateItemData iUpDateItemData,IOnItemClickListener onItemClickListener){
        //如果数据时空的话,隐藏跑马灯
        if(list == null || list.isEmpty()){
            setVisibility(GONE);
            return;
        }
        this.iUpDateItemData = iUpDateItemData;
        this.list = list;
        //如果在布局文件中加载了 子布局,需要清除掉
        if(getChildCount() > 0){
            removeAllViews();
        }
        //添加到此控件
        addView(itemView1);
        addView(itemView2);
        //展示第一条数据
        if(iUpDateItemData != null){
            iUpDateItemData.updateItemData(itemView1, list.get(0));
        }
        bindOnClickListener(onItemClickListener);
        if(list.size()<=1){
            setAutoStart(false);
        }
    }

    //绑定监听事件
    private void bindOnClickListener(final IOnItemClickListener onItemClickListener){

        if(onItemClickListener != null){
            itemView1.setOnClickListener(new View.OnClickListener(){

                @Override
                public void onClick(View v) {
                    onItemClickListener.onMarqueeItemClickListener(v,list.get(index));
                }
            });
            itemView2.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View v) {
                    onItemClickListener.onMarqueeItemClickListener(v,list.get(index));
                }
            });
        }
    }

    /**
     * 当跑马灯每次转动 都会调用这个方法
     * 可以在这个方法里更新数据
     * @param whichChild
     */
    @Override
    public void setDisplayedChild(int whichChild) {
        super.setDisplayedChild(whichChild);
        if(list == null || list.size() <= 1) return;
        View view  = getCurrentView();
        if(view == null) return;
        if(iUpDateItemData != null){
            index++;
            if(index >= list.size()){
                index = 0;
            }
            iUpDateItemData.updateItemData(view,list.get(index));
        }
    }

    /**
     * 更新数据的接口
     */
    public interface IUpDateItemData<T>{
        void updateItemData(View view, T data);
    }

    /**
     * 跑马灯的每个item的点击事件
     */
    public interface IOnItemClickListener<T>{
        void onMarqueeItemClickListener(View view, T data);
    }
}

你可能感兴趣的:(Android高级UI绘制,Android,自定义控件)