Android--- Drawer and Tab Navigation
Tab Navigation — View Pager+ Fragment + TabLayout
关于ViewPager
- ViewPager是一个可以实现横向滑动的组件, 如图片横向滑动和页面横向滑动
ViewPager2
- ViewPager2内部实现是RecyclerView,所以ViewPager2的性能更高
- ViewPager2可以实现竖向滑动,ViewPager只能横向滑动。
- ViewPager2模式实现了懒加载,默认不进行预加载。内部是通过Lifecycle 对 Fragment 的生命周期进行管理。ViewPager会进行预加载,懒加载需要我们自己去实现
- ViewPager2只有一个adapter,FragmentStateAdapter继承自RecyclerView.Adapter。
而ViewPager有两个adapter,FragmentStatePagerAdapter和FragmentPagerAdapter,均是继承PagerAdapter
Tab Navigation
- 定义布局文件
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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"
tools:context=".activity.MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/Theme.EatWhat.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/mainTabBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toBottomOf="@id/mainTabBar"
app:layout_behavior="@string/appbar_scrolling_view_behavior" >
</androidx.viewpager.widget.ViewPager>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginEnd="@dimen/fab_margin"
android:layout_marginBottom="16dp"
app:srcCompat="@drawable/ic_baseline_add_24" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
- 构建Adapter
package com.example.eatwhat.adapter;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import com.example.eatwhat.mainActivityFragments.NotesFragment;
import com.example.eatwhat.mainActivityFragments.RestaurantFragment;
import com.example.eatwhat.mainActivityFragments.TodaysFragment;
public class MainTabAdapter extends FragmentPagerAdapter {
private Context myContext;
private FragmentManager myManager;
int totalTabs;
public MainTabAdapter(Context context, FragmentManager fm, int totalTabs) {
super(fm);
myManager = fm;
myContext = context;
this.totalTabs = totalTabs;
}
@NonNull
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
RestaurantFragment restaurantFragment = new RestaurantFragment();
return restaurantFragment;
case 1:
NotesFragment notesFragment = new NotesFragment();
return notesFragment;
case 2:
TodaysFragment todaysFragment = new TodaysFragment();
return todaysFragment;
default:
return null;
}
}
@Override
public int getCount() {
return totalTabs;
}
}
- 在Activit中构建Tab
private void createTabsFragment() {
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setNavigationIcon(R.drawable.ic_baseline_menu_24);
tabLayout = (TabLayout) findViewById(R.id.mainTabBar);
viewPager = (ViewPager) findViewById(R.id.viewPager);
tabLayout.addTab(tabLayout.newTab().setText("Restaurants"));
tabLayout.addTab(tabLayout.newTab().setText("Posts"));
tabLayout.addTab(tabLayout.newTab().setText("Today's"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
final MainTabAdapter adapter = new MainTabAdapter(this, getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
Drawer Navigation
- 定义menu布局
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group
android:id="@+id/drawer_menu_top"
android:checkableBehavior="none">
<item android:id="@+id/drawer_home"
android:checkable="true"
android:title="Home"
android:icon="@drawable/drawer_home_24"/>
<item android:id="@+id/drawer_profile"
android:checkable="true"
android:title="My Profile"
android:icon="@drawable/drawer_myprofile_24"
/>
<item android:id="@+id/drawer_postes"
android:checkable="true"
android:title="My Posts"
android:icon="@drawable/drawer_reviewhistory_24"
/>
<item android:id="@+id/drawer_collected_restaurant"
android:checkable="true"
android:title="Collected Restaurant"
android:icon="@drawable/drawer_myposts_24"
/>
<item android:id="@+id/drawer_liked_Post"
android:checkable="true"
android:title="Liked Post"
android:icon="@drawable/ic_baseline_thumb_up_24"
/>
</group>
<group
android:id="@+id/drawer_menu_bottom"
android:checkableBehavior="none">
<item android:id="@+id/drawer_logout"
android:checkable="true"
android:title="Log out"
android:icon="@drawable/drawer_logout_24"
/>
</group>
</menu>
- 定义Header布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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"
>
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/drawer_avatar"
android:layout_width="90dp"
android:layout_height="90dp"
android:layout_gravity="center"
android:layout_marginTop="20sp"
android:src="@mipmap/eatwhat_logo"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/drawer_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="20sp"
android:textIsSelectable="true"
android:text="Group 4"
android:textAppearance="?attr/textAppearanceHeadline6"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/drawer_avatar" />
</androidx.constraintlayout.widget.ConstraintLayout>
- 定义drawer布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
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"
tools:context=".activity.MainActivity"
tools:openDrawer="start"
android:id="@+id/drawer_layout"
>
<include
layout="@layout/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<com.google.android.material.navigation.NavigationView
android:id="@+id/drawer_view"
app:menu="@menu/drawer_menu"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/drawer_header"
/>
</androidx.drawerlayout.widget.DrawerLayout>
- Activity中构建drawer
private void createDrawer() {
setContentView(R.layout.drawer_layout);
myDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
myNavigationView = (NavigationView) findViewById(R.id.drawer_view);
myNavigationView.setNavigationItemSelectedListener(this);
}
- Activity重写onOptionsItemSelected
- 实现点击左上角图标打开drawer navigation
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case android.R.id.home:
myDrawerLayout.openDrawer(GravityCompat.START);
return true;
}
return super.onOptionsItemSelected(item);
}
- Activity实现 NavigationView.OnNavigationItemSelectedListener接口
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch(item.getItemId()) {
case R.id.drawer_home:
myDrawerLayout.closeDrawer(GravityCompat.START);
return true;
case R.id.drawer_profile:
Intent toProfile = new Intent(this, ProfileActivity.class);
startActivityForResult(toProfile, USER_NAME_CODE);
return true;
case R.id.drawer_postes:
Intent toMyNotes = new Intent(this, MyNotesActivity.class);
startActivity(toMyNotes);
return true;
case R.id.drawer_logout:
FirebaseAuth.getInstance().signOut();
Intent logoutIntent = new Intent(this, SignInActivity.class);
startActivity(logoutIntent);
finish();
return true;
case R.id.drawer_collected_restaurant:
Intent toCollected = new Intent(this, CollectedRestaurantActivity.class);
startActivity(toCollected);
return true;
case R.id.drawer_liked_Post:
Intent toLikedNotes = new Intent(this, LikedNotesActivity.class);
startActivity(toLikedNotes);
return true;
}
return false;
}
|