定义一个事件接口
public interface EventListener {
void onEvent(Component component,int pos,Object data);
}
定义一个点击事件接口
public interface ClickListener {
void onClick(int pos, Object data);
}
BaseProvider
public class BaseProvider<T> extends BaseItemProvider {
private List<T> data;
private Context context;
protected boolean enableMult = false;
protected ArrayList<Class> holders;
protected HashMap<Class,Class> map;
public int current = 0; //代表当前选中的count
protected int multCount = 1;
public HashMap<Integer, ClickListener> clickMap;
public HashMap<Integer, EventListener> eventMap;
/**
* 拿到集合数据
* @return
*/
public List<T> getData(){
return data;
}
/**
* 注册holder
* @param holder
*/
public BaseProvider<T> register(Class pojo,Class holder){
if(holders == null){
holders = new ArrayList<>();
map = new HashMap<>();
}
holders.add(holder);
map.put(pojo,holder);
return this;
}
/**
* 点击事件
*/
public BaseProvider<T> bindClick(int id, ClickListener listener){
if(clickMap == null){
clickMap = new HashMap<>();
}
clickMap.put(id,listener);
return this;
}
/**
* 绑定事件
*/
public BaseProvider<T> bindEvent(int id, EventListener eventListener){
if(eventMap == null){
eventMap = new HashMap<>();
}
eventMap.put(id,eventListener);
return this;
}
/**
* 是否允许多布局
* @param enableMult
* @return
*/
public BaseProvider<T> mult(boolean enableMult){
this.enableMult = enableMult;
return this;
}
public BaseProvider(Context context) {
super();
this.context = context;
data = new ArrayList<>();
clickMap = new HashMap<>();
eventMap = new HashMap<>();
}
public BaseProvider(Context context, List<T> data) {
super();
this.data = data;
this.context = context;
}
public void refreshData(List<T> data){
setData(data);
notifyDataChanged();
}
/**
* 添加数据
* @param more
*/
public void more(List<T> more){
if(more != null){
this.data.addAll(more);
}
notifyDataChanged();
}
public BaseProvider<T> setData(List<T> data){
if (data != null){
this.data.clear();
this.data.addAll(data);
}
return this;
}
public boolean hasData(){
if(MapUtil.isEmpty(data)){
return false;
}else{
return true;
}
}
public BaseProvider<T> setMultCount(int count) {
this.multCount = count;
return this;
}
public BaseProvider<T> vertical(ListContainer listContainer) {
listContainer.setOrientation(ListContainer.VERTICAL);
listContainer.setLayoutManager(new DirectionalLayoutManager());
listContainer.setItemProvider(this);
return this;
}
public BaseProvider<T> horizontal(ListContainer listContainer) {
listContainer.setOrientation(ListContainer.HORIZONTAL);
listContainer.setLayoutManager(new DirectionalLayoutManager());
listContainer.setItemProvider(this);
return this;
}
public BaseProvider<T> grid(ListContainer listContainer,int count) {
TableLayoutManager tableLayoutManager = new TableLayoutManager();
tableLayoutManager.setColumnCount(count);
listContainer.setLayoutManager(tableLayoutManager);
listContainer.setItemProvider(this);
return this;
}
@Override
public T getItem(int i) {
return data.get(i);
}
@Override
public int getCount() {
return data.size();
}
@Override
public long getItemId(int pos) {
return pos;
}
@Override
public int getItemComponentType(int position) {
T data = getItem(position);
if(data instanceof Mult){
Mult mult = (Mult)data;
Class holderClass = map.get(data.getClass());
return holderClass.hashCode()+mult.mult();
}
return position;
}
@Override
public int getComponentTypeCount() {
return multCount;
}
@Override
public Component getComponent(int pos, Component component, ComponentContainer componentContainer) {
/**
* 正常布局
*/
T itemData = data.get(pos);
Class<ViewHolder<T>> holderClass = map.get(itemData.getClass());
if(holderClass == null){
throw new RuntimeException("请先注册holder和数据类型");
}
T data = itemData;
ViewHolder<T> holder = ViewHolder.<T>get(this,context,component,data,pos,holderClass);
return holder.getRootComponent();
}
/**
* 点击的是否是当前
* @param pos
* @return
*/
public boolean clickCurrent(int pos){
return current == pos;
}
}
ViewHolder
public abstract class ViewHolder<Data> {
protected HashMap<Integer, Component> mComponents;
protected Component mRootComponent;
protected Context context;
protected int layoutId;
protected int position;
protected Data itemData;
protected LayoutScatter layoutScatter;
protected HashMap<Integer, ClickListener> clickMap;
protected HashMap<Integer, EventListener> eventMap;
protected BaseProvider provider;
public ViewHolder(Context context) {
super();
this.context = context;
if(layoutScatter == null){
layoutScatter = LayoutScatter.getInstance(context);
}
mComponents = new HashMap<>();
}
public void setLayout(Data data){
layoutId = getLayoutId(data,position);
this.mRootComponent = layoutScatter.parse(layoutId,null,false);
mRootComponent.setTag(this);
findComponent(data,position);
}
public static <T> ViewHolder<T> get(BaseProvider provider,Context context,Component convertView,T data,int pos,Class holderClass) {
ViewHolder holder = null;
try {
if(convertView == null){
Constructor<ViewHolder<T>> declaredConstructor = holderClass.getDeclaredConstructor(Context.class);
holder = declaredConstructor.newInstance(context);
holder.position = pos;
holder.itemData = data;
holder.setLayout(data);
holder.bindProvider(provider);
}else{
holder = (ViewHolder)convertView.getTag();
holder.position = pos;
holder.itemData = data;
}
}catch (Exception e){
e.printStackTrace();
}
holder.convert(data,pos);
return holder;
}
public void bindProvider(BaseProvider provider){
this.provider = provider;
}
public Component getRootComponent(){
return mRootComponent;
}
public abstract void convert(Data data,int position);
/**
* 通过componentId获取控件
*
* @param viewId
* @return
*/
public <T extends Component> T getComponent(int viewId) {
Component view = mComponents.get(viewId);
if (view == null) {
view = mRootComponent.findComponentById(viewId);
mComponents.put(viewId, view);
}
return (T) view;
}
/**
* 绑定点击事件
* @param component
* @return
*/
protected ViewHolder<Data> bindClick(Component component){
if(clickMap == null && provider != null){
clickMap = provider.clickMap;
}
if(clickMap != null){
ClickListener clickListener = clickMap.get(component.getId());
component.setClickedListener(component1 -> {
if (clickListener != null){
clickListener.onClick(position,itemData);
}
});
}
return this;
}
/**
* 绑定事件
* @param component
* @return
*/
protected ViewHolder<Data> bindEvent(Component component){
if(eventMap == null && provider != null){
eventMap = provider.eventMap;
}
if(eventMap != null){
EventListener eventListener = eventMap.get(component.getId());
if(eventListener != null){
eventListener.onEvent(component,position,itemData);
}
}
return this;
}
protected abstract int getLayoutId(Data data,int position);
protected abstract void findComponent(Data data,int position);
protected void setGridWidth(Component rootView,int other,int spanCount){
int displayWidthInPx = ViewUtil.getDisplayWidthInPx(context);
int width = (displayWidthInPx - (AttrHelper.vp2px(other, context))) / spanCount;
ComponentContainer.LayoutConfig layoutConfig = rootView.getLayoutConfig();
layoutConfig.width = width;
rootView.setLayoutConfig(layoutConfig);
}
}
使用
new BaseProvider<Notice>(getContext())
.register(Notice.class,NoticeHolder.class)
//绑定事件
.bindClick(ResourceTable.Id_item_notice_root, (pos, data) -> {
Notice notice = (Notice)data;
Router.toSimpleAbility(getFractionAbility(),NoticeDetailSlice.class,
MapUtil.mapObj().puts(NoticeDetailSlice.ID,notice.id));
})
.vertical(noticeList);
在具体的ViewHolder中绑定
public class NoticeHolder extends ViewHolder<Notice> {
private Image imgView;
private Component rootView;
private Text titleView,contentView;
public NoticeHolder(Context context) {
super(context);
}
@Override
public void convert(Notice notice, int position) {
titleView.setText(notice.title);
contentView.setText(notice.description);
bindClick(rootView); //这一定必须!!!
}