实现一个可定制化的TabFlowLayout(三) -- 动态数据添加与常用接口封装
2023-09-27 14:28:04 时间
效果图
上面咱们已经实现了滑动的效果,今天来实现数据的添加;效果如下:
这里学习一下 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 结合,实现多种效果
相关文章
- C++基础语法(一):C++语言概述【面向对象编程(OOP)三大特性:封装、继承、多态】
- Linux网络编程(七)-第三方库-Libevent02:专注网络开发的事件库【封装了多种I/O 多路复用】【用于开发TCP服务端】【事件的底层处理框架;精简;性能高】【核心:事件驱动(触发),回调】
- C++哈希-使用/模拟/封装
- Pytest学习 ------ 接口自动化测试之pytest 接口关联框架封装
- 对Volley框架的一些接口进行封装:VolleyAir
- FLV封装格式及分析器工具
- 用应用封装来提高移动安全,这合适吗?
- uniapp中自定义组件的封装及使用
- 说说接口封装
- springboot-接口返回统一规范封装的方法
- 2022-03-07 Influxdb创建用户接口与raft日志交互封装
- vue项目实战:api管理和封装
- Vue中如何完成对axios的二次封装、统一接口管理
- phpmailer类的再封装
- webrtc封装sdk(二)call api的使用
- Flutter网络请求封装
- okhttp二次封装
- 【Vue 开发实战】实战篇 # 40:自己封装一个支持自动校验的表单项
- 客快物流大数据项目(五十五):封装公共接口(根据存储介质抽取特质)
- RN实战项目网络请求封装
- react-native-io-fetch io接口请求封装
- AJAX封装闭包
- 轻松把玩HttpClient之封装HttpClient工具类(五),携带Cookie的请求
- 我的Android进阶之旅------>Android关于Log的一个简单封装