开发中基本上每个APP都会有自己的头部,如何去写这个头部呢?一部分人会在xml布局中直接写,一部分人会调用系统的ToolBar自定义布局,这两种方式都可以去实现,但是有个问题,如果产品频繁让你改这个头部你会不会崩溃呢?
A : “我自己写的,我都清楚哪个控件是什么,有什么用,改一下也不费事”
B : "慢慢捋还是可以改的";
我想说 既然每个应用都能用到这个头部 为什么不能进一步封装一下呢?一句代码搞定的事没有必要写很多行。
这一期我们来看一下如何利用Builder设计模式构建整个应用的NavigationBar,再也不必在activity中写任何布局,而且一行解决头部的问题。
-
首选看一下我们要写的NavigationBar的结构图
通过图可以知道,首先先写个接口用来规范头部,然后写个abstract基类,再写一个DefaultNavigationBar去实现这个抽象类,特殊情况特殊对待吧。
1.定义头部规范接口
/**
* 导航栏规范
*/
public interface INavigation {
//绑定头部ID
public int bindLayoutId();
//绑定头部参数
public void applyView();
}
2.创建一个基类AbsNavigationBar
在创建前先稍微讲一下builder设计模式的构造 看图。
/**
* Created by LiMing on 2018/4/24.
* QQ:1002464056
* Email: [email protected]
* Version:1.0
* 基类(所有的在此基础上写)
*/
public abstract class AbsNavigationBarimplements INavigation {
private P mParmas;
private View mNavigationView;
public AbsNavigationBar(P parmas){
this.mParmas=parmas;
creatAndBind();
}
public P getmParmas() {
return mParmas;
}
//创建和绑定视图
private void creatAndBind() {
if (mParmas.mParent==null) {
//获取根布局
ViewGroup viewGroup = ((Activity) mParmas.mContext).findViewById(android.R.id.content);
// 将根布局中第一个视图作为父容器(linearLayout)
mParmas.mParent= (ViewGroup) viewGroup.getChildAt(0);
}
if (mParmas.mParent==null) {
return;
}
//创建头部视图
mNavigationView= LayoutInflater.from(mParmas.mContext).inflate(R.layout.title_bar,mParmas.mParent,false);
//将头部视图添加到父容器中
mParmas.mParent.addView(mNavigationView,0);
//调用设置参数的方法
applyView();
}
public abstract static class Build{
public Build (Context context,ViewGroup parent){}
// 创建一个 AbsNavigationBar
public abstract AbsNavigationBar builder();
public static class AbsNavigationBarParmas{
public Context mContext;
public ViewGroup mParent;
public AbsNavigationBarParmas(Context context,ViewGroup parent){
this.mContext=context;
this.mParent=parent;
}
}
}
}
3.实现类 DefaultNavigationBar 实现基类,然后在此基础上添加设置,如修改文字,设置监听之类的
/**
* Created by LiMing on 2018/4/24.
* QQ:1002464056
* Email: [email protected]
* Version:1.0
*/
public class DefaultNavigationBar extends AbsNavigationBar {
public DefaultNavigationBar(DefaultNavigationBar.Build.DefaultNavigationBarParmas parmas) {
super(parmas);
}
@Override
public int bindLayoutId() {
return R.layout.title_bar;
}
@Override
public void applyView() {
//实现设置的参数
//设置标题
setText(R.id.title,getmParmas().mTitle);
//设置左边文字
setText(R.id.left_text,getmParmas().leftText);
// 设置左边图片的点击事件
setOnClickListener(R.id.back,getmParmas().leftClickListener);
}
public static class Build extends AbsNavigationBar.Build{
DefaultNavigationBarParmas p;
public Build(Context context, ViewGroup parent) {
super(context, parent);
//创建DefaultNavigationBarParma 对象
p=new DefaultNavigationBarParmas(context,parent);
}
public Build(Context context) {
super(context, null);
p=new DefaultNavigationBarParmas(context,null);
}
@Override
public DefaultNavigationBar builder() {
DefaultNavigationBar defaultNavigationBar=new DefaultNavigationBar(p);
return defaultNavigationBar;
}
// 1.设置参数
/**
* 设置title
* @param title
* @return
*/
public DefaultNavigationBar.Build setTitle(String title){
p.mTitle=title;
return this;
}
/**
* 设置左边的文字
* @param leftText
* @return
*/
public DefaultNavigationBar.Build setLeftText(String leftText){
p.leftText=leftText;
return this;
}
/**
* 设置左边图片监听
* @param clickListener
* @return
*/
public DefaultNavigationBar.Build setLeftImageClickListener(View.OnClickListener clickListener){
p.leftClickListener=clickListener;
return this;
}
public class DefaultNavigationBarParmas extends AbsNavigationBarParmas{
//2.参数存放的位置
public String mTitle;
public String leftText;
public View.OnClickListener leftClickListener;
public DefaultNavigationBarParmas(Context context, ViewGroup parent) {
super(context, parent);
}
}
}
}
通用的80%的功能在此基本可以实现,我只是写了几个方法,有需要的要继续完善,剩下的特殊的20%的功能需要自己去实现了。
具体怎么调用呢?很简单的,一句代码搞定!
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DefaultNavigationBar defaultNavigationBar= new DefaultNavigationBar.Build(this)
.setTitle("导航栏")
.setLeftText("返回").setLeftImageClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this, "点击了返回按钮", Toast.LENGTH_SHORT).show();
}
})
.builder();
}
}
好了,以后不用再为修改头部烦恼了,一句代码搞定,觉得实用呢就试着用用~~
受辉哥的影响,学习了不少,大家可以去他的博客看看,很实用 @红橙Darren