实现一个可定制化的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 结合,实现多种效果

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