日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

Android封装含有通用标题栏的基类BaseActivity

發(fā)布時(shí)間:2023/12/20 Android 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android封装含有通用标题栏的基类BaseActivity 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

安卓開(kāi)發(fā)中,經(jīng)常會(huì)遇到項(xiàng)目的標(biāo)題欄基本樣式都是一致的,只有個(gè)別界面需要定制化,而TitltBar或許跟我們的業(yè)務(wù)需求不是很相符,所以很多時(shí)候我們都想要去封裝一個(gè)含有通用標(biāo)題欄并且可定制化的BaseActivity。本文希望對(duì)有這方面需求的童鞋提供一種參考。效果圖類似于這樣

首先很多開(kāi)發(fā)者比較喜歡的一種做法是寫(xiě)一份通用的標(biāo)題欄布局,然后在每次創(chuàng)建的Activity的布局文件中去選擇include的方式加入布局,這種方式其實(shí)在我看來(lái)工作量其實(shí)還是挺大,為了使用的時(shí)候更方便,可以將寫(xiě)好的標(biāo)題欄布局作為一個(gè)View添加到根布局中。

下面先貼出標(biāo)題欄的布局:

<?xml version="1.0" encoding="utf-8"?> <!-- 默認(rèn)TitleBar布局文件 --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="44dp"android:background="@color/white"><TextViewandroid:id="@+id/tv_titlebar_name"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:paddingLeft="90dp"android:paddingRight="90dp"android:singleLine="true"android:text="@string/app_name"android:textColor="@color/color_333333"android:textSize="18sp" /><TextViewandroid:id="@+id/tv_titlebar_left"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_alignParentLeft="true"android:drawableLeft="@mipmap/icon_back"android:gravity="center"android:paddingLeft="8dp"android:paddingRight="8dp"android:layout_centerVertical="true"android:textColor="@color/white"android:textSize="14sp" /><TextViewandroid:id="@+id/tv_titlebar_right"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_alignParentRight="true"android:gravity="center"android:paddingLeft="5dp"android:paddingRight="15dp"android:text="@string/app_name"android:textColor="@color/color_333333"android:textSize="14sp" /><TextViewandroid:id="@+id/tv_titlebar_more"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_toLeftOf="@id/tv_titlebar_right"android:gravity="center"android:paddingLeft="5dp"android:paddingRight="5dp"android:text="@string/app_name"android:textColor="@color/color_333333"android:textSize="14sp" /></RelativeLayout></LinearLayout>

這里講一下為什么返回按鍵,中間標(biāo)題,右邊兩個(gè)小標(biāo)題都選用了TextView,因?yàn)槲业南敕ㄊ菫榱俗寴?biāo)題欄按鈕是圖標(biāo)的時(shí)候,可以更快捷的使用。畢竟TextView還可以在它的上下左右動(dòng)態(tài)添加Drawable嘛。還有一點(diǎn),為什么選用線性布局中嵌套了一個(gè)相對(duì)布局,那是因?yàn)槲铱紤]到以后可能會(huì)存在需要在標(biāo)題欄下面添加一些類似于間隔啊之類的布局,所以就給預(yù)留出來(lái)了,如果不需要的話,可以選擇去掉外層的線性布局。標(biāo)題欄的右側(cè)我自己是添加了兩個(gè)預(yù)留的按鈕,可以方便右上角存在比如保存、分享之類的操作。

下面貼一下不含標(biāo)題欄的基類BaseActivity的代碼:

