一陌僵、EventBus
1缕溉、什么是EventBus
EventBus is a publish/subscribe event bus for Android and Java.
2、特點(diǎn)優(yōu)勢
simplifies the communication between components
decouples event senders and receivers
performs well with Activities, Fragments, and background threads
avoids complex and error-prone dependencies and life cycle issues
makes your code simpler
is fast
is tiny (~60k jar)
is proven in practice by apps with 1,000,000,000+ installs
has advanced features like delivery threads, subscriber priorities, etc.
3、步驟
1.依賴
implementation 'org.greenrobot:eventbus:3.2.0'
2.定義事件(消息)
public class LoginSuccessEvent {
}
3.定義接收事件的方法
@Subscribe
public void onEvent1(LoginSuccessEvent event) {
Log.i("Simon", "onEvent1");
}
@Subscribe(threadMode = ThreadMode.POSTING)
public void onEvent2(LoginSuccessEvent event) {
Log.i("Simon", "onEvent2");
}
@Subscribe(threadMode = ThreadMode.ASYNC)
public void onEvent3(LoginSuccessEvent event) {
Log.i("Simon", "onEvent3");
}
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onEvent4(LoginSuccessEvent event) {
Log.i("Simon", "onEvent4");
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent5(LoginSuccessEvent event) {
Log.i("Simon", "onEvent5");
}
@Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
public void onEvent6(LoginSuccessEvent event) {
Log.i("Simon", "onEvent6");
}
4.注冊和反注冊
@Override
protected void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
protected void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
5.發(fā)射事件
EventBus.getDefault().post(new LoginSuccessEvent());
4、三要素
Event 事件。它可以是任意類型蛾绎。
Subscriber 事件訂閱者。在EventBus3.0之前我們必須定義以onEvent開頭的那幾個(gè)方法鸦列,分別是onEvent租冠、onEventMainThread、onEventBackgroundThread和onEventAsync薯嗤,而在3.0之后事件處理的方法名可以隨意取顽爹,不過需要加上注解@subscribe(),并且指定線程模型骆姐,默認(rèn)是POSTING镜粤。
Publisher 事件的發(fā)布者。我們可以在任意線程里發(fā)布事件玻褪,一般情況下肉渴,使用EventBus.getDefault()就可以得到一個(gè)EventBus對象,然后再調(diào)用post(Object)方法即可带射。
5同规、線程模型
POSTING
POSTING是默認(rèn)線程模式,在哪個(gè)線程發(fā)送事件就在對應(yīng)線程處理事件窟社,避免了線程切換券勺,效率高。因此灿里,對于不要求是主線程并且耗時(shí)很短的簡單任務(wù)推薦使用該模式关炼。在線程模型為POSTING的事件處理函數(shù)中盡量避免執(zhí)行耗時(shí)操作,因?yàn)樗鼤?huì)阻塞事件的傳遞匣吊,甚至有可能會(huì)引起ANR儒拂。
MAIN
訂閱者方法將在主線程(UI線程)中被調(diào)用寸潦。因此,可以在該模式的訂閱者方法中直接更新UI界面社痛。事件處理的時(shí)間不能太長见转,長了會(huì)導(dǎo)致ANR。
MAIN_ORDERED
訂閱者在主線程中調(diào)用褥影。該事件總是排隊(duì)等待以后交付給訂閱者池户,因此對post的調(diào)用將立即返回。這為事件處理提供了更嚴(yán)格且更一致的順序凡怎,例如校焦,在具有MAIN線程模式的事件處理程序中發(fā)布另一個(gè)事件,則第二個(gè)事件處理程序?qū)⒃诘谝粋€(gè)事件處理程序之前完成统倒,事件處理的時(shí)間不能太長寨典,長了會(huì)導(dǎo)致ANR。
BACKGROUND
訂閱者將在后臺(tái)線程中調(diào)用房匆。如果發(fā)布線程不是主線程耸成,則將在發(fā)布線程中直接調(diào)用事件處理程序方法。如果發(fā)布線程是主線程浴鸿,則EventBus使用單個(gè)后臺(tái)線程井氢,該線程將按順序傳遞其所有事件。在此事件處理函數(shù)中禁止進(jìn)行UI更新操作岳链。
ASYNC
無論事件在哪個(gè)線程中發(fā)布花竞,該事件處理函數(shù)都會(huì)在新建的子線程中執(zhí)行;同樣掸哑,此事件處理函數(shù)中禁止進(jìn)行UI更新操作约急。
6、粘性事件
所謂粘性事件苗分,就是在發(fā)送事件之后再訂閱該事件也能收到該事件厌蔽。請注意這里與普通事件的區(qū)別,普通事件是先注冊在綁定摔癣。
二奴饮、Design的使用
1、什么是Material Design
Material Design 是用于指導(dǎo)用戶在各種平臺(tái)和設(shè)備上進(jìn)行視覺供填、動(dòng)作和互動(dòng)設(shè)計(jì)的全面指南拐云。
Android Design
https://material.io/
https://github.com/material-components
2、Android Design Support Library
是Google在2015年的IO大會(huì)上發(fā)布的全新Material Design支持庫近她,在這個(gè)support庫里面主要包含了 8 個(gè)新的 Material Design組件,最低支持 Android 2.1膳帕。
3粘捎、組件
控件 | 描述 |
---|---|
Snackbar | 提示框 |
FloatingActionButton | MD風(fēng)格的圓形按鈕 |
TextInputLayout EditText | 輔助控件 |
TabLayout | 選項(xiàng)卡 |
NavigationView | DrawerLayout的側(cè)滑界面 |
CoordinatorLayout | 超級FrameLayout |
CollapsingToolbarLayout | 可折疊的MD風(fēng)格ToolbarLayout |
AppBarLayout | MD風(fēng)格的滑動(dòng)Layout |
DrawerLayout | 創(chuàng)建抽屜式導(dǎo)航欄薇缅,即顯示應(yīng)用的主導(dǎo)航菜單的界面面板。當(dāng)用戶從屏幕左邊緣滑動(dòng)手指或點(diǎn)按應(yīng)用欄中的抽屜式導(dǎo)航欄圖標(biāo)時(shí)攒磨,此導(dǎo)航欄就會(huì)顯示 |
1.CoordinatorLayout + AppBarLayout + CollapsingToolbarLayout
androidx.coordinatorlayout.widget.CoordinatorLayout
super-powered FrameLayout
作為頂層布局泳桦;
作為協(xié)調(diào)子 View 之間交互的容器。
com.google.android.material.appbar.AppBarLayout
AppBarLayout is a vertical LinearLayout which implements many of the features of material designs app bar concept, namely scrolling gestures.
com.google.android.material.appbar.CollapsingToolbarLayout
CollapsingToolbarLayout is a wrapper for Toolbar which implements a collapsing app bar. It is designed to be used as a direct child of a AppBarLayout. CollapsingToolbarLayout contains the following features:
依賴
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.1.0'
implementation 'com.google.android.material:material:1.2.1'
layout
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="250dp"
app:collapsedTitleGravity="left"
app:contentScrim="#777777"
app:expandedTitleGravity="bottom|right"
app:title="王賢兵"
android:minHeight="10dp"
app:layout_scrollFlags="scroll">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/hong20"
android:scaleType="fitXY" />
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="60dp"
app:layout_collapseMode="pin" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="#ff0000" />
<ImageView
android:layout_width="match_parent"
android:layout_height="300dp"
android:src="@drawable/ic_launcher_background" />
<View
android:layout_width="wrap_content"
android:layout_height="300dp"
android:background="#0000ff" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
app:layout_scrollFlags屬性
-scroll:所有想滾動(dòng)出屏幕的view都需要設(shè)置這個(gè)flag娩缰,沒有設(shè)置這個(gè)flag的View將會(huì)被固定在屏幕頂部灸撰。
-enterAlways:當(dāng)滑動(dòng)組件向下滾動(dòng)時(shí),標(biāo)題欄會(huì)直接往下滾動(dòng)拼坎。
-enterAlwaysCollapsed:當(dāng)你的視圖已經(jīng)設(shè)置minHeight屬性又使用此標(biāo)志時(shí)浮毯,你的視圖只能已最小高度進(jìn)入,只有當(dāng)滾動(dòng)視圖到達(dá)頂部時(shí)才擴(kuò) 大到完整高度泰鸡。
-exitUntilCollapsed:當(dāng)標(biāo)題欄要往上逐漸“消逝”時(shí)债蓝,會(huì)一直往上滑動(dòng),直到剩下的的高度達(dá)到它的最小高度盛龄,再響應(yīng)滑動(dòng)組件的內(nèi)部滑動(dòng)事件饰迹。
app:layout_behavior屬性
滑動(dòng)的組件必須要設(shè)置此屬性為"@string/appbar_scrolling_view_behavior"
2.DrawerLayout
依賴
implementation "androidx.drawerlayout:drawerlayout:1.1.1"
layout
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/drawer_layout">
<LinearLayout
android:id="@+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff0000"
android:orientation="horizontal" />
<LinearLayout
android:id="@+id/left_layout"
android:layout_width="250dp"
android:layout_height="match_parent"
android:background="#00ff00"
android:orientation="horizontal"
android:layout_gravity="start" />
</androidx.drawerlayout.widget.DrawerLayout>
public class MainActivity extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.drawer_layout);
mDrawerLayout = findViewById(R.id.drawer_layout);
mDrawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() {
@Override
public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {
Log.i("Simon", "onDrawerSlide");
}
@Override
public void onDrawerOpened(@NonNull View drawerView) {
Log.i("Simon", "onDrawerOpened");
}
@Override
public void onDrawerClosed(@NonNull View drawerView) {
Log.i("Simon", "onDrawerClosed");
}
@Override
public void onDrawerStateChanged(int newState) {
Log.i("Simon", "onDrawerStateChanged");
}
});
}
}
對于 DrawerLayout 內(nèi)的界面布局有以下幾個(gè)要求:
1.主界面布局一定要位于所有側(cè)滑界面布局之前,寬度與高度應(yīng)設(shè)置為 match_parent 余舶,并且不能包含 layout_gravity 標(biāo)簽啊鸭。
2.側(cè)滑界面必須設(shè)置 layout_gravity 屬性,且當(dāng)該屬性值為 start 或 left 時(shí)該側(cè)滑界面從左側(cè)滑出匿值,當(dāng)該屬性值為 end 或 right 時(shí)赠制,該側(cè)滑界面從右側(cè)滑出。
3.側(cè)滑界面的高度屬性建議設(shè)定為 match_parent 千扔,寬度屬性建議設(shè)置為一個(gè)常數(shù)憎妙。
4.界面任意一個(gè)垂直邊緣最多允許配置一個(gè)側(cè)滑界面,如果在布局時(shí)為單個(gè)垂直邊緣配置了多個(gè)側(cè)滑界面曲楚,則運(yùn)行時(shí)將引發(fā)異常厘唾。
void closeDrawer(View drawerView) \ 關(guān)閉側(cè)滑界面
void openDrawer(View drawerView) \ 打開側(cè)滑界面
boolean isDrawerOpen(View drawer) \ 判斷側(cè)滑界面是否處于打開狀態(tài)
3.TabLayout
<com.google.android.material.tabs.TabLayout
android:id="@+id/mytab"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
TabLayout tabLayout = (TabLayout) findViewById(R.id.mytab);
tabLayout.addTab(tabLayout.newTab().setText("選項(xiàng)卡一").setIcon(R.mipmap.ic_launcher));
tabLayout.addTab(tabLayout.newTab().setText("選項(xiàng)卡二").setIcon(R.mipmap.ic_launcher));
tabLayout.addTab(tabLayout.newTab().setText("選項(xiàng)卡三").setIcon(R.mipmap.ic_launcher));
tabLayout.addTab(tabLayout.newTab().setText("選項(xiàng)卡四").setIcon(R.mipmap.ic_launcher));
tabLayout.addTab(tabLayout.newTab().setText("選項(xiàng)卡五").setIcon(R.mipmap.ic_launcher));
tabLayout.addTab(tabLayout.newTab().setText("選項(xiàng)卡六").setIcon(R.mipmap.ic_launcher));
3.TextInputLayout
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="userName" />
</com.google.android.material.textfield.TextInputLayout>
4. FloatingActionButton
FAB常用屬性
app:elevation="8dp":陰影的高度,elevation是Android 5.0中引入的新屬性龙誊,設(shè)置該屬性使控件有一個(gè)陰影抚垃,感覺該
控件像是“浮”起來一樣,這樣達(dá)到3D效果趟大。對應(yīng)的方法:setCompatElevation(float)
app:fabSize="normal":FAB的大小鹤树,為normal時(shí),大小為:56 * 56dp 逊朽,為mini時(shí)罕伯,大小為: 40 * 40 dp。
app:backgroundTint="#31bfcf":FAB的背景顏色叽讳。
app:rippleColor="#e7d16b":點(diǎn)擊FAB時(shí)追他,形成的波紋顏色坟募。
app:borderWidth="0dp":邊框?qū)挾龋ǔTO(shè)置為0 邑狸,用于解決Android 5.X設(shè)備上陰影無法正常顯示的問題
app:pressedTranslationZ="16dp":點(diǎn)擊按鈕時(shí)懈糯,按鈕邊緣陰影的寬度,通常設(shè)置比elevation的數(shù)值大!
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/contentView"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/anchorView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_anchor="@id/anchorView"
app:layout_anchorGravity="bottom|right"
android:onClick="onClick"
android:layout_marginRight="10dp"
android:layout_marginBottom="10dp"/>
</android.support.design.widget.CoordinatorLayout>
5.Snackbar
Snackbar.make(findViewById(R.id.button), R.string.app_name, 1000).show();