麻花痒 发表于 2024-10-28 18:21:16

Android导航栏与侧边栏实现(TabLayout+Viewpager2+DrawerLayout)

想要做的效果
https://i-blog.csdnimg.cn/direct/5a635159d0414873afb94516bf7fe587.png
https://i-blog.csdnimg.cn/direct/f716250dc17748e295a56e009b5c7d19.png
目前效果,图标巨细还不太匹配,后续会再更改一下
https://i-blog.csdnimg.cn/direct/11b3f91241b24f11a6a2cda4c3d5ac5b.png
https://i-blog.csdnimg.cn/direct/fa69b01b921f4256a8f7227b5e1f6b2c.png
拆解分析
1导航栏 tablayout+viewpgaer+fragment
下面参考中已写得非常好,不再赘述。
参考
https://blog.csdn.net/W41ted/article/details/123571731
2侧边栏 drawerLayout+toolbar
参考
https://github.com/Li-Xiang-Lan/AndroidSidebar-master
https://blog.csdn.net/cdhahaha/article/details/70208860
图标均来自阿里,可自行查找 https://www.iconfont.cn/
下面是具体实现
1 activity_main xml

主结构为DrawerLayout,用两个FrameLayout分别装载主页内容(导航栏)和侧边栏内容
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:fitsSystemWindows="true"

    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--主页内容-->
    <FrameLayout
      android:id="@+id/content_frame"
      android:layout_width="match_parent"
      android:layout_height="match_parent">
      <include layout="@layout/activity_content"/>
    </FrameLayout>

    <!--侧边栏内容-->
    <FrameLayout
      android:id="@+id/menu_frame"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:layout_gravity="start">
      <include layout="@layout/left_menu"/>
    </FrameLayout>

</androidx.drawerlayout.widget.DrawerLayout>
2 activity_content xml

<?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"
    android:orientation="vertical">

    <!--模拟状态栏占位-->
    <View
      android:id="@+id/view_statusbar"
      android:layout_width="match_parent"
      android:layout_height="1dp"
      android:orientation="horizontal"
      app:layout_constraintTop_toTopOf="parent"/>

    <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:orientation="vertical">
    <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:background="@color/white"
      android:weightSum="8"
      android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
      tools:ignore="MissingConstraints">
    <!--与drawerlayout配合实现更换图标等功能-->
    <androidx.appcompat.widget.Toolbar
      android:layout_weight="1"

      android:id="@+id/toolbar"
      android:layout_width="0dp"
      android:layout_height="?actionBarSize"
      app:layout_constraintTop_toBottomOf="@+id/view_statusbar"
      app:subtitleTextColor="@android:color/white"
      app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
      app:title=" "
      app:titleTextColor="@android:color/white">
    </androidx.appcompat.widget.Toolbar>
      <com.google.android.material.tabs.TabLayout
            android:layout_weight="6"
            android:id="@+id/tab_layout"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:tabIndicatorHeight="0dp"
            app:tabBackground="@color/transparent"
            app:tabRippleColor="@color/transparent"
            app:tabMode="fixed"
            app:tabGravity="fill">
            <com.google.android.material.tabs.TabItem
                android:id="@+id/item_music"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">

            </com.google.android.material.tabs.TabItem>
            <com.google.android.material.tabs.TabItem
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">

            </com.google.android.material.tabs.TabItem>
            <com.google.android.material.tabs.TabItem
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
            </com.google.android.material.tabs.TabItem>

      </com.google.android.material.tabs.TabLayout>

      <ImageView
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:src="@drawable/search"></ImageView>
    </LinearLayout>
    <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="主页内容"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintLeft_toLeftOf="parent"
      app:layout_constraintRight_toRightOf="parent"
      app:layout_constraintTop_toTopOf="parent"/>

    <androidx.viewpager2.widget.ViewPager2
      android:id="@+id/viewpager2"
      android:layout_width="match_parent"
      android:layout_height="match_parent">

    </androidx.viewpager2.widget.ViewPager2>

    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
3 left_menu xml 侧边栏内容

<?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"
    android:background="@android:color/white">

    <androidx.constraintlayout.widget.ConstraintLayout
      android:id="@+id/cl_head_view"
      android:layout_width="match_parent"
      android:layout_height="150dp"
      tools:ignore="MissingConstraints">

      <androidx.appcompat.widget.AppCompatImageView
            android:id="@+id/iv_head"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/test1"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

      <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:text="@string/User"
            android:textColor="@android:color/black"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/iv_head"/>

    </androidx.constraintlayout.widget.ConstraintLayout>

    <LinearLayout
      android:id="@+id/ll_android"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:gravity="center_vertical"
      android:orientation="horizontal"
      android:padding="10dp"
      app:layout_constraintTop_toBottomOf="@+id/cl_head_view">
      <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:drawablePadding="10dp"
            android:gravity="center"
            android:text="随机内容1"/>
    </LinearLayout>

    <LinearLayout
      android:id="@+id/ll_apple"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_marginTop="10dp"
      android:orientation="horizontal"
      android:padding="10dp"
      app:layout_constraintTop_toBottomOf="@+id/ll_android">

      <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:drawablePadding="10dp"
            android:gravity="center"
            android:text="随机内容2"/>
    </LinearLayout>

    <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_marginTop="10dp"
      android:orientation="horizontal"
      android:padding="10dp"
      app:layout_constraintTop_toBottomOf="@+id/ll_apple">
      <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:drawablePadding="10dp"
            android:gravity="center"
            android:text="随机内容3"/>
    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