/*** Activity基類*/ public class BaseActivity extends FragmentActivity {protected int mResultCode = RESULT_CANCELED;private int mStatusHeight;// 狀態(tài)欄高度private int mTitleHeight;// 標(biāo)題欄高度private int mScreenWidth, mScreenHeight;// 屏幕寬度、高度protected boolean mIsFirst = true;// true-界面第一次聚焦private RequestUploadDialog mUploadDialog;// 加載框@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);ActivityStackUtils.getInstance().pushActivity(this);// activity入棧管理}@Overrideprotected void onResume() {super.onResume();}@Overrideprotected void onPause() {super.onPause();}@Overrideprotected void onStart() {super.onStart();}@Overrideprotected void onStop() {super.onStop();}@Overrideprotected void onDestroy() {super.onDestroy();ActivityStackUtils.getInstance().finishActivity(this);// activity出棧管理}/*** 隱藏鍵盤(pán)*/public void hideKeyBoard() {try {View rootView = this.getWindow().getDecorView();View focusView = rootView.findFocus();if (focusView != null) {int viewId = focusView.getId();View view = findViewById(viewId);if (view instanceof EditText) {InputMethodManager manager = (InputMethodManager) getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE);manager.hideSoftInputFromWindow(view.getWindowToken(), 0);}}} catch (Exception e) {e.printStackTrace();}}/*** 獲取狀態(tài)欄高度* @return 狀態(tài)欄高度(px)*/public int statusHeight() {if (mStatusHeight == 0) {try {Class<?> c = Class.forName("com.android.internal.R$dimen");int x = Integer.parseInt(c.getField("status_bar_height").get(c.newInstance()).toString());mStatusHeight = getResources().getDimensionPixelSize(x);} catch (Exception e1) {e1.printStackTrace();}}return mStatusHeight;}/*** 獲取屏幕寬度* @return 屏幕寬度(px)*/public int screenWidth() {if (mScreenWidth == 0) {DisplayMetrics displayMetrics = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);mScreenWidth = displayMetrics.widthPixels;}return mScreenWidth;}/*** 獲取屏幕高度* @return 屏幕高度(px)*/public int screenHeight() {if (mScreenHeight == 0) {DisplayMetrics displayMetrics = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);mScreenHeight = displayMetrics.heightPixels;}return mScreenHeight;}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_BACK) {return executeKeyDownBack(keyCode, event);}return super.onKeyDown(keyCode, event);}/*** 監(jiān)聽(tīng)返回鍵* @param keyCode 鍵值* @param event 事件* @return true-消耗事件,false-不消耗事件*/protected boolean executeKeyDownBack(int keyCode, KeyEvent event) {return super.onKeyDown(keyCode, event);}/*** Home鍵監(jiān)聽(tīng)回調(diào)方法* @param context 上下文環(huán)境* @param intent 意圖*/public void onHomeWatcherReceiver(Context context, Intent intent) {}/*** 顯示加載框* @param uploadResId 資源ID*/public void showUpload(int uploadResId) {showUpload(getString(uploadResId));}/*** 顯示加載框* @param uploadContent 文本*/public void showUpload(String uploadContent) {if (mUploadDialog == null)mUploadDialog = new RequestUploadDialog(this);mUploadDialog.showText(uploadContent).show();}/*** 隱藏加載框*/public void hideUpload() {if (mUploadDialog == null)return;mUploadDialog.dismiss();}/*** 顯示提示語(yǔ)* @param toastResId 資源ID*/public void showToast(int toastResId) {Toast.makeText(this, toastResId, Toast.LENGTH_SHORT).show();}/*** 顯示提示語(yǔ)* @param toastText 文本*/public void showToast(String toastText) {Toast.makeText(this, toastText, Toast.LENGTH_SHORT).show();}/*** 設(shè)置TextView的left圖片(不添加文字)* @param textView 控件* @param resIds 資源ID*/public void drawableLeft(TextView textView, int resIds) {textView.setVisibility(TextView.VISIBLE);textView.setText("");Drawable drawable = getResources().getDrawable(resIds);drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());textView.setCompoundDrawables(drawable, null, null, null);}/*** 設(shè)置TextView的right圖片(不添加文字)* @param textView 控件* @param resIds 資源ID*/public void drawableRight(TextView textView, int resIds) {textView.setVisibility(TextView.VISIBLE);textView.setText("");Drawable drawable = getResources().getDrawable(resIds);drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());textView.setCompoundDrawables(null, null, drawable, null);}/*** 設(shè)置TextView顏色* @param textView 控件* @param resId 資源ID*/public void textColor(TextView textView, int resId) {textView.setTextColor(getResources().getColor(resId));}/*** 著色狀態(tài)欄(4.4以上系統(tǒng)有效)*/protected void SetStatusBarColor() {StatusBarCompat.setStatusBarColor(this, ContextCompat.getColor(this, R.color.base_color));}/*** 著色狀態(tài)欄(4.4以上系統(tǒng)有效)*/protected void SetStatusBarColor(int color) {StatusBarCompat.setStatusBarColor(this, color);}/*** 沉浸狀態(tài)欄(4.4以上系統(tǒng)有效),全屏模式*/protected void SetTranslanteBar() {StatusBarCompat.translucentStatusBar(this);}@Overridepublic void startActivity(Intent intent) {super.startActivity(intent);overridePendingTransition(R.anim.anim_right2enter, R.anim.anim_left2exit);}/*** 通過(guò) Class 跳轉(zhuǎn)界面,不含參數(shù)**/public void startActivity(Class<?> cls) {startActivity(cls, null);}/*** 含有 Bundle 通過(guò) Class 跳轉(zhuǎn)界面* 帶有跳轉(zhuǎn)動(dòng)畫(huà)**/public void startActivity(Class<?> cls, Bundle bundle) {Intent intent = new Intent();intent.setClass(this, cls);if (bundle != null) {intent.putExtras(bundle);}startActivity(intent);overridePendingTransition(R.anim.anim_right2enter, R.anim.anim_left2exit);}/*** 通過(guò) Class 跳轉(zhuǎn)界面**/public void startActivityForResult(Class<?> cls, int requestCode) {startActivityForResult(cls, null, requestCode);overridePendingTransition(R.anim.anim_right2enter, R.anim.anim_left2exit);}/*** 含有Bundle通過(guò)Class跳轉(zhuǎn)界面**/public void startActivityForResult(Class<?> cls, Bundle bundle,int requestCode) {Intent intent = new Intent();intent.setClass(this, cls);if (bundle != null) {intent.putExtras(bundle);}startActivityForResult(intent, requestCode);overridePendingTransition(R.anim.anim_right2enter, R.anim.anim_left2exit);}/*** 跳轉(zhuǎn)到登錄界面*/public void jumpToLoginActivity(int requestCode) {Intent intent = new Intent(IntentAction.ACTION_LOGIN);startActivityForResult(intent, requestCode);overridePendingTransition(R.anim.anim_bottom_in, R.anim.anim_bottom_window);}@Overridepublic void finish() {super.finish();}/*** finish 當(dāng)前界面,手動(dòng)控制頁(yè)面關(guān)閉動(dòng)畫(huà)** @param closeAnim true:關(guān)閉時(shí)有動(dòng)畫(huà),false:關(guān)閉是無(wú)動(dòng)畫(huà)*/public void finish(boolean closeAnim) {super.finish();if (closeAnim) {overridePendingTransition(R.anim.anim_left2enter, R.anim.anim_right2exit);}}}

里面封裝了一些其他比較常用的方法,有幾個(gè)細(xì)節(jié)的點(diǎn)可以描述一下

1.里面封裝了通用的彈toast和彈加載框的方法,當(dāng)然加載框大家也可以封裝到網(wǎng)絡(luò)請(qǐng)求模塊和本地?cái)?shù)據(jù)庫(kù)操作中去,這個(gè)看個(gè)人的喜好

