鴻蒙ListContainer多布局實(shí)踐,給條目控件加事件

定義一個(gè)事件接口

public interface EventListener {
    void onEvent(Component component,int pos,Object data);
}

定義一個(gè)點(diǎn)擊事件接口

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; //代表當(dāng)前選中的count
    protected int multCount = 1;
    public HashMap<Integer, ClickListener> clickMap;
    public HashMap<Integer, EventListener> eventMap;

    /**
     * 拿到集合數(shù)據(jù)
     * @return
     */
    public List<T> getData(){
        return data;
    }

    /**
     * 注冊(cè)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;
    }

    /**
     * 點(diǎn)擊事件
     */
    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();
    }

    /**
     * 添加數(shù)據(jù)
     * @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("請(qǐng)先注冊(cè)holder和數(shù)據(jù)類(lèi)型");
        }
        T data = itemData;
        ViewHolder<T> holder = ViewHolder.<T>get(this,context,component,data,pos,holderClass);
        return holder.getRootComponent();
    }

    /**
     * 點(diǎn)擊的是否是當(dāng)前
     * @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);

    /**
     * 通過(guò)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;
    }

    /**
     * 綁定點(diǎn)擊事件
     * @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);  //這一定必須!!!
    }

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末熏瞄,一起剝皮案震驚了整個(gè)濱河市捧搞,隨后出現(xiàn)的幾起案子吩坝,更是在濱河造成了極大的恐慌圆裕,老刑警劉巖密浑,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抵赢,死亡現(xiàn)場(chǎng)離奇詭異挎挖,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)筝闹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)媳叨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人关顷,你說(shuō)我怎么就攤上這事糊秆。” “怎么了议双?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵痘番,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng)汞舱,這世上最難降的妖魔是什么伍纫? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮昂芜,結(jié)果婚禮上莹规,老公的妹妹穿的比我還像新娘。我一直安慰自己泌神,他們只是感情好良漱,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著腻扇,像睡著了一般债热。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上幼苛,一...
    開(kāi)封第一講書(shū)人閱讀 51,208評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音焕刮,去河邊找鬼舶沿。 笑死,一個(gè)胖子當(dāng)著我的面吹牛配并,可吹牛的內(nèi)容都是我干的括荡。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼溉旋,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼畸冲!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起观腊,我...
    開(kāi)封第一講書(shū)人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤邑闲,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后梧油,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體苫耸,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年儡陨,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了褪子。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡骗村,死狀恐怖嫌褪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情胚股,我是刑警寧澤笼痛,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站信轿,受9級(jí)特大地震影響晃痴,放射性物質(zhì)發(fā)生泄漏残吩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一倘核、第九天 我趴在偏房一處隱蔽的房頂上張望泣侮。 院中可真熱鬧,春花似錦紧唱、人聲如沸活尊。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蛹锰。三九已至,卻和暖如春绰疤,著一層夾襖步出監(jiān)牢的瞬間铜犬,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工轻庆, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留癣猾,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓余爆,卻偏偏與公主長(zhǎng)得像纷宇,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蛾方,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容