FlowHelper工程源码
上面咱们已经实现了滑动的效果,今天来实现数据的添加;效果如下:
这里学习一下 listview 或 Recyclerview 的数据封装,我们也整蛊一下 adapter;
考虑到,顶部 tab 可能要有未读消息,或者不同的控件,所以 layoutId 肯定是要有的,datas 数据肯定也是,且这个 data 类型用泛型修饰;
所以,大致可以这么写:
/**
* @author by zhengshaorui on 2019/10/8
* Describe: 数据构建基类
*/
public abstract class TabAdapter {
private int mLayoutId;
private List mDatas;
public TabAdapter(int layoutId, List data) {
mLayoutId = layoutId;
mDatas = data;
}
/**
* 获取个数
* @return
*/
int getItemCount(){
return mDatas == null ? 0 : mDatas.size();
}
/**
* 获取id
* @return
*/
int getLayoutId(){
return mLayoutId;
}
/**
* 获取数据
* @return
*/
List 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 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{
public TabFlowAdapter(int layoutId, List 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 结合,实现多种效果