Android 一步步教你从ActionBar迁移到ToolBar
谷歌的材料设计也发布了有一段时间了,包括官方的support库 相信大家也熟悉了不少,今天就把actionbar 迁移到toolbar的 经验发出来。
这个地方要注意 我用的图标都是studio里的一个插件提供的,我随便选的图标,大家知道意思就行 不要在意图标的意义。。。。。。美术不好 见谅。。
先上一个actionbar的demo,里面基本上包括了actionbar的主要功能点。
比如 菜单,二级菜单,一键返回主界面,action provider,tab,和searchview的结合 等。
主界面的代码:
1 package com.example.administrator.actionbartest; 2 3 import android.app.ActionBar; 4 import android.app.Activity; 5 import android.os.Bundle; 6 import android.view.Menu; 7 import android.view.MenuItem; 8 import android.widget.Toast; 9 10 public class MainActivity extends Activity { 11 12 13 @Override 14 protected void onCreate(Bundle savedInstanceState) { 15 super.onCreate(savedInstanceState); 16 setContentView(R.layout.activity_main); 17 getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 18 ActionBar.Tab tab1 = getActionBar().newTab().setText("艺术家").setTabListener(new TabListener<AritistFragment>(this, "artist", AritistFragment.class)); 19 ActionBar.Tab tab2 = getActionBar().newTab().setText("专辑名").setTabListener(new TabListener<AlbumFragment>(this, "album", AlbumFragment.class)); 20 ActionBar.Tab tab3 = getActionBar().newTab().setText("公司名").setTabListener(new TabListener<CompanyFragment>(this, "company", CompanyFragment.class)); 21 getActionBar().addTab(tab1); 22 getActionBar().addTab(tab2); 23 getActionBar().addTab(tab3); 24 25 26 } 27 28 @Override 29 public boolean onCreateOptionsMenu(Menu menu) { 30 // Inflate the menu; this adds items to the action bar if it is present. 31 getMenuInflater().inflate(R.menu.menu_main, menu); 32 33 34 return super.onCreateOptionsMenu(menu); 35 } 36 37 38 @Override 39 public boolean onOptionsItemSelected(MenuItem item) { 40 // Handle action bar item clicks here. The action bar will 41 // automatically handle clicks on the Home/Up button, so long 42 // as you specify a parent activity in AndroidManifest.xml. 43 int id = item.getItemId(); 44 String msg = ""; 45 switch (id) { 46 case R.id.action_search: 47 msg = "action_search"; 48 break; 49 case R.id.action_intent: 50 msg = "action_intent"; 51 break; 52 case R.id.action_settings: 53 msg = "action_settings"; 54 break; 55 default: 56 break; 57 58 } 59 Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); 60 61 return super.onOptionsItemSelected(item); 62 } 63 }
manifest文件
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="com.example.administrator.actionbartest"> 4 5 <application 6 android:allowBackup="true" 7 android:icon="@mipmap/ic_launcher" 8 android:label="@string/app_name" 9 android:logo="@drawable/ic_account_circle_red_300_18dp" 10 android:theme="@android:style/Theme.Holo.Light"> 11 <activity 12 android:name=".MainActivity" 13 android:label="@string/app_name"> 14 <intent-filter> 15 <action android:name="android.intent.action.MAIN" /> 16 17 <category android:name="android.intent.category.LAUNCHER" /> 18 </intent-filter> 19 </activity> 20 <activity 21 android:name=".Main2Activity" 22 android:label="@string/title_activity_main2"></activity> 23 <activity 24 android:name=".Main3Activity" 25 android:label="@string/title_activity_main3" 26 android:parentActivityName=".MainActivity"> 27 28 </activity> 29 </application> 30 31 </manifest>
tablistener
1 package com.example.administrator.actionbartest; 2 3 import android.app.ActionBar; 4 import android.app.Activity; 5 import android.app.Fragment; 6 import android.app.FragmentTransaction; 7 8 /** 9 * Created by Administrator on 2015/8/14. 10 */ 11 public class TabListener<T extends Fragment> implements ActionBar.TabListener { 12 13 private Fragment fragment; 14 private final Activity mActivity; 15 private final String mTag; 16 private final Class<T> mClass; 17 18 public TabListener(Activity mActivity, String mTag, Class<T> mClass) { 19 this.mActivity = mActivity; 20 this.mTag = mTag; 21 this.mClass = mClass; 22 } 23 24 @Override 25 public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) { 26 27 if (fragment == null) { 28 fragment = Fragment.instantiate(mActivity, mClass.getName()); 29 ft.add(android.R.id.content, fragment, mTag); 30 31 } else { 32 ft.attach(fragment); 33 } 34 35 36 } 37 38 @Override 39 public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) { 40 if (fragment != null) { 41 ft.detach(fragment); 42 } 43 } 44 45 @Override 46 public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) { 47 48 } 49 }
自定义的actionprovider
1 package com.example.administrator.actionbartest; 2 3 import android.content.Context; 4 import android.view.ActionProvider; 5 import android.view.MenuItem; 6 import android.view.SubMenu; 7 import android.view.View; 8 import android.widget.Toast; 9 10 /** 11 * Created by Administrator on 2015/8/14. 12 */ 13 public class MyActionProvider extends ActionProvider { 14 15 16 private Context context; 17 18 public MyActionProvider(Context context) { 19 super(context); 20 this.context = context; 21 22 } 23 24 @Override 25 public View onCreateActionView() { 26 return null; 27 } 28 29 @Override 30 public boolean hasSubMenu() { 31 return true; 32 } 33 34 @Override 35 public void onPrepareSubMenu(SubMenu subMenu) { 36 subMenu.clear(); 37 subMenu.add("sub item1").setIcon(R.drawable.ic_queue_black_18dp).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { 38 @Override 39 public boolean onMenuItemClick(MenuItem item) { 40 Toast.makeText(context, "item1", Toast.LENGTH_SHORT).show(); 41 42 return false; 43 } 44 } 45 ); 46 47 subMenu.add("sub item2").setIcon(R.drawable.ic_account_circle_red_300_18dp).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { 48 @Override 49 public boolean onMenuItemClick(MenuItem item) { 50 Toast.makeText(context, "item2", Toast.LENGTH_SHORT).show(); 51 52 return false; 53 } 54 } 55 ); 56 57 58 super.onPrepareSubMenu(subMenu); 59 } 60 }
最后是菜单布局
1 <menu xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 tools:context=".MainActivity"> 4 5 <item 6 android:id="@+id/action_search" 7 android:actionViewClass="android.widget.SearchView" 8 android:icon="@drawable/ic_queue_black_18dp" 9 android:showAsAction="ifRoom|collapseActionView" 10 android:title="search" /> 11 <item 12 android:id="@+id/action_intent" 13 android:actionProviderClass="com.example.administrator.actionbartest.MyActionProvider" 14 android:icon="@drawable/ic_account_circle_red_300_18dp" 15 android:showAsAction="ifRoom" 16 android:title="share" /> 17 <item 18 android:id="@+id/delete" 19 android:icon="@drawable/ic_picture_in_picture_black_18dp" 20 android:showAsAction="ifRoom" 21 android:title="delete" /> 22 23 24 <!-- 永远显示在overflow中--> 25 <item 26 android:id="@+id/action_settings" 27 android:showAsAction="never" 28 android:title="@string/action_settings" /> 29 </menu>
然后我们来看看toolbar 怎么做。以及他们之间的区别。实际上你仔细观察以后就能发现,toolbar 比actionbar 效果更好,尤其是增加了很多动画效果。
此外toolbar 是没有tab的,他需要结合support库里的tablayout来完成原来actionbar里的tab功能。除此之外,你在使用toolbar的时候要先屏蔽掉
actionbar否则会报错。另外就是toolbar实际上放在哪都是可以的,actionbar 则固定在顶端位置。另外就是一些xml文件的参数在写的时候要多注意
前缀。最后就是同样一个类 不要用4.x自带的,要用v4 或者v7的,不然会有很多错。
主界面代码
1 package com.example.administrator.toolbartest; 2 3 import android.os.Bundle; 4 import android.support.design.widget.TabLayout; 5 import android.support.v4.app.Fragment; 6 import android.support.v4.app.FragmentManager; 7 import android.support.v4.app.FragmentStatePagerAdapter; 8 import android.support.v4.view.MenuItemCompat; 9 import android.support.v4.view.ViewPager; 10 import android.support.v7.app.AppCompatActivity; 11 import android.support.v7.widget.Toolbar; 12 import android.view.Menu; 13 import android.view.MenuItem; 14 import android.widget.Toast; 15 16 public class MainActivity extends AppCompatActivity { 17 18 private Toolbar toolbar; 19 20 private TabLayout tabLayout; 21 22 23 private ViewPager viewPager; 24 25 private PagerAdapter adapter; 26 27 @Override 28 protected void onCreate(Bundle savedInstanceState) { 29 super.onCreate(savedInstanceState); 30 setContentView(R.layout.activity_main); 31 toolbar = (Toolbar) this.findViewById(R.id.toolBar); 32 tabLayout = (TabLayout) this.findViewById(R.id.tabLayout); 33 tabLayout.addTab(tabLayout.newTab().setText("Tab 1")); 34 tabLayout.addTab(tabLayout.newTab().setText("Tab 2")); 35 tabLayout.addTab(tabLayout.newTab().setText("Tab 3")); 36 tabLayout.setTabGravity(TabLayout.GRAVITY_FILL); 37 viewPager = (ViewPager) findViewById(R.id.viewpager); 38 adapter = new PagerAdapter 39 (getSupportFragmentManager(), tabLayout.getTabCount()); 40 viewPager.setAdapter(adapter); 41 viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout)); 42 tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { 43 @Override 44 public void onTabSelected(TabLayout.Tab tab) { 45 viewPager.setCurrentItem(tab.getPosition()); 46 } 47 48 @Override 49 public void onTabUnselected(TabLayout.Tab tab) { 50 51 } 52 53 @Override 54 public void onTabReselected(TabLayout.Tab tab) { 55 56 } 57 }); 58 toolbar.setTitle("ToolBar"); 59 60 setSupportActionBar(toolbar); 61 //有些语句得写在setSupportActionBar 之后才有效果 62 63 toolbar.setNavigationIcon(R.drawable.ic_account_circle_red_500_18dp); 64 toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { 65 66 67 @Override 68 public boolean onMenuItemClick(MenuItem menuItem) { 69 int id = menuItem.getItemId(); 70 String msg = ""; 71 switch (id) { 72 case R.id.action_search: 73 msg = "action_search"; 74 break; 75 case R.id.action_intent: 76 msg = "action_intent"; 77 //这个地方要注意使用这种方式增加actionprovider不然会报错 78 MenuItemCompat.setActionProvider(menuItem, new MyActionProvider(MainActivity.this)); 79 break; 80 default: 81 break; 82 83 } 84 Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show(); 85 86 return false; 87 } 88 }); 89 } 90 91 class PagerAdapter extends FragmentStatePagerAdapter { 92 93 int numOfTabs; 94 95 public PagerAdapter(FragmentManager fm, int numOfTabs) { 96 super(fm); 97 this.numOfTabs = numOfTabs; 98 } 99 100 @Override 101 public Fragment getItem(int position) { 102 103 switch (position) { 104 case 0: 105 TabFragment1 tab1 = new TabFragment1(); 106 return tab1; 107 case 1: 108 TabFragment2 tab2 = new TabFragment2(); 109 return tab2; 110 case 2: 111 TabFragment3 tab3 = new TabFragment3(); 112 return tab3; 113 default: 114 return null; 115 } 116 } 117 118 @Override 119 public int getCount() { 120 return numOfTabs; 121 } 122 } 123 124 125 @Override 126 public boolean onCreateOptionsMenu(Menu menu) { 127 // Inflate the menu; this adds items to the action bar if it is present. 128 getMenuInflater().inflate(R.menu.menu_main, menu); 129 return true; 130 } 131 132 @Override 133 public boolean onOptionsItemSelected(MenuItem item) { 134 // Handle action bar item clicks here. The action bar will 135 // automatically handle clicks on the Home/Up button, so long 136 // as you specify a parent activity in AndroidManifest.xml. 137 138 return super.onOptionsItemSelected(item); 139 } 140 }
主界面布局文件
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 tools:context=".MainActivity"> 6 7 8 <android.support.v7.widget.Toolbar 9 android:id="@+id/toolBar" 10 android:layout_width="match_parent" 11 android:layout_height="wrap_content" 12 android:background="?attr/colorPrimary" 13 android:minHeight="?attr/actionBarSize"></android.support.v7.widget.Toolbar> 14 15 <android.support.design.widget.TabLayout 16 android:id="@+id/tabLayout" 17 android:layout_width="match_parent" 18 android:layout_height="wrap_content" 19 android:layout_below="@id/toolBar" 20 android:background="?attr/colorPrimary"></android.support.design.widget.TabLayout> 21 22 <android.support.v4.view.ViewPager 23 android:id="@+id/viewpager" 24 android:layout_width="match_parent" 25 android:layout_height="match_parent" 26 android:layout_below="@id/tabLayout" /> 27 28 29 </RelativeLayout>
manifest配置文件
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="com.example.administrator.toolbartest" > 4 5 <application 6 android:allowBackup="true" 7 android:icon="@mipmap/ic_launcher" 8 android:label="@string/app_name" 9 android:theme="@style/AppTheme" > 10 <activity 11 android:name=".MainActivity" 12 android:label="@string/app_name" > 13 <intent-filter> 14 <action android:name="android.intent.action.MAIN" /> 15 16 <category android:name="android.intent.category.LAUNCHER" /> 17 </intent-filter> 18 </activity> 19 </application> 20 21 </manifest>
用于屏蔽actionbar的style文件
1 <resources> 2 3 <!-- Base application theme. --> 4 <style name="AppTheme" parent="AppTheme.Base"> 5 <!-- Customize your theme here. --> 6 </style> 7 8 <style name="AppTheme.Base" parent="Theme.AppCompat"> 9 <item name="windowActionBar">false</item> 10 <item name="windowNoTitle">true</item> 11 <!-- Actionbar color --> 12 <item name="colorPrimary">@color/material_blue_grey_800</item> 13 <!--Status bar color--> 14 <item name="colorPrimaryDark">@color/accent_material_light</item> 15 <!--Window color--> 16 <item name="android:windowBackground">@color/dim_foreground_material_dark</item> 17 18 19 </style> 20 21 22 </resources>
自定义的actionprovider 其实这个和actionbar的那个相比 只是引用的actionprovider不一样罢了。这个是用的v4包里的
1 package com.example.administrator.toolbartest; 2 3 import android.content.Context; 4 import android.support.v4.view.ActionProvider; 5 import android.util.Log; 6 import android.view.MenuItem; 7 import android.view.SubMenu; 8 import android.view.View; 9 import android.widget.Toast; 10 11 /** 12 * Created by Administrator on 2015/8/14. 13 */ 14 public class MyActionProvider extends ActionProvider { 15 16 17 private Context context; 18 19 public MyActionProvider(Context context) { 20 super(context); 21 this.context = context; 22 23 } 24 25 @Override 26 public View onCreateActionView() { 27 return null; 28 } 29 30 @Override 31 public boolean hasSubMenu() { 32 return true; 33 } 34 35 @Override 36 public void onPrepareSubMenu(SubMenu subMenu) { 37 Log.v("burning","onPrepareSubMenu"); 38 subMenu.clear(); 39 subMenu.add("sub item1").setIcon(R.drawable.ic_add_shopping_cart_red_500_18dp).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { 40 @Override 41 public boolean onMenuItemClick(MenuItem item) { 42 Toast.makeText(context, "item1", Toast.LENGTH_SHORT).show(); 43 44 return false; 45 } 46 } 47 ); 48 49 subMenu.add("sub item2").setIcon(R.drawable.ic_assignment_ind_red_500_18dp).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { 50 @Override 51 public boolean onMenuItemClick(MenuItem item) { 52 Toast.makeText(context, "item2", Toast.LENGTH_SHORT).show(); 53 54 return false; 55 } 56 } 57 ); 58 59 60 super.onPrepareSubMenu(subMenu); 61 } 62 }
然后看一下 菜单文件
1 <menu xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:app="http://schemas.android.com/apk/res-auto" 3 xmlns:tools="http://schemas.android.com/tools" 4 tools:context=".MainActivity"> 5 6 <item 7 android:id="@+id/action_settings" 8 android:orderInCategory="100" 9 android:title="@string/action_settings" 10 app:showAsAction="never" /> 11 12 <!-- 注意这个地方searchview的写法和actionbar的不同 如果用actionbar的写法会有很多错误--> 13 <item 14 android:id="@+id/action_search" 15 android:icon="@drawable/ic_redeem_red_500_18dp" 16 android:title="search" 17 app:actionViewClass="android.support.v7.widget.SearchView" 18 app:showAsAction="ifRoom|collapseActionView" /> 19 20 <item 21 android:id="@+id/action_intent" 22 android:actionProviderClass="com.example.administrator.toolbartest.MyActionProvider" 23 android:icon="@drawable/ic_account_balance_red_500_18dp" 24 app:showAsAction="ifRoom" 25 android:title="share" /> 26 <!-- 27 <item 28 android:id="@+id/delete" 29 android:icon="@drawable/ic_picture_in_picture_black_18dp" 30 android:showAsAction="ifRoom" 31 android:title="delete" /> 32 --> 33 34 </menu>
基本上就是这些异同了。注释写的不多,因为比较简单。最后如果你要更改一些自定义效果 一定要多看源码里的style文件
那个里面包含一切,只是谷歌的话很多你会查不到 因为这东西刚出来不久。