BaseActivity中封装通用的Toolbar
2017-04-28 23:35
190 查看
之前写过一篇关于如何使用Toolbar的文章,最近在搭建新项目时对Toolbar做了封装。封装的预期目标是只在BaseActivity中引入Toolbar,然后子Activity通过继承BaseActivity就能显示Toolbar。接下来就看看如何实现这样的功能。
因为我们使用toolbar作为titlebar,因此首先需要去掉Actionbar。在style文件下修改默认Theme的parent为Theme.AppCompat.Light.NoActionBar便可以去掉默认的Actionbar,如下:
然后定义一个toolbar_layout的xml文件,在toolbar中加入俩个TextView作为标题和子标题,如下:
接着在BaseActivity的布局文件中include进toolbar_layout,如下:
这样BaseActivity中就可以正常显示出Toolbar了。那么如何实现子Activity继承BaseActivity而显示toolbar呢?其实我们可以在BaseActivity中做文章。
首先在BaseActivity中声明一个LinearLayout,然后把BaseActivity的布局文件添加到该LinearLayout中。我们知道子Activity通过setContentView()方法来关联布局文件,因此我们可以在BaseActivity中去重写setContentView()方法,在重写的setContentView中把子类的布局文件也添加到事先声明的LinearLayout中,接下来应该解决如何将这个LinearLayout与Activity关联。查阅相关资料可以知道,可以通过 findViewById(android.R.id.content)拿到window的ViewGroup然后将刚才声明的LinearLayout添加到这个ViewGroup中,这样就可以在子Activity中显示出BaseActivity中的Toolbar了。(具体原因可以查阅android.R.id.content和 DecorView)代码如下:
上述代码通过initContentView()方法将BaseActivity中的布局文件添加到了声明的parentLinearLayout中,通过setContentView()方法将子Activity的布局也添加到了parentLinearLayout中,然后又将parentLinearLayout添加到了viewGroup中实现了Activity与布局文件的关联。至此我们完成了第一步,使子Activity可以显示出BaseActivity中的Toolbar布局。
接下来,我们需要在BaseActivity中对Toolbar进行封装,使其能够更加方便的在子Activity中使用。比如添加toolbar回退键的监听,添加是否显示回退键的方法等。完整的BaseActivity如下:
最后我们可以在子Activity中去使用toolbar了。
我们让MainActivity继承BaseActivity,并在布局文件中添加一个button,切布局文件中没有添加标题栏,布局文件的代码就不再贴出了。然后 重写isShowBacing()方法,使其返回false,隐藏MainActivity的回退键。
代码如下:
创建TestActivity并继承BaseActivity,TestActivity的布局文件中不添加任何view。然后在TestActivity中给toolbar设置内容,如下:
效果如下图所示
因为我们使用toolbar作为titlebar,因此首先需要去掉Actionbar。在style文件下修改默认Theme的parent为Theme.AppCompat.Light.NoActionBar便可以去掉默认的Actionbar,如下:
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style>
然后定义一个toolbar_layout的xml文件,在toolbar中加入俩个TextView作为标题和子标题,如下:
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/colorPrimary" android:minHeight="?attr/actionBarSize"> <!--自定义toolbar的title 和subtitle --> <TextView android:id="@+id/tv_right" style="@style/TextAppearance.AppCompat.Widget.ActionBar.Subtitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:maxLines="1" android:textColor="@color/white" android:text="right" android:paddingRight="10dp" android:layout_gravity="right" /> <TextView android:id="@+id/tv_title" style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:lines="1" android:ellipsize="end" android:text="title" android:scrollHorizontally="true" android:textColor="@color/white" android:layout_gravity="center" /> </android.support.v7.widget.Toolbar>
接着在BaseActivity的布局文件中include进toolbar_layout,如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <include layout="@layout/toolbar_layout"/> </LinearLayout>
这样BaseActivity中就可以正常显示出Toolbar了。那么如何实现子Activity继承BaseActivity而显示toolbar呢?其实我们可以在BaseActivity中做文章。
首先在BaseActivity中声明一个LinearLayout,然后把BaseActivity的布局文件添加到该LinearLayout中。我们知道子Activity通过setContentView()方法来关联布局文件,因此我们可以在BaseActivity中去重写setContentView()方法,在重写的setContentView中把子类的布局文件也添加到事先声明的LinearLayout中,接下来应该解决如何将这个LinearLayout与Activity关联。查阅相关资料可以知道,可以通过 findViewById(android.R.id.content)拿到window的ViewGroup然后将刚才声明的LinearLayout添加到这个ViewGroup中,这样就可以在子Activity中显示出BaseActivity中的Toolbar了。(具体原因可以查阅android.R.id.content和 DecorView)代码如下:
public abstract class BaseActivity extends AppCompatActivity{ //the container of this activity layout and sub-activity layout private LinearLayout parentLinearLayout; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initContentView(R.layout.activity_base); setContentView(getLayoutId()); initToolBar(); init(); } // overwrite the function in sub-activity and return the layout id of sub-activity protected abstract int getLayoutId(); private void initContentView(@LayoutRes int layoutResID) { ViewGroup viewGroup = (ViewGroup) findViewById(android.R.id.content); viewGroup.removeAllViews(); parentLinearLayout = new LinearLayout(this); parentLinearLayout.setOrientation(LinearLayout.VERTICAL); // add parentLinearLayout in viewGroup viewGroup.addView(parentLinearLayout); // add the layout of BaseActivity in parentLinearLayout LayoutInflater.from(this).inflate(layoutResID, parentLinearLayout, true); } /** * @param layoutResID layout id of sub-activity */ @Override public void setContentView(@LayoutRes int layoutResID) { // added the sub-activity layout id in parentLinearLayout LayoutInflater.from(this).inflate(layoutResID, parentLinearLayout, true); } }
上述代码通过initContentView()方法将BaseActivity中的布局文件添加到了声明的parentLinearLayout中,通过setContentView()方法将子Activity的布局也添加到了parentLinearLayout中,然后又将parentLinearLayout添加到了viewGroup中实现了Activity与布局文件的关联。至此我们完成了第一步,使子Activity可以显示出BaseActivity中的Toolbar布局。
接下来,我们需要在BaseActivity中对Toolbar进行封装,使其能够更加方便的在子Activity中使用。比如添加toolbar回退键的监听,添加是否显示回退键的方法等。完整的BaseActivity如下:
public abstract class BaseActivity extends AppCompatActivity{ //the container of this activity layout and sub-activity layout private LinearLayout parentLinearLayout; private TextView mTvTitle; private TextView mTvRight; private Toolbar mToolbar; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initContentView(R.layout.activity_base); setContentView(getLayoutId()); initToolBar(); setBackIcon(); init(); } // overwrite the function in sub-activity and return the layout id of sub-activity protected abstract int getLayoutId(); private void initContentView(@LayoutRes int layoutResID) { ViewGroup viewGroup = (ViewGroup) findViewById(android.R.id.content); viewGroup.removeAllViews(); parentLinearLayout = new LinearLayout(this); parentLinearLayout.setOrientation(LinearLayout.VERTICAL); viewGroup.addView(parentLinearLayout); // add the layout of BaseActivity in parentLinearLayout LayoutInflater.from(this).inflate(layoutResID, parentLinearLayout, true); } /** * @param layoutResID the layout id of sub Activity */ @Override public void setContentView(@LayoutRes int layoutResID) { // added the sub-activity layout id in parentLinearLayout LayoutInflater.from(this).inflate(layoutResID, parentLinearLayout, true); } private void setBackIcon(){ if (null != getToolbar() && isShowBacking()) { getToolbar().setNavigationIcon(R.drawable.icon_back); getToolbar().setNavigationOnClickListener((v) -> onBackPressed()); } } /** * @return TextView in center */ public TextView getToolbarTitle() { return mTvTitle; } /** * @return TextView on the right */ public TextView getSubTitle() { return mTvRight; } /** * set Title * @param title */ public void setToolBarTitle(CharSequence title) { if (mTvTitle != null) { mTvTitle.setText(title); } else { getToolbar().setTitle(title); setSupportActionBar(getToolbar()); } } /** * the toolbar of this Activity * @return support.v7.widget.Toolbar. */ public Toolbar getToolbar() { return (Toolbar) findViewById(R.id.toolbar); } /** * is show back icon,default is none。 * you can override the function in subclass and return to true show the back icon * @return */ protected boolean isShowBacking() { return true; } }
最后我们可以在子Activity中去使用toolbar了。
我们让MainActivity继承BaseActivity,并在布局文件中添加一个button,切布局文件中没有添加标题栏,布局文件的代码就不再贴出了。然后 重写isShowBacing()方法,使其返回false,隐藏MainActivity的回退键。
代码如下:
public class MainActivity extends BaseActivity { @BindView(R.id.btn) Button mBtn1; @Override protected int getLayoutId() { return R.layout.activity_main; } @Override protected boolean isShowBacking() { return false; } @OnClick({R.id.btn}) public void Onclick(View view){ switch (view.getId()){ case R.id.btn: startActivity(new Intent(this,TestActivity.class)); break; } } }
创建TestActivity并继承BaseActivity,TestActivity的布局文件中不添加任何view。然后在TestActivity中给toolbar设置内容,如下:
public class TestActivity extends BaseActivity { @Override protected int getLayoutId() { return R.layout.activity_test; } @Override protected void init() { getToolbarTitle().setText("中间标题"); getSubTitle().setText("右边标题"); Toolbar toolbar = getToolbar(); toolbar.setLogo(R.mipmap.ic_launcher); toolbar.setNavigationIcon(R.drawable.back_white); } }
效果如下图所示
相关文章推荐
- baseactivity实现封装toolbar
- BaseActivity中封装通用的Toolbar
- BaseActivity的toolbar的封装
- ToolBar的封装
- baseActivity的封装——模板式设计模式
- 用DbProviderFactory 实现通用数据库操作的封装
- JDBC事务及将查询结果封装成对象(通用)
- asp.net mvc(一) ----------简单封装成通用的List<T>集合
- 对进度条的通用封装实现
- js封装表单通用函数
- 拒绝无用功,封装一个通用的PopupWindow
- fun:数字字符转换成大写人民币通用方法封装
- Android ToolBar 的简单封装
- Android 通用标题栏简单封装实现
- 封装一个BaseActivity并实现沉浸式状态栏
- 把redis源码的linux网络库提取出来,自己封装成通用库使用(★firecat推荐★)
- RecyclerView的通用适配器,和滚动时不加载图片的封装
- 教你如何封装一个通用的PopupWindow
- android Toolbar的封装
- 使用redisTemplete简单封装的一个通用操作类