1.实现功能概述
2.代码实现
1.实现功能概述
实现了滑动更换页面同时切换底部Tab的图标、文字的颜色,同时也支持点击底部Tab达到切换页面的效果,有点类似微信首页布局
外带实现toolbar overflow菜单显示图标。
2.代码实现
2.1 效果截图(资源来源于网络,做学习所用若有不妥指出,反正我也改不了)
2.2 主布局actvity_main.xml<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:toolbar="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.viewpager.MainActivity"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" toolbar:popupTheme="@style/OverflowTheme" android:layout_width="match_parent" android:background="@color/customColorPrimary" android:layout_height="?actionBarSize"> </android.support.v7.widget.Toolbar> <android.support.v4.view.ViewPager android:layout_weight="1" android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="0dp" android:layout_above="@+id/bottom_tab_layout"> </android.support.v4.view.ViewPager> <LinearLayout android:layout_alignParentBottom="true" android:orientation="horizontal" android:background="#000" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="5dp" android:id="@+id/bottom_tab_layout"> <!--消息tab--> <LinearLayout android:orientation="vertical" android:layout_weight="1" android:layout_width="0dp" android:id="@+id/msg_layout" android:layout_height="wrap_content"> <ImageView android:id="@+id/msg_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:src="@drawable/msg_green"/> <TextView android:id="@+id/msg_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="消息" android:layout_gravity="center" android:textSize="14sp" android:textColor="@color/tabTextColorGreen"/> </LinearLayout> <!--应用tab--> <LinearLayout android:id="@+id/all_layout" android:orientation="vertical" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content"> <ImageView android:id="@+id/all_icon" android:layout_gravity="center" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/all_white"/> <TextView android:id="@+id/all_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="应用" android:layout_gravity="center" android:textSize="14sp" android:textColor="@color/tabTextColor"/> </LinearLayout> <!--折扣tab--> <LinearLayout android:orientation="vertical" android:layout_weight="1" android:layout_width="0dp" android:id="@+id/sale_layout" android:layout_height="wrap_content"> <ImageView android:id="@+id/sale_icon" android:layout_gravity="center" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/sale"/> <TextView android:id="@+id/sale_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="折扣" android:layout_gravity="center" android:textSize="14sp" android:textColor="@color/tabTextColor"/> </LinearLayout> <!--时间线tab--> <LinearLayout android:id="@+id/timeline_layout" android:orientation="vertical" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content"> <ImageView android:id="@+id/timeline_icon" android:layout_gravity="center" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/timeline_white"/> <TextView android:id="@+id/timeline_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="时间线" android:layout_gravity="center" android:textSize="14sp" android:textColor="@color/tabTextColor"/> </LinearLayout> </LinearLayout> </LinearLayout>
2.3 菜单布局toolbar_menu.xml
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" tools:context=".MainActivity"> <!-- 属性用法: android:title="":设置自定义action的标题文字,放入action flow中时只显示文字 android:orderInCategory="":表示action在app bar上显示的顺序,值越小越靠前 android:icon="":设置显示的图标 app:showAsAction="ifRoom":设置显示的位置,ifRoom(有空间显示,没空间显示到overflow) never(一直显示到overflow),alaways(一直显示在app bar上), withText(设置图标和文字一起显示) actionViewClass:可以设置替换toolbar中Action Button的控件 --> <!--查询按钮--> <item android:id="@+id/action_search" android:title="@string/action_search" android:orderInCategory="1" android:actionViewClass="android.widget.SearchView" android:icon="@drawable/search_24" app:showAsAction="ifRoom|collapseActionView" /> <!--分享--> <item android:id="@+id/action_share" android:title="@string/action_share" android:orderInCategory="2" app:showAsAction="ifRoom|withText" android:icon="@drawable/share_24" /> <!--设置--> <item android:id="@+id/action_setting" android:title="@string/action_setting" android:orderInCategory="3" app:showAsAction="never|withText" android:icon="@drawable/back" /> <!--更多--> <item android:id="@+id/action_more" android:title="@string/action_more" android:orderInCategory="4" app:showAsAction="never|withText" android:icon="@drawable/share_24b" /> </menu>
2.4 主布局类MainActivity.java
package com.example.viewpager; import android.os.Bundle; import android.support.v4.view.MenuItemCompat; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewConfiguration; import android.view.Window; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity implements View.OnClickListener,ViewPager.OnPageChangeListener { private Toolbar toolbar; private ViewPager viewPager; private ImageView allImage,msgImage,timelineImage,saleImage; private TextView allText,msgText,timelineText,saleText; private LinearLayout allLayout,msgLayout,timelineLayout,saleLayout; private List<View> pages; private CustomViewPagerAdapter customViewPagerAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化控件 initView(); //初始化viewpager页面 initPages(); //设置总是显示Overflow setAlwaysShowOverflow(); //设置toolbar toolbar.setTitle("ViewPager"); setSupportActionBar(toolbar); //toolbar menu设置监听 toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { Toast.makeText(MainActivity.this,item.getTitle().toString(),Toast.LENGTH_SHORT).show(); return false; } }); //初始化自定义适配器 customViewPagerAdapter = new CustomViewPagerAdapter(pages); //设置adapter viewPager.setAdapter(customViewPagerAdapter); //设置监听 allLayout.setOnClickListener(this); msgLayout.setOnClickListener(this); timelineLayout.setOnClickListener(this); saleLayout.setOnClickListener(this); viewPager.setOnPageChangeListener(this); } /* * 初始化viewpager页面 * */ private void initPages() { pages = new ArrayList<View>(); View page01 = View.inflate(MainActivity.this,R.layout.viewpager01,null); View page02 = View.inflate(MainActivity.this,R.layout.viewpager02,null); View page03 = View.inflate(MainActivity.this,R.layout.viewpager03,null); View page04 = View.inflate(MainActivity.this,R.layout.viewpager04,null); pages.add(page01); pages.add(page02); pages.add(page03); pages.add(page04); } /* *创建选项菜单 * */ @Override public boolean onCreateOptionsMenu(Menu menu) { Log.d("run","onCreateOptionsMenu"); //通过menu布局加载器将定义的menu xml适配到overflow显示 MenuInflater menuInflater = getMenuInflater(); menuInflater.inflate(R.menu.toolbar_menu,menu); //判断menu是否为空,如果不为空则通过反射获取setOptionalIconsVisible()方法 //并实现overflow菜单显示icon,类似于下面public boolean onMenuOpened( // int featureId, Menu menu) {}方法中实现,不过区别在于,他们的执行时间不同。 if (menu != null) { //获取MenuBuilder类 if (menu.getClass().getSimpleName().equals("MenuBuilder")) { //打印全类名和简单类名,可以看看他们长啥样 Log.d("debug",menu.getClass().getSimpleName()); Log.d("debug",menu.getClass().getName()); try { //获取类中的返回值为boolean类型的setOptionalIconsVisible方法 Method m = menu.getClass().getDeclaredMethod( "setOptionalIconsVisible", Boolean.TYPE); //设置该方法是可接近的,可操作的 m.setAccessible(true); //设置Icon显示 m.invoke(menu, true); } catch (Exception e) { e.printStackTrace(); } } } /* //获取到添加Action View的菜单项,并设置监听操作,在这里可能和菜单监听事件有冲突,没有进行测试 MenuItem searchItem = menu.findItem(R.id.action_search); //添加action行为 MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() { @Override public boolean onMenuItemActionExpand(MenuItem item) { Toast.makeText(MainActivity.this,"你可以搜索啦",Toast.LENGTH_SHORT).show(); return false; } @Override public boolean onMenuItemActionCollapse(MenuItem item) { Toast.makeText(MainActivity.this,"你离开了我,宝宝不开心",Toast.LENGTH_SHORT).show(); return false; } });*/ return true; } /* * 继承该方法通过反射实现点击物理Menu键后弹出的菜单显示icon * */ @Override public boolean onMenuOpened(int featureId, Menu menu) { Log.d("run","onMenuOpened"); Log.d("param",featureId+""); if (menu != null) { if (menu.getClass().getSimpleName().equals("MenuBuilder")) { Log.d("debug",menu.getClass().getSimpleName()); Log.d("debug",menu.getClass().getName()); try { Method m = menu.getClass().getDeclaredMethod( "setOptionalIconsVisible", Boolean.TYPE); m.setAccessible(true); m.invoke(menu, true); } catch (Exception e) { e.printStackTrace(); } } } return super.onMenuOpened(featureId, menu); } /* * 设置一直显示Overflow为了避免有硬件Menu键的时候菜单会从底部弹出 * */ public void setAlwaysShowOverflow() { try { ViewConfiguration config = ViewConfiguration.get(this); if (config.hasPermanentMenuKey()) { Field menuKeyField = ViewConfiguration.class .getDeclaredField("sHasPermanentMenuKey"); if (menuKeyField != null) { menuKeyField.setAccessible(true); menuKeyField.setBoolean(config, false); Log.d("setAlwaysShowOverflow", menuKeyField.toString()); } } } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } } /* * 初始化控件方法 * */ private void initView() { toolbar = (Toolbar) findViewById(R.id.toolbar); viewPager = (ViewPager) findViewById(R.id.viewpager); allImage = (ImageView) findViewById(R.id.all_icon); allText = (TextView) findViewById(R.id.all_tv); msgImage = (ImageView) findViewById(R.id.msg_icon); msgText = (TextView) findViewById(R.id.msg_tv); timelineImage = (ImageView) findViewById(R.id.timeline_icon); timelineText = (TextView) findViewById(R.id.timeline_tv); saleImage = (ImageView) findViewById(R.id.sale_icon); saleText = (TextView) findViewById(R.id.sale_tv); allLayout = (LinearLayout) findViewById(R.id.all_layout); timelineLayout = (LinearLayout) findViewById(R.id.timeline_layout); saleLayout = (LinearLayout) findViewById(R.id.sale_layout); msgLayout = (LinearLayout) findViewById(R.id.msg_layout); } /* * 实现tab点击监听 * */ @Override public void onClick(View v) { resumeTab(); switch (v.getId()){ case R.id.all_layout: allImage.setImageResource(R.drawable.all_green); allText.setTextColor(getResources().getColor(R.color.tabTextColorGreen)); viewPager.setCurrentItem(1); break; case R.id.sale_layout: saleImage.setImageResource(R.drawable.sale_green); saleText.setTextColor(getResources().getColor(R.color.tabTextColorGreen)); viewPager.setCurrentItem(2); break; case R.id.timeline_layout: timelineImage.setImageResource(R.drawable.time_green); timelineText.setTextColor(getResources().getColor(R.color.tabTextColorGreen)); viewPager.setCurrentItem(3); break; case R.id.msg_layout: msgImage.setImageResource(R.drawable.msg_green); msgText.setTextColor(getResources().getColor(R.color.tabTextColorGreen)); viewPager.setCurrentItem(0); break; default: break; } } /* * 将底部的tab颜色恢复全灰 * */ private void resumeTab() { allImage.setImageResource(R.drawable.all_white); msgImage.setImageResource(R.drawable.msg_white); timelineImage.setImageResource(R.drawable.time_white); saleImage.setImageResource(R.drawable.sale); allText.setTextColor(getResources().getColor(R.color.tabTextColor)); msgText.setTextColor(getResources().getColor(R.color.tabTextColor)); timelineText.setTextColor(getResources().getColor(R.color.tabTextColor)); saleText.setTextColor(getResources().getColor(R.color.tabTextColor)); } /* * 继承自ViewPager.OnPageChangeListener接口 * 实现页面滑动的事件监听 * */ @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } /* * 继承自ViewPager.OnPageChangeListener接口 * 实现页面选中后的事件监听 * */ @Override public void onPageSelected(int position) { resumeTab(); switch (position){ case 0: msgImage.setImageResource(R.drawable.msg_green); msgText.setTextColor(getResources().getColor(R.color.tabTextColorGreen)); break; case 1: allImage.setImageResource(R.drawable.all_green); allText.setTextColor(getResources().getColor(R.color.tabTextColorGreen)); break; case 2: saleImage.setImageResource(R.drawable.sale_green); saleText.setTextColor(getResources().getColor(R.color.tabTextColorGreen)); break; case 3: timelineImage.setImageResource(R.drawable.time_green); timelineText.setTextColor(getResources().getColor(R.color.tabTextColorGreen)); break; default: break; } } /* * 继承自ViewPager.OnPageChangeListener接口 * 实现页面滑动状态改变的事件监听 * */ @Override public void onPageScrollStateChanged(int state) { } }
2.5 自定义的adapter类CustomViewPagerAdapter.java
package com.example.viewpager; import android.support.v4.view.PagerAdapter; import android.view.View; import android.view.ViewGroup; import java.util.List; /** * Created by elimy on 2016-09-11. */ public class CustomViewPagerAdapter extends PagerAdapter { List<View> pages; public CustomViewPagerAdapter(List<View> pages){ this.pages = pages; }; /* * 获取页面数量 * */ @Override public int getCount() { return pages.size(); } /* *判断类型是否匹配 * */ @Override public boolean isViewFromObject(View view, Object object) { return object==view; } /* * 加载page * */ @Override public Object instantiateItem(ViewGroup container, int position) { View view = pages.get(position); container.addView(view); return view; } /* * 移除page * */ @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(pages.get(position)); } }
2.6 viewPager布局viewpager01.java(其他viewpager页面布局类似,就不一一给出了)
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/page01_back"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:textSize="18sp" android:textColor="@color/contentTextColor" android:text="你有新消息请注意查收"/> </RelativeLayout>