TabLayout实现类似网易选项卡的动态滑动效果
1.配置build.gradle
在开启这个项目的时候一定记得要配置build.gradle.
这个项目里面会要用到recyclerview和cardview
,所以一定要记得导包,不然就会报错。
代码如下:
compile 'com.android.support:appcompat-v7:26.1.0'
compile 'com.android.support:design:26.1.0'
compile 'com.android.support:recyclerview-v7:26.1.0'
compile 'com.android.support:cardview-v7:26.1.0'
2.主界面的布局
主界面的代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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=".TabLayoutActivity"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicatorColor="#ADBE107E"
app:tabMode="scrollable"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</LinearLayout>
代码里面的大部分大家都懂,我就来讲一下几个新学的把。
android.support.design.widget.TabLayout 标签中的 app:tabMode="scrollable’ 设置 Tab 的模式为"可滑动的”;app:tabMode=”fixed”,表示固定不可滑动的。
Java代码
FragmentAdapter主要处理了两件:一件事就是根据不同的position来返回不同的 Fgment;另一件事就是根据不同的position来返回不同的title。代码如下:
public class FragmentAdapter extends FragmentStatePagerAdapter {
private List<Fragment> mFragments;
private List<String> mTitles;
public FragmentAdapter(FragmentManager fm, List<Fragment> fragments, List<String> titles) {
super(fm);
mFragments = fragments;
mTitles = titles;
}
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
@Override
public int getCount() {
return mFragments.size();
}
@Override
public CharSequence getPageTitle(int position) {
return mTitles.get(position);
}
}
我们用了自己创建的ListFragment作为每个Tab的界面,接下来我们就来看一下ListFragment是怎么定义的吧。
public class ListFragment extends Fragment {
private RecyclerView mRecyclerView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mRecyclerView =
(RecyclerView) inflater.inflate(R.layout.list_fragment, container, false);
return mRecyclerView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mRecyclerView.setLayoutManager(new LinearLayoutManager(mRecyclerView.getContext()));
mRecyclerView.setAdapter(new RecyclerViewAdapter(getActivity()));
}
}
其他的代码大家都知道,我就不多说了。
用NavigationView来实现抽屉菜单界面
页面布局
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/dl_main_drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="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=".TabLayoutActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicatorColor="#ADBE107E"
app:tabMode="scrollable" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="@+id/nv_main_navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/navigation_header"
app:menu="@menu/drawer_view" />
</android.support.v4.widget.DrawerLayout>
DrawerLayout标签包含了主界面的布局以及抽屉的布局,这个抽屉界面就是Navigation,Navigation标签下的。app:headerLayout="@layout/navigation_header"就是引用头部文件,app:menu="@menu/drawer_view" 就是引入菜单的布局。
接下来我们就来看一下头部文件吧。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="150dp"
android:background="?attr/colorPrimaryDark"
android:orientation="horizontal"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="50dp"
android:background="@drawable/ic_user" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:text="Liuwangshu"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:textSize="20sp" />
</LinearLayout>
头部就只包含了ImageView显示图片跟TextView显示文字。
接下来我们就来看一下菜单文件吧。
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_home"
android:icon="@drawable/ic_dashboard"
android:title="首页" />
<item
android:id="@+id/nav_messages"
android:icon="@drawable/ic_event"
android:title="事项" />
<item
android:id="@+id/nav_friends"
android:icon="@drawable/ic_headset"
android:title="音乐" />
<item
android:id="@+id/nav_discussion"
android:icon="@drawable/ic_forum"
android:title="消息" />
</group>
</menu>
所有菜单元素都放在group标签之下,他用
group android:checkableBehavior="single"表明每次只有一个被选中。
在以上界面的基础上添加如下代码,就可以为Item添加子菜单来实现带有头部的分组效果。
<item android:title="其他">
<menu>
<item
android:icon="@drawable/ic_dashboard"
android:title="设置" />
<item
android:icon="@drawable/ic_dashboard"
android:title="关于我们" />
</menu>
</item>
Java代码
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tab_layout);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final ActionBar ab = getSupportActionBar();
ab.setHomeAsUpIndicator(R.drawable.ic_menu);
ab.setDisplayHomeAsUpEnabled(true);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
mDrawerLayout = (DrawerLayout) findViewById(R.id.dl_main_drawer);
NavigationView navigationView =
(NavigationView) findViewById(R.id.nv_main_navigation);
if (navigationView != null) {
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
// 改变item选中状态
menuItem.setChecked(true);
String title = menuItem.getTitle().toString();
Toast.makeText(getApplicationContext(), title, Toast.LENGTH_SHORT).show();
//关闭导航菜单
mDrawerLayout.closeDrawers();
return true;
}
});
}
initViewPager();
}
我们用setNavigationItemSelectedListener()方法来设置当导航项被点击时的回调。在回调方法 onNavigationItemSelected(MenuItem menultem)中会向我们提供被选中的 Menultem,得到 的Menultem对象就可以处理Menultem相关的功能,比如获取标题(String title = menuItem.getTitle().toString();)等。通过这个回调也可以改变item选中状态、关闭导航菜单,以及其他操作。
同时要对Toolbar的菜单选项进行监听回调,否则抽屉就出不来了。具体代码如下所示:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_overaction, menu);
return true;
}
return super.onOptionItemSelected(item);