學習 Android 開發的過程中,UI 控件往往是最直觀也最容易踩坑的部分。本文整理了我在學習《第一行代碼》后的實踐筆記,涵蓋 Toolbar
、自定義標題欄、菜單、Snackbar
、CoordinatorLayout
、可折疊標題欄、SwipeRefreshLayout
下拉刷新、FloatingActionButton
懸浮按鈕 等常見控件的使用方法和心得體會。通過這些總結,希望能幫助你快速掌握 Android 界面開發的核心知識點,讓界面更靈活、更具交互感eve~
Toolbar
Toolbar是什么?
Toolbar
是 Android 5.0)后引入的新控件,用來替代以前的ActionBar
,可以自由控制位置、樣式- 因為是可自定義的,所以比 ActionBar 靈活得多
Toolbar 的常見功能
- 應用標題
默認顯示 App 名稱,你可以改成自定義標題 - 導航按鈕(返回鍵 / 菜單按鈕)
可以添加返回箭頭、菜單按鈕,或者換成你想要的圖標 - 菜單
可以在右上角加“搜索”“更多”等按鈕 - 完全自定義布局
Toolbar 內部可以放 TextView、ImageView,甚至自定義控件
Toolbar的使用(配合菜單)
- 可以直接在layout布局文件中使用:
<Toolbarandroid:layout_width="match_parent"android:layout_height="40dp"android:id = "@+id/toolbar"android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"app:popupTheme = "@style/ThemeOverlay.AppCompat.Dark"app:layout_constraintTop_toTopOf="parent"android:title="你好"></Toolbar>
以上代碼中有兩個較為陌生的屬性:
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar
"代表頂部導航欄的主題顏色
@style/ThemeOverlay.AppCompat.Dark.ActionBar
代表白色字體圖標;@style/ThemeOverlay.AppCompat.Light
表示深色字體圖標
app:popupTheme = "@style/ThemeOverlay.AppCompat.Dark"
表示菜單的主體顏色
@style/ThemeOverlay.AppCompat.Light
→ 白色彈窗
@style/ThemeOverlay.AppCompat.Dark
→ 深色彈窗
app:navigationIcon
設置左上角的導航圖標(常見是返回箭頭)
菜單項這樣來寫:
<itemandroid:id="@+id/it1"android:icon="@drawable/ic_launcher_background"android:title="TODO"app:showAsAction = "always"></item>
<itemandroid:id="@+id/it2"android:icon="@drawable/ic_launcher_foreground"android:title="TOD1"app:showAsAction = "ifRoom"></item>
<itemandroid:id="@+id/it3"android:title="TOD2"android:icon="@drawable/ic_launcher_foreground"app:showAsAction = "never"></item>
app:showAsAction = "always"
代表表現的方式:
always
代表一定要顯示在頂部導航欄,否則不顯示
ifRoom
代表如果能顯示顯示,不能顯示就去菜單項
never
一定在菜單項
最后把菜單項膨脹到視圖,一定要使用這個方法,因為有菜單時,系統會回調這個方法;
public boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.toolbai,menu);return true;
}
public boolean onOptionsItemSelected(MenuItem item) {if (item.getItemId() == R.id.action_search) {Toast.makeText(this, "點擊了搜索", Toast.LENGTH_SHORT).show();return true;}return super.onOptionsItemSelected(item);
}
設置toolbar
Toolbar toolbars = (Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbars);
設置導航按鈕(返回箭頭)
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbars.setNavigationOnClickListener(v -> finish());
注意:toolbar最好使用androidx
androidx.appcompat.widget.Toolbar
使用Androidx的toolbar時需要添加依賴,依賴如下:
implementation 'androidx.appcompat:appcompat:1.6.1'
當然我們也可以自定義toolbar,在toolbar中自定義控件:
Toolbar toolbar = findViewById(R.id.custom_toolbar);
setSupportActionBar(toolbar);
// 去掉系統默認標題,使用我們自己的 TextView
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setDisplayShowTitleEnabled(false)
;核心就是設置后setSupportActionBar的這一句代碼,我們就可以使用自定義控件了,那么具體怎么自定義,那就看你想要什么樣子的效果啦;
不過需要注意一點,這里只是去掉了默認的標題,所以系統默認的標題不顯示了,但是我們仍然可以使用其他方法,比如設置返回圖標;
好了,Toolbar的簡單學習先到這里;
FloatingActionButton
這是懸浮按鈕,我們可以做點擊事件
在xml文件中簡單使用如下
<com.google.android.material.floatingactionbutton.FloatingActionButtonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="bottom|right"android:layout_margin="20dp"android:id = "@+id/fa"android:elevation="2dp"android:src = "@drawable/ic_launcher_foreground"/>
屬性解釋:
android:elevation="2dp"
數值越大,陰影面積大,但淺,反之則相反;
android:src = "@drawable/ic_launcher_foreground"
可用來添加圖片
Snackbar
一個功能類似toast提示框,與toast不同的是,可以和用戶交互
floatingActionButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Snackbar.make(view,"嘿嘿",Snackbar.LENGTH_LONG).setAction("確定", new View.OnClickListener() {@Overridepublic void onClick(View view) {Toast.makeText(MainActivity.this,"雪雪學安卓",Toast.LENGTH_SHORT).show();}}).show();}
});
Snackbar.make(view,"嘿嘿",Snackbar.LENGTH_LONG);
-
make方法是確認提示主體,第一個參數是界面任意一個view,snackbar會自動選擇最上層那一個,第二個參數是提示語
-
setAction方法
通過setaction方法和用戶交互,第一個參數是按鈕效果,第二個參數做監聽
最后別忘記show()!
CoordinatorLayout布局
這個布局和幀布局差不多
但是它可以監聽所有的子控件,從而做出最佳響應:比如懸浮按鈕和提示框重合問題
需要注意的是:
那前提得是子控件,所以提示框傳入的view參數得是coordinatorlayout的子控件了;
glide依賴如下
implementation 'com.github.bumptech.glide:glide:4.16.0'
Recycleview進階版
可能照片資源過大,所以這個時候就需要它了;
依賴如下:
implementation 'com.github.bumptech.glide:glide:4.16.0'
Glide.with(mcontext).load(fruit.getImageid()).into(holder.imageView);
第一個參數是context,第二個是把這個id加載到第三個參數的布局中;
GridLayoutManager layoutManager = new GridLayoutManager(this,2);
代表兩列
<androidx.coordinatorlayout.widget.CoordinatorLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"><com.google.android.material.appbar.AppBarLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><androidx.appcompat.widget.Toolbarandroid:layout_width="match_parent"android:layout_height="40dp"android:id = "@+id/toolbar"android:theme="@style/Widget.AppCompat.Light.ActionBar"app:popupTheme = "@style/ThemeOverlay.AppCompat.Light"app:layout_scrollFlags="scroll|enterAlways|snap"app:layout_constraintTop_toTopOf="parent"android:title="你好"></androidx.appcompat.widget.Toolbar></com.google.android.material.appbar.AppBarLayout><androidx.recyclerview.widget.RecyclerViewandroid:layout_width="match_parent"android:layout_height="match_parent"app:layout_behavior="@string/appbar_scrolling_view_behavior"android:id="@+id/recy"></androidx.recyclerview.widget.RecyclerView>
陌生屬性介紹:
-
com.google.android.material.appbar.AppBarLayout
這個布局為了頂部導航欄的顯示; -
app:layout_behavior="@string/appbar_scrolling_view_behavior"
為了頂部導航欄的顯示,否則可能遮擋頂部導航欄; -
app:layout_scrollFlags="scroll|enterAlways|snap"
scroll
作用:視圖會隨著內容滾動而一起滾動(向上滑時隱藏,向下滑時顯示)
enterAlways
作用:
向下滾動時立即顯示視圖(不需要滾動到頂部)
snap
作用: 滾動停止時自動"吸附"到最近的邊界(要么完全顯示,要么完全隱藏, 提供更流暢的用戶體驗)
exitUntilCollapsed
作用:
- 視圖會滾動退出,但不會完全消失,而是停留在折疊狀態
- 必須與
scroll
標志一起使用 - 需要定義
minHeight
屬性指定折疊后的高度
我們通常是scroll
和exitUntilCollapsed
搭配使用!
SwipeRefreshLayout下拉刷新
依賴:
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
xml文件:用法包在recyview外面表示刷新
<androidx.swiperefreshlayout.widget.SwipeRefreshLayoutandroid:layout_width="match_parent"app:layout_behavior="@string/appbar_scrolling_view_behavior"android:id = "@+id/swip"android:layout_height="match_parent"><androidx.recyclerview.widget.RecyclerViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:id="@+id/recy"></androidx.recyclerview.widget.RecyclerView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
在mainactivity
我把過程中難以理解的代碼都標注出來啦
SwipeRefreshLayout swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swip);
swipeRefreshLayout.setColorSchemeColors(R.color.black);//刷新的顏色
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
//每次刷新都會回調@Overridepublic void onRefresh() {//經常得到數據之后,開始刷新,所以要在子線程中new Thread(new Runnable() {@Overridepublic void run() {try {Thread.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}//回到主線程中runOnUiThread(new Runnable() {@Overridepublic void run() {//適配器刷新Notifyfruitadapots.notifyDataSetChanged();//表示刷新事件結束,隱藏刷新進度條swipeRefreshLayout.setRefreshing(false);}});}}).start();}
});
可折疊式表示欄
CoordinatorLayout
這是最外層的布局
然后你需要把你的用于折疊的照片,還有頂部導航欄,都設置在**appbarlayout
**布局中
<com.google.android.material.appbar.AppBarLayoutandroid:layout_height="250dp"android:layout_width="match_parent"android:id = "@+id/appbar"><com.google.android.material.appbar.CollapsingToolbarLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:id = "@+id/coll"android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"app:contentScrim="?attr/colorPrimary"app:layout_scrollFlags="snap|scroll|exitUntilCollapsed"><ImageViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:id = "@+id/iv"app:layout_collapseMode="parallax"android:scaleType="centerCrop"></ImageView><androidx.appcompat.widget.Toolbarandroid:layout_width="match_parent"android:layout_height="50dp"android:id = "@+id/toolbar"app:layout_collapseMode="pin"></androidx.appcompat.widget.Toolbar></com.google.android.material.appbar.CollapsingToolbarLayout></com.google.android.material.appbar.AppBarLayout>
定義在CollapsingToolbarLayout
-
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
代表設置一個主題 -
app:contentScrim="?attr/colorPrimary"
代表這個布局在趨于折疊和折疊后的背景色 -
app:layout_scrollFlags="snap|scroll|exitUntilCollapsed"
是appbarlayout
中的屬性
app:layout_collapseMode="parallax"
表示折疊模式
有三種折疊模式:
Pin
代表在折疊時永不消失,這里代表頂部導航欄,在折疊會回固定在頂部,通常和toolbar一起聯合使用;
parallax
模式(視差模式)
效果:控件以較慢速度滾動,產生景深效果,我們還可以設置它的滾動的速度,更有感覺。
滾動的速度通過此來控制,數值越小,速度越慢:
app:layout_collapseParallaxMultiplier="0.7"
默認
模式(無模式)
效果:控件會隨滾動完全消失,一般不設置,無折疊效果。
中間內容:經常是recycleview等等
<androidx.core.widget.NestedScrollViewandroid:layout_width="match_parent"android:layout_height="match_parent"app:layout_behavior="@string/appbar_scrolling_view_behavior"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"><androidx.cardview.widget.CardViewandroid:layout_width="match_parent"android:id = "@+id/card"app:cardCornerRadius="4dp"android:layout_margin="10dp"android:layout_height="wrap_content"><TextViewandroid:layout_width="match_parent"android:id = "@+id/tv"android:layout_height="wrap_content"></TextView></androidx.cardview.widget.CardView></LinearLayout></androidx.core.widget.NestedScrollView>
app:layout_behavior="@string/appbar_scrolling_view_behavior"
這個屬性搭配折疊效果;
NestedScrollView**
只能有一個直接子項布局**
體會
編者對于在運用折疊式標題欄時有了一些新的體會:
- 當你在某控件中設置
parallax
,即使折疊后仍然顯示當前折疊時的背景,它不會因為折疊就直接消失顯示pin模式下的控件,假如parallax
設置的是背景圖,那么背景圖會和pin
模式下的視圖重疊,直接你看不到是因為通常toobar
設置的是pin
,toolbar
的會擋住背景圖,當你嘗試把toolbar
設置為透明時,你會發現有重合的問題qvq; - 折疊后的高度由誰決定?
AI中會解釋道:由toolbar
的高度決定,但你仔細看,你就會發現是由使用pin模式的控件決定的,因為toolbar
設置了pin
,所以AI才會這樣解釋,當我們toolbar
中的設置為100dp,那么折疊后的高度就是100dp了;此時又發現一個屬性minheigh
(控制CollapsingToolbarLayout
的最小可見高度),它也會影響高度,當它的高度大于PIN
模式下控件的高度時,那么此時折疊后的高度就是minheight
了,所以如果是minHeight
比toolbar
的高度要高,最后的結果就是上面是toolbar
,折疊后仍然留有一部分高度是minheight
的剩余高度; - 可折疊模式寫在
coll
布局的直接子view中; - 當有很多空間都設置了
pin
模式,按照在xml文件中的排布在頂部依次顯示; - 可折疊式標題欄的核心:
最外層是coor
的一個布局
中間套appbarlayout
負責響應滑動:android:fitsSystemWindows="true"
這里這個屬性true
代表toolbar
在狀態欄下方,避免系統的窗口區域和布局重疊;
里面是coll
的一個布局:里面寫兩個重要屬性:app:layout_scrollFlags
,控制滾動的效果,app:contentScrim
折疊后顯示的背景色(不寫會出現透明/白色突兀問題);
在未折疊的布局中寫屬性控制折疊后的效果;
在內容區例如recycleview
或者scroll
中寫app:layout_behavior="@string/appbar_scrolling_view_behavior"
不然滑動不會帶動 AppBar
折疊;
希望編者的理解對你有幫助哦!
懸浮按鈕升級版
<com.google.android.material.floatingactionbutton.FloatingActionButtonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="16dp"app:layout_anchor="@id/appbar"app:layout_anchorGravity="bottom|end"></com.google.android.material.floatingactionbutton.FloatingActionButton>
app:layout_anchor="@id/appbar"
錨定誰
app:layout_anchorGravity="bottom|end"
錨定誰的哪里
anchor
錨點:
這么設置就會出現在標題欄的區域內
另外:
collapsingToolbarLayout.setTitle("i like");
這里也可以設置折疊后導航欄的標題,搭配頂部導航欄的使用;
本次分享到這里結束!