實現一個可定製化的TabFlowLayout(三) -- 動態數據添加與常用接口封裝

效果圖

在這裏插入圖片描述

FlowHelper工程源碼

上面咱們已經實現了滑動的效果,今天來實現數據的添加;效果如下:
在這裏插入圖片描述
這裏學習一下 listview 或 Recyclerview 的數據封裝,我們也整蠱一下 adapter;
考慮到,頂部 tab 可能要有未讀消息,或者不同的控件,所以 layoutId 肯定是要有的,datas 數據肯定也是,且這個 data 類型用泛型修飾;
所以,大致可以這麼寫:

/**
 * @author by  zhengshaorui on 2019/10/8
 * Describe: 數據構建基類
 */
public abstract class TabAdapter<T> {
    private int mLayoutId;
    private List<T> mDatas;
    public TabAdapter(int layoutId, List<T> data) {
        mLayoutId = layoutId;
        mDatas = data;
    }

    /**
     * 獲取個數
     * @return
     */
    int getItemCount(){
        return mDatas == null ? 0 : mDatas.size();
    }

    /**
     * 獲取id
     * @return
     */
    int getLayoutId(){
        return mLayoutId;
    }

    /**
     * 獲取數據
     * @return
     */
    List<T> getDatas(){
        return mDatas;
    }

    /**
     * 公佈給外部的數據
     * @param view
     * @param data
     * @param position
     */
    public abstract void bindView(View view,T data,int position);

    /**
     * 單擊
     * @param view
     * @param position
     */
    public void onItemClick(View view,T data,int position){}

    /**
     * 通知數據改變
     */
    public void notifyDataChanged(){
        if (mListener != null) {
            mListener.notifyDataChanged();
        }
    }

    /**
     * 構建一個listener,用來改變數據
     */

    public AdapterListener mListener;
    void setListener(AdapterListener listener){
        mListener = listener;
    }


    
    /**
     * 常用模板
     */
    public TabAdapter setText(View view,int viewId,int resId){
        TextView textView = view.findViewById(viewId);
        if (textView != null) {
            textView.setText(resId);
        }
        return this;
    }
    public TabAdapter setText(View view,int viewId,String msg){
        TextView textView = view.findViewById(viewId);
        if (textView != null) {
            textView.setText(msg);
        }
        return this;
    }
    
}

同樣,配置完 adapter ,那麼肯定要有個入口去設置 adapter ,沒錯,這次我們又新建一個類: TabFlowLayout 用來實現數據的配置和一部分UI的繪製;

首先是 setAdapter 方法了:

    /**
     * 添加adapter,
     * @param adapter
     */
    public void setAdapter(TabAdapter adapter){
        mAdapter = adapter;
        mAdapter.setListener(this);
        //實現數據更新
        notifyDataChanged();
    }

setAdapter 非常簡單,就是配置監聽,然後拿到 view 之後,addview 進去即可:

    @Override
    public void notifyDataChanged() {
        removeAllViews();
        TabAdapter adapter = mAdapter;
        int itemCount = adapter.getItemCount();
        for (int i = 0; i < itemCount; i++) {
            View view = LayoutInflater.from(getContext()).inflate(adapter.getLayoutId(),this,false);
            adapter.bindView(view,adapter.getDatas().get(i),i);
            configClick(view,i);
            addView(view);
        }
    }

    private void configClick(final View view, final int i) {
        view.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mAdapter.onItemClick(view,mAdapter.getDatas().get(i),i);
            }
        });
    }

當然,在 configClick 這裏,還可以添加更多的操作,比如子控件的點擊事件;view 的select 狀態,從而實現選擇效果或者點擊效果;這個可以根據自己需求去實現。

這樣,在Activity 的配置也會變得特別簡單:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tab);
        TabFlowLayout tabFlowLayout = findViewById(R.id.tabflow);
        mAdapter = new TabFlowAdapter(R.layout.item_tab_text, mTitle);
        tabFlowLayout.setAdapter(mAdapter);
    }

    public void update(View view) {
        mTitle.clear();
        ArrayList<String> strings = new ArrayList<>(Arrays.asList("Life is like an ocean. Only strong willed people can reach the other side".split(" ")));
        mTitle.addAll(strings);
        Log.d(TAG, "zsr - update: "+mTitle.size());
        mAdapter.notifyDataChanged();
    }

    class TabFlowAdapter extends TabAdapter<String>{

        public TabFlowAdapter(int layoutId, List<String> data) {
            super(layoutId, data);
        }

        @Override
        public void bindView(View view, String data, int position) {
            setText(view,R.id.item_text,data);
        }

        @Override
        public void onItemClick(View view,String data,int position) {
            super.onItemClick(view,data,position);
            Toast.makeText(TabActivity.this, data, Toast.LENGTH_SHORT).show();
        }
    }

這樣,只需要繼承 TabAdapter 就可以像 listview 或者 recyclerview 這樣的數據配置方式了;

下一章,我們將學習與 viewpager 結合,實現多種效果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章