4 MainActivity java

import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.viewpager2.widget.ViewPager2;
import android.os.Bundle;
import android.view.View;
import com.blueshark.bsplayer.R;
import com.blueshark.bsplayer.util.ScreenInfoUtils;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import com.nineoldandroids.view.ViewHelper;

public class MainActivity extends AppCompatActivity {


    private TabLayout tabLayout;
    private ViewPager2 viewPager2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);

      //初始化布局
      setContentView(R.layout.activity_main);

      //初始化侧边栏
      initsidebar();

      //初始化主页内容
      initcontent();

    }

    private void initsidebar() {
      //隐藏状态栏时,获取状态栏高度
      int statusBarHeight = ScreenInfoUtils.getStatusBarHeight(this);
      //隐藏状态栏
      ScreenInfoUtils.fullScreen(this);
      //初始化状态栏的高度
      View statusbar = (View) findViewById(R.id.view_statusbar);
      ConstraintLayout.LayoutParams params = new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_PARENT, statusBarHeight);
      statusbar.setLayoutParams(params);


      Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
      final DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

      setSupportActionBar(toolbar);//将toolbar与ActionBar关联
      ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawerLayout, toolbar, 0, 0);
      //设置侧边栏图标
      toggle.setDrawerIndicatorEnabled(false);
      toolbar.setNavigationIcon(R.drawable.user);
      //设置图标后点击事件会消失,重新设置点击事件
      toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                drawerLayout.openDrawer(GravityCompat.START);
            }
      });

      drawerLayout.addDrawerListener(toggle);//初始化状态
      toggle.syncState();


      //蒙层颜色
      drawerLayout.setScrimColor(getResources().getColor(R.color.slidegray));
      drawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() {
            @Override
            public void onDrawerStateChanged(int newState) {
            }

            @Override
            public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {
                View mContent = drawerLayout.getChildAt(0);
                View mMenu = drawerView;
                ViewHelper.setTranslationX(mContent, mMenu.getMeasuredWidth() * slideOffset);
            }

            @Override
            public void onDrawerOpened(@NonNull View drawerView) {
            }

            @Override
            public void onDrawerClosed(@NonNull View drawerView) {
            }
      });
    }

    final String[] titleArray = new String[]{"测试1", "测试2", "测试3"};
    final int[] titleItem = new int[]{R.drawable.ic_test,R.drawable.ic_test,R.drawable.ic_test};

    private void initcontent() {
      tabLayout = findViewById(R.id.tab_layout);
      viewPager2 = findViewById(R.id.viewpager2);
      OuterPagerAdapter outerPagerAdapter = new OuterPagerAdapter(this);
      viewPager2.setAdapter(outerPagerAdapter);
      //TabLayout 和 Viewpager2 关联
      TabLayoutMediator tab = new TabLayoutMediator(tabLayout, viewPager2, new TabLayoutMediator.TabConfigurationStrategy() {
            @Override
            public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
            //若settext会在图标下方出现文字
//                tab.setText(titleArray);
                tab.setIcon(titleItem);
            }
      });
      tab.attach();
    }
}
OuterPagerAdapter 和 DynamicFragment 都写得比较简朴,可以根据需求自行扩充
5 OuterPagerAdapter java

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;

import java.util.ArrayList;
import java.util.List;

public class OuterPagerAdapter extends FragmentStateAdapter {
    private final List<Fragment> fragments = new ArrayList<>();

    public OuterPagerAdapter(@NonNull FragmentActivity fragmentActivity) {
      super(fragmentActivity);
      fragments.add(new DynamicFragment());
      fragments.add(new DynamicFragment());
      fragments.add(new DynamicFragment());

    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
      return fragments.get(position);
    }

    @Override
    public int getItemCount() {
      return fragments.size();
    }
}
6 DynamicFragment java

xml只有一个textview,就不再贴了
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
public class DynamicFragment extends Fragment {


    public static DynamicFragment newInstance(String title) {
      DynamicFragment fragment = new DynamicFragment();

      return fragment;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
      View view = inflater.inflate(R.layout.fragment_dynamic, container, false);
      return view;
    }

}

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Android导航栏与侧边栏实现(TabLayout+Viewpager2+DrawerLayout)