2.基類中包含有軟鍵盤(pán)的關(guān)閉操作,因?yàn)榘沧康能涙I盤(pán)一直是一個(gè)比較頭疼的問(wèn)題,所以我選擇直接封裝到基類中,如果需要用到某些操作需要關(guān)閉軟鍵盤(pán)的可以直接調(diào)用

3.封裝的有對(duì)某個(gè)TextView添加Drawable的方法,這樣標(biāo)題欄需要加載圖標(biāo)的時(shí)候,方便調(diào)用

4.封裝的有修改狀態(tài)欄顏色和主題的方法,但是StatusBarCompat這個(gè)工具類我沒(méi)有貼出來(lái),不知道其中操作細(xì)節(jié)的可以去網(wǎng)上自行搜索查看

下面就是對(duì)含有標(biāo)題欄的Activity的封裝了,思路文章開(kāi)頭已經(jīng)提到過(guò),就直接上代碼吧:

/*** Activity基類:含TitleBar*/ public class BaseTitleBarActivity extends BaseViewStubActivity {protected TextView mTvCenter, mTvLeft, mTvRight, mTvMore;protected View mViewTitleBar;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);}@Overridepublic void setContentView(int layoutResID) {super.setContentView(layoutResID);}@Overrideprotected void addTitleBarView() {mViewTitleBar = View.inflate(this, addTitleBarLayout(), null);mTvCenter = mViewTitleBar.findViewById(R.id.tv_titlebar_name);mTvLeft = mViewTitleBar.findViewById(R.id.tv_titlebar_left);mTvRight = mViewTitleBar.findViewById(R.id.tv_titlebar_right);mTvMore = mViewTitleBar.findViewById(R.id.tv_titlebar_more);mTvLeft.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {onTitleBarClickLeft(v);}});mTvRight.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {onTitleBarClickRight(v);}});mTvCenter.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {onTitleBarClickCenter(v);}});mTvMore.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {onTitleBarClickMore(v);}});onChangedTitleBar(mTvLeft, mTvCenter, mTvRight);mLayoutContent.addView(mViewTitleBar);}/*** 設(shè)置TitleBar布局* @return TitleBar布局*/protected int addTitleBarLayout() {return R.layout.layout_base_titlebar;}/*** 修改TitleBar* @param left 左邊按鈕* @param center 中間文本* @param right 右邊按鈕,默認(rèn)隱藏*/protected void onChangedTitleBar(TextView left, TextView center, TextView right) {right.setVisibility(View.GONE);mTvMore.setVisibility(View.GONE);}/*** TitleBar左邊按鈕點(diǎn)擊事件* @param view 控件*/protected void onTitleBarClickLeft(View view) {setResult(mResultCode);finish();}/*** TitleBar右邊按鈕點(diǎn)擊事件* @param view 控件*/protected void onTitleBarClickRight(View view) {}/*** TitleBar右邊(更多)按鈕點(diǎn)擊事件* @param view 控件*/protected void onTitleBarClickMore(View view) {}/*** TitleBar中間按鈕點(diǎn)擊事件* @param view 控件*/protected void onTitleBarClickCenter(View view) {}/*** 獲取焦點(diǎn)* @param view 控件*/public void requestFocus(final View view) {view.postDelayed(new Runnable() {@Overridepublic void run() {view.setFocusable(true);view.setFocusableInTouchMode(true);view.requestFocus();}}, 100);} }

