Android技能杂谈——如何优雅的处理控件的点击事件
首先分享一个最佳实践:
大家开发复杂一些的Android应用的时候常常会写一个BaseActivity或者BaseFragment,里面写上一些基本而公用的方法,比如监听网络状况、弹出对话框、设置actionbar等,然后实现业务的Activity或者Fragment继承自这个基类。这样子可以大幅度的节省很多代码量,维护起来也很快速。
但是若界面上View很多,而且很多都要有click事件,那你是不是要写一堆setOnClick之类的代码呢?通过笔者的经验,有两种方式可以让你的ViewClick处理的代码更加优雅:
- 使用butterknife框架
- 在基类中做文章
前者不多说,大家可以多参考下butterknife的资料,这里着重介绍后者方式
问题引入(这里用Fragment举例)
如果你对某个view需要设置click事件,传统的代码是:
private TextView mPayment; mPayment = (TextView) findViewById(R.id.payment); mPayment.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //do something } });
你看为了处理一个view的点击事件,还没写具体点击事件做的事情就已经堆了这么多的代码。但是你有没有思考过,这个View是否要用到呢?是否需要findviewbyid出来呢?仅仅处理点击事件是否可以这样子写:
findViewById(R.id.payment).setOnClickListener(this); @Override public void onClick(View v) { int id = v.getId(); switch (id) { case R.id.payment: break; } }
这里的onClick是整个Fragment要implements一个View.onClickListener后自动需要强制实现的,具体点击事件可以在里面做。
上面的代码能看到我实际上并没有获取一个mPayment这个TextView的实例,实际上我可能并不需要获得他因为后面我不会去改变他。这样子还有一个好处,就是减少了内存消耗,因为少了一个对象。
改造基类
如果需要添加的点击事件view很多了,那么这里就要写很多这样的代码了:
findViewById(R.id.payment).setOnClickListener(this);
由于都是重复代码,显然这些代码可以放到基类中,于是在基类这样子设计:
public abstract class BaseFragment extends Fragment implements View.OnClickListener{ public void setViewClickListener(ArrayList<Integer> viewIds, View rootView) { for (int viewId : viewIds) { rootView.findViewById(viewId).setOnClickListener(this); } } }
这个方法传入一个以view的id为元素的list和一个停靠view即可
那么子类都继承自这个BaseFragment,具体写法是:
public class RootCashierFragment extends BaseFragment { private ArrayList<Integer> viewIds = new ArrayList<>(); @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.root_layout_cashier, null); viewIds.add(R.id.fab); setViewClickListener(viewIds, view); return view; } @Override public void onClick(View v) { switch (v.getId()) { case R.id.payment: L.d("click payment"); break; } } }
这样子所有的view的click事件全部放在了onClick中,看起来很优雅不乱,维护起来也一目了然
如何维护
后期若是需要添加减少需要监听需要点击事件的view,那么只需要做两件事情:
- 在viewIds中add新(remove旧)的view的id
- 在onClick实现(删除)点击后具体的内容
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?