ViewPager+Fragment+DrawableLayout 实现页面水平滑动与侧滑抽屉布局

1. 设计目标

因为最近做课设,需要实现水平滑动页面和侧滑打开侧边栏功能,于是把这两个功能合在一起写了个demo。
实现的功能主要有:水平滑动和点击底部按钮切换页面,侧滑菜单拉出与监听。

2. 思路简介

2.1 ViewPager + Fragment

ViewPager 对象具有内置滑动手势来切换页面,并且默认显示屏幕滑动动画,因此无需再额外实现手势识别和创建自己的动画,直接使用即可。ViewPager 使用 PagerAdapter 对象提供要显示的新页面,因此需要创建的 Fragment 类。在Fragment类里加载页面的layout,并返回View。同时需要重写TabFragmentPagerAdapter类对Frament进行管理。在屏幕底部添加两个Button监听点击事件进行Frament切换。为了提高用户体验,在屏幕顶部增加了标题栏来告知用户当前所在页面,屏幕底部在Button也有高亮的字体提示用户当前所在页面。

2.2 DrawableLayout + NavigationView

drawerLayout是一个布局控件,跟LinearLayout等控件是一样的,只是drawerLayout带有滑动的功能。只要按照drawerLayout的规定布局方式写完布局,就能有侧滑的效果。其中在编写过程需要注意:1.必须设置layout_gravity属性,它表示侧滑菜单是在左边还是右边,这里选择了start,表示跟随系统语言判断左右(汉语往左)。2.NavigationView需要在布局文件的最下面,可能会被其他布局给覆盖到导致无法监听。
NavigationView可以很方便的实现Drawable的菜单页面,只需要把它放在DrawerLayout里,再通过它把需要跳转的页面设置进去即可。

3.实现方法

3.1 activity_main布局

  • 为了能侧滑,应把drawerLayout放在最外层。
  • NavigationView需要在布局文件的最下面,可能会被其他布局给覆盖到导致无法监听
<?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:custom="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="0dp"
        android:paddingLeft="0dp"
        android:paddingRight="0dp"
        android:paddingTop="0dp"
        >

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:background="@color/cpb_blue"
                >

                <LinearLayout
                    android:orientation="horizontal"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:layout_gravity="center_vertical">


                </LinearLayout>

                <LinearLayout
                    android:orientation="horizontal"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:id="@+id/textView_topTitle"
                        android:text="安卓课设"
                        android:textSize="25dp"
                        android:textColor="@color/white"
                        android:layout_gravity="center_vertical"
                        android:textAlignment="center"
                        custom:ignore="RtlCompat" />
                </LinearLayout>

                <LinearLayout
                    android:orientation="horizontal"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <LinearLayout
                        android:orientation="horizontal"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:layout_weight="1"></LinearLayout>


                </LinearLayout>

            </LinearLayout>
            <androidx.viewpager.widget.ViewPager
                android:id="@+id/myViewPager"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:layout_marginLeft="0dp">
                <FrameLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:id="@+id/content"></FrameLayout>
            </androidx.viewpager.widget.ViewPager>
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:layout_gravity="bottom"
                android:background="@color/lightgrey">

                <Button
                    android:id="@+id/button_manage"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginLeft="40dp"
                    android:layout_weight="1"
                    android:background="@drawable/main_button_bg"
                    android:text="管理系统"
                    android:textAlignment="center"
                    android:textSize="15dp" />

                <Button
                    android:id="@+id/button_status"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginRight="40dp"
                    android:layout_weight="1"
                    android:background="@drawable/main_button_bg"
                    android:text="状态查询"
                    android:textSize="15dp" />

            </LinearLayout>

        </LinearLayout>
    </RelativeLayout>
    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_gravity="start"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:menu="@menu/nav_menu"
        app:headerLayout="@layout/nav_header"/>
</androidx.drawerlayout.widget.DrawerLayout>


3.2两个Fragment子页面与侧滑菜单布局

activity_status:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="状态查询"
    android:id="@+id/textView_status"
    android:textSize="25dp"
    tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>

activity_manage:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="管理系统"
        android:id="@+id/textView_manage"
        android:textSize="25dp"
        tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>

nav_header:

<?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="180dp"
    android:padding="10dp"
    android:background="?attr/colorPrimary">

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/icon_image"
        android:layout_width="132dp"
        android:layout_height="90dp"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="15dp"
        android:layout_marginLeft="15dp"
        android:layout_marginTop="9dp"
        android:src="@drawable/head" />

    <TextView
        android:id="@+id/username"
        android:layout_width="307dp"
        android:layout_height="35dp"
        android:layout_below="@id/icon_image"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentBottom="true"
        android:layout_marginStart="15dp"
        android:layout_marginLeft="15dp"
        android:layout_marginTop="6dp"
        android:layout_marginBottom="30dp"
        android:text="lan"
        android:textColor="@color/black"
        android:textSize="18sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/mail"
        android:layout_width="356dp"
        android:layout_height="wrap_content"


        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:layout_marginStart="15dp"
        android:layout_marginLeft="15dp"
        android:layout_marginEnd="53dp"

        android:layout_marginRight="53dp"
        android:layout_marginBottom="5dp"
        android:text="[email protected]"
        android:textColor="@color/black"
        android:textSize="14sp" />

