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); } }
自定义跑马灯,可以绑定任意布局
最新推荐文章于 2022-12-07 15:04:45 发布