美文网首页
鸿蒙ListContainer多布局实践,给条目控件加事件

鸿蒙ListContainer多布局实践,给条目控件加事件

作者: 洋葱cy | 来源:发表于2021-11-15 09:58 被阅读0次

    定义一个事件接口

    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);  //这一定必须!!!
        }
    
    

    相关文章

      网友评论

          本文标题:鸿蒙ListContainer多布局实践,给条目控件加事件

          本文链接:https://www.haomeiwen.com/subject/etoftrtx.html