</RelativeLayout>

在res目录下新建一个menu文件夹,存放nav_menu:

<?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_call"
            android:icon="@drawable/nav_call"
            android:title="Call" />
        <item
            android:id="@+id/nav_friends"
            android:icon="@drawable/nav_friends"
            android:title="Friends" />
        <item
            android:id="@+id/nav_location"
            android:icon="@drawable/nav_location"
            android:title="Location" />
        <item
            android:id="@+id/nav_mail"
            android:icon="@drawable/nav_mail"
            android:title="Mail" />
        <item
            android:id="@+id/nav_task"
            android:icon="@drawable/nav_task"
            android:title="Tasks" />
    </group>
</menu>

3.3 建立两个Fragment类加载布局和建立TabFragmentPagerAdapter类管理Fragment

Fragment_Manage:

package com.example.test7;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.fragment.app.Fragment;

public class Fragment_Manage extends Fragment {
    
    
    public View onCreateView(LayoutInflater inflater , ViewGroup container, Bundle savedInstanceState){
    
    
        View view=inflater .inflate(R.layout.activity_manage ,container,false) ;

        return view;
    }
}

Fragment_status:

package com.example.test7;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.fragment.app.Fragment;

public class Fragment_Staus extends Fragment {
    
    
    public View onCreateView(LayoutInflater inflater , ViewGroup container, Bundle savedInstanceState){
    
    
        View view=inflater .inflate(R.layout.activity_status ,container,false) ;

        return view;
    }
}

TabFragmentPagerAdapter:

package com.example.test7;


import android.view.ViewGroup;

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;

import java.util.List;

public class TabFragmentPagerAdapter extends FragmentPagerAdapter {
    
    
    private List<Fragment> mlist;


    public TabFragmentPagerAdapter(FragmentManager fm, List<Fragment> list) {
    
    
        super(fm);
        this.mlist = list;
    }

    @Override
    public void setPrimaryItem(ViewGroup container, int position, Object object) {
    
    
        super.setPrimaryItem(container, position, object);
    }

    @Override
    public Fragment getItem(int arg0) {
    
    
        return mlist.get(arg0);//显示第几个页面
    }

    @Override
    public int getCount() {
    
    
        return mlist.size();//有几个页面
    }
}

3.4 MainActivity

package com.example.test7;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
import androidx.viewpager.widget.ViewPager;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.material.navigation.NavigationView;

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



public class MainActivity extends AppCompatActivity {
    
    

    private List<Fragment> list;
    private ViewPager myViewPager;
    private TabFragmentPagerAdapter adapter;

    private TextView  topTitle;


    private Button bt_status;
    private Button bt_manage;

    private NavigationView navView;
    private DrawerLayout myDrawerLayout;

    private ColorStateList cl_blue;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }
    private void initView()
    {
    
    
        //绑定点击事件
        bt_status=(Button)  findViewById(R.id.button_status ) ;
        bt_manage =(Button)  findViewById(R.id.button_manage ) ;
        topTitle =(TextView)  findViewById(R.id.textView_topTitle ) ;
        myViewPager = (ViewPager) findViewById(R.id.myViewPager);
        myViewPager.setOnPageChangeListener(new MyPagerChangeListener()) ;

        navView = findViewById(R.id.nav_view);
        myDrawerLayout = findViewById(R.id.drawer_layout);

        //颜色初始化
        Resources resource = (Resources) getBaseContext().getResources();
        cl_blue= (ColorStateList) resource.getColorStateList(R.color.cpb_blue);

        //把Fragment添加到List集合里面
        list = new ArrayList<>();
        list.add(new Fragment_Manage() );
        list.add(new Fragment_Staus() );
        adapter = new TabFragmentPagerAdapter(getSupportFragmentManager(), list);
        myViewPager.setAdapter(adapter);

        //初始化显示第一个页面
        myViewPager.setCurrentItem(0);

        //button切换监听
        bt_status.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                myViewPager.setCurrentItem(1);
            }
        });
        bt_manage.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                myViewPager.setCurrentItem(0);
            }
        });


        //侧边栏item的监听
        navView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
    
    
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
    
    
                switch (menuItem.getItemId()) {
    
    
                    case R.id.nav_call:
                        Toast.makeText(MainActivity.this, "You clicked Call", Toast.LENGTH_SHORT).show();
                        myDrawerLayout.closeDrawers();
                        break;
                }
                return false;
            }
        });



    }

    //ViewPager监听事件,当左右滑动ViewPager时菜单栏被选中状态跟着改变
    public class MyPagerChangeListener implements ViewPager.OnPageChangeListener {
    
    

        @Override
        public void onPageScrollStateChanged(int arg0) {
    
    
        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {
    
    
        }

        @Override
        public void onPageSelected(int arg0) {
    
    
            switch (arg0) {
    
    
                case 0:
                    bt_manage.setTextColor(cl_blue  );
                    bt_status.setTextColor(Color.BLACK );
                    topTitle .setText("管理系统") ;
                    break;
                case 1:
                    bt_manage.setTextColor(Color.BLACK);
                    bt_status.setTextColor(cl_blue);
                    topTitle .setText("状态查询") ;
                    break;
            }

        }

    }
}

4. 补充

猜你喜欢

转载自blog.csdn.net/xiaolan7777777/article/details/109039938