標籤:一行代碼 parent 關閉 launcher 狀態 set art back cas
Android5.0出現了一個可以代替ActionBar的控制項ToolBar,使用更加靈活,一般我們使用ToolBar來和DrawerLayout配合使用,官方提供了一個開關類ActionBarDrawerToggle,來實現ToolBar和DrawerLayout的關聯,但是 有時根據我們的需求需要更改左側的表徵圖,不在需要系統預設的三條杠的表徵圖同時點擊表徵圖還想要DrawerLayout的側拉頁面出來,下面講解兩種不同的方式
一:通過代碼來實現改變ToolBar的表徵圖
public class TempActivity extends AppCompatActivity { ActionBarDrawerToggle toggle; private DrawerLayout mDrawerLayout; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.text_tool_bar); initToolBar(); } private void initToolBar() { Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); //設定表徵圖 toolbar.setNavigationIcon(R.drawable.ic_launcher); // 標題 toolbar.setTitle("Title"); //把ToolBar的設定的ActionBar的位置 setSupportActionBar(toolbar); //擷取開關同時讓開關和DrawerLayout關聯在一起 toggle = new ActionBarDrawerToggle(this, mDrawerLayout, 0, 0); getSupportActionBar().setDisplayHomeAsUpEnabled(true); //設定點擊事件,點擊彈出menu介面 mDrawerLayout.setDrawerListener(toggle); } //覆寫方法讓系統判斷點擊的表徵圖後是否彈出側拉頁面 @Override public boolean onOptionsItemSelected(MenuItem item) { toggle.onOptionsItemSelected(item); return super.onOptionsItemSelected(item); }}
這樣就把左側的表徵圖設定成了我們需要的表徵圖,同時點擊表徵圖也可以彈出DrawerLayout的側拉頁面,但是注意:在以上的代碼中少了一行代碼toggle.syncState();作用是將左側小表徵圖和側拉頁面的狀態同步,只有當去掉這一行代碼的時候,這個方法自訂的表徵圖才會顯示
弊端:1.使用代碼來放置表徵圖沒有XML靈活,
2.這種方式不能給表徵圖是指背景選取器
二:通過XML來實現自訂表徵圖(好處是,可以靈活的放置控制項在ToolBar的位置)
使用XML來自訂表徵圖也有兩種方式
方式1:在ToolBar的根節點設定屬性
<android.support.v7.widget.Toolbar app:navigationIcon="@drawable/ic_add_follow" android:id="@+id/tool_bar" android:layout_width="match_parent" android:layout_height="50dp" android:background="@android:color/holo_green_light"> </android.support.v7.widget.Toolbar>
以上的布局中添加了app:navigationIcon=”@drawable/ic_add_follow” 這一行代碼,用來展示表徵圖,注意命名空間不一樣
同樣在代碼中和DrawerLayout關聯覆寫onOptionsItemSelected方法即可完成和側拉頁面的關聯
public class TextActivity extends AppCompatActivity { private ActionBarDrawerToggle toggle; private ImageView toolBarIcon; private DrawerLayout mDrawerLayout; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.text_tool_bar); initToolBar(); } private void initToolBar() { Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); //不顯示標題 toolbar.setTitle(""); setSupportActionBar(toolbar); //把開關和DrawerLayout關聯 toggle = new ActionBarDrawerToggle(this, mDrawerLayout, 0, 0); } //覆寫方法讓系統判斷點擊的表徵圖後是否彈出側拉頁面 @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()){ case android.R.id.home: toggle.onOptionsItemSelected(item); } return super.onOptionsItemSelected(item); }
弊端:一:這種方式雖然可以在布局檔案中來設定表徵圖,但是無法給表徵圖設定選取器
二:由於是在ToolBar的根節點來設定圖片,所以不能只當圖片擺放的位置
優點:直接在XML中指定圖片,而且一行代碼搞定
方式2:通過查看ToolBar發現它繼承了ViewGroup,所以我們可以在ToolBar的裡面來設定子控制項來自訂表徵圖
布局:
<android.support.v7.widget.Toolbar android:id="@+id/tool_bar" android:layout_width="match_parent" android:layout_height="50dp"
android:background="@android:color/holo_green_light"> <ImageView android:layout_gravity="left" android:id="@+id/tool_bar_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher"
android:background="@drawable/selector_infodetail_back_bg"/></android.support.v7.widget.Toolbar>
我們可以設定ImageView的layout_gravity的屬性來指定表徵圖的位置,同時可以給ImageView來設定背景選取器
代碼邏輯:
public class TextActivity extends AppCompatActivity { private ActionBarDrawerToggle toggle; private DrawerLayout mDrawerLayout; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.text_tool_bar); initToolBar(); } private void initToolBar() { //找到表徵圖的id ImageView toolBarIcon = (ImageView) findViewById(R.id.tool_bar_icon); Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); toolbar.setTitle(""); setSupportActionBar(toolbar); //設定監聽 toolBarIcon.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { toggle(); } }); }}
private void toggle() { int drawerLockMode = mDrawerLayout.getDrawerLockMode(GravityCompat.START); if (mDrawerLayout.isDrawerVisible(GravityCompat.START) && (drawerLockMode != DrawerLayout.LOCK_MODE_LOCKED_OPEN)) { mDrawerLayout.closeDrawer(GravityCompat.START); } else if (drawerLockMode != DrawerLayout.LOCK_MODE_LOCKED_CLOSED) { mDrawerLayout.openDrawer(GravityCompat.START); } }
通過這種方式設定的表徵圖就不能通過覆寫onOptionsItemSelected方法的方式來實現側拉頁面的開啟和關閉了,因為表徵圖的id已經不是android.R.id.home,所以只能寫監聽事件來完成側拉頁面的開啟和關閉。
通過查看onOptionsItemSelected的源碼發現系統內部實現方式最終調用的是toggle方法,但是這個方法是私人的我們不能通過對象調用到,發現這個方法中只用到了DrawerLayout的對象,所以就直接將這個方法拷貝到自己的類中來使用,完成了這個效果
弊端:XML中代碼比較多
優點:可以給表徵圖設定狀態選取器,表徵圖的擺放位置比較靈活,還可以放其他的控制項
以上幾種方式都可以實現更改ToolBar表徵圖的需求,根據具體需求選擇最方便的一種
Android ToolBar自訂表徵圖,關聯DrawerLayout