BaseActivity中封裝通用的Toolbar
之前寫過一篇關於如何使用Toolbar的文章,最近在搭建新專案時對Toolbar做了封裝。封裝的預期目標是隻在BaseActivity中引入Toolbar,然後子Activity通過繼承BaseActivity就能顯示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);
}
}
效果如下圖所示
相關文章
- 我一行程式碼都不寫實現Toolbar!你卻還在封裝BaseActivity?行程封裝
- .NET中封裝SqlHelper封裝SQL
- BaseActivity與BaseFragment的簡單封裝Fragment封裝
- 在Flutter中封裝redux的使用Flutter封裝Redux
- ToolBar封裝策略封裝
- 專案中封裝axios封裝iOS
- Simulink中封裝子系統封裝
- ToolBar專案封裝使用封裝
- 使用DLL檔案中封裝的視窗 (轉)封裝
- WPF中封裝一個自己的MessageBox封裝
- Android基礎 使用ToolBar教你打造一個通用的標題欄Android
- vue.js中封裝全域性filterVue.js封裝Filter
- 分享幾個我工作中封裝的typeScript方法封裝TypeScript
- Android談談封裝那些事--BaseActivity和BaseFragment(-)Android封裝Fragment
- 在webview_flutter中封裝JSBridgeWebViewFlutter封裝JS
- Vue中封裝axios傳送請求Vue封裝iOS
- 在Vue中封裝一個select元件Vue封裝元件
- Android 談談封裝那些事 –BaseActivity 和 BaseFragment(二)Android封裝Fragment
- Android 談談封裝那些事 --BaseActivity 和 BaseFragment(二)Android封裝Fragment
- C++中封裝和繼承的訪問許可權C++封裝繼承訪問許可權
- 元件化封裝之標題欄Toolbar元件化封裝
- Android Toolbar的用法Android
- MapStruct在專案中封裝實踐-帶原始碼Struct封裝原始碼
- 在vue中封裝一個從右至左滾動公告的元件Vue封裝元件
- Activity繼承BaseActivity的使用(使用相同佈局)繼承
- 封裝一個通用的PopupWindow封裝
- WPF apply style in Toolbar via Static ToolBar.ButtonStyleKeyAPP
- DjangoRestFramework框架三種分頁功能的實現 - 在DjangoStarter專案模板中封裝DjangoRESTFramework框架封裝
- Toolbar使用總結
- Toolbar不能實現你的需求?
- MD 2. - TextInputLayout的使用 ToolBar
- React — 通用hooks封裝ReactHook封裝
- IEWebControl的toolbar的使用!!!! (轉)Web
- Django除錯工具django-debug-toolbar安裝使用教程Django除錯
- 基於Tencent封裝的通用UI框架封裝UI框架
- Android 封裝一個通用的PopupWindowAndroid封裝
- 前端開發 通用JS工具的封裝前端JS封裝
- ListView 通用 Adapter 封裝ViewAPT封裝