BaseViewStubActivity的代碼如下:

/*** Activity基類:不含TitleBar*/ public class BaseViewStubActivity extends BaseActivity {protected LinearLayout mLayoutContent;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);}@Overridepublic void setContentView(int layoutResID) {// 設(shè)置狀態(tài)欄顏色 // SetTranslanteBar();super.setContentView(R.layout.activity_base_titlebar);mLayoutContent = findViewById(R.id.ll_content_view);addTitleBarView(); // 添加TitleBaraddContentView(layoutResID);// 添加ContentView}/*** 添加TitleBar*/protected void addTitleBarView() {}/*** 添加ContentView* @param layoutResID 布局*/protected void addContentView(int layoutResID) {View.inflate(this, layoutResID, mLayoutContent);} }

這里相關(guān)的activity_base_titlebar布局文件如下:

<?xml version="1.0" encoding="utf-8"?> <!-- Activity基類默認(rèn)加載的布局文件 --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayoutandroid:id="@+id/ll_content_view"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"></LinearLayout></RelativeLayout>

這樣一來(lái),使用的時(shí)候只需要繼承自BaseTitlebarActivity并實(shí)現(xiàn)onChangedTitleBar就可以隨意對(duì)標(biāo)題欄進(jìn)行定制化了,對(duì)左上角的按鈕點(diǎn)擊方法是默認(rèn)的對(duì)出操作,如果需要重寫(xiě),也可以自己重新對(duì)該方法進(jìn)行實(shí)現(xiàn),標(biāo)題欄每個(gè)按鈕的點(diǎn)擊操作都是單獨(dú)出來(lái)的,需要點(diǎn)擊操作的時(shí)候再進(jìn)行重寫(xiě)。

效果圖就不上了,談一談封裝過(guò)程中遇到的一個(gè)最主要的問(wèn)題吧

最初在封裝BaseViewStubActivity的時(shí)候addContentView方法中我是使用的

mLayoutContent.addView(View.inflate(this, layoutResID, null));

這種方式進(jìn)行添加,運(yùn)行起來(lái)最初沒(méi)有發(fā)現(xiàn)什么問(wèn)題,但是一旦遇到相對(duì)布局的時(shí)候,需要在底部添加一個(gè)按鈕的時(shí)候,發(fā)現(xiàn)最底部的控件的margin_bottom會(huì)失效,后來(lái)查閱了很多資料,原來(lái)是執(zhí)行這句代碼的時(shí)候,子布局其實(shí)并沒(méi)有掛載到父布局中,所以造成了控件的布局寬高屬性都為默認(rèn)的LayoutParams.WRAP_CONTENT自適應(yīng),不清楚的可以去閱讀以下addView的源碼,所以解決這個(gè)的方法有兩種:

第一種:修改添加子布局的方式為View.inflate(this, layoutResID, mLayoutContent);

第二種:掛載的方式修改為

mLayoutContent.addView(View.inflate(this, layoutResID, null), new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

也就是手動(dòng)賦予子布局一個(gè)布局參數(shù)。

?

補(bǔ)充:

在繼承自BaseTitlebarActivity的activity中同樣也可以調(diào)用addTitleBarLayout方法來(lái)加載另外的標(biāo)題欄布局,但是此時(shí)由于在上一級(jí)基類Activity中已經(jīng)對(duì)標(biāo)題欄進(jìn)行了操作,所以請(qǐng)務(wù)必保持加載的新標(biāo)題欄布局的每個(gè)控件id和通用標(biāo)題欄的控件id一致,否則會(huì)造成空指針異常,當(dāng)然如果只是對(duì)標(biāo)題欄的顏色或者字體顏色那些修改的話,也提供兩種思路,一種是定義另外一個(gè)主題顏色的標(biāo)題欄布局,但是id與通用標(biāo)題欄每個(gè)控件id一致;第二種是在上一級(jí)基類Activity中開(kāi)放另外一個(gè)方法,調(diào)用時(shí)動(dòng)態(tài)更新主題顏色等。

如果有問(wèn)題歡迎指出,非常感謝!

?

總結(jié)

以上是生活随笔為你收集整理的Android封装含有通用标题栏的基类BaseActivity的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。