Android开发日记(一) 基础界面设计

年级的工程设计实践课要组队开发一个项目,我们组决定开发一款空闲自习室人数查询app,可以让学生更快的找到合适的自习室学习。
这个项目分为服务器端与客户端,我和另一个小老弟负责客户端的开发,我主要负责登录进入系统之后的界面布局和逻辑开发。
首先是基础界面设计,采用google的Material Design设计风格以获得较好的显示效果。

一、Toolbar

  1. 打开 res/values/styles.xml 将AppTheme属性的parent改为 Theme.AppCompat.Light.NoActionBar
  2. activity_main.xml 中引入Toolbar
    <android.support.v7.widget.Toolbar
    		android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            android:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
    
  3. 修改 MainActivity 中的代码:
    public class MainActivity extends AppCompatActivity {
          
          
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
          
          
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initActivity();
     
        private void initActivity() {
          
          
            // 使用Toolbar
        	Toolbar toolbar = findViewById(R.id.toolbar);
        	setSupportActionBar(toolbar);
        }
    }
    

二、侧边栏

  1. 打开 app/build.gradle 文件, 添加两行依赖:

    implementation 'com.android.support:design:28.0.0'
    implementation 'de.hdodenhof:circleimageview:3.0.0'
    

    其中前一行是谷歌提供的design库, 我们要使用其中的NavigationView控件来实现滑动菜单, 第二行是一个开源项目CircleImageView, 它可以用来轻松的切割圆形图片, 项目地址 CircleImageView

  2. 准备menu和headerLayout来显示侧边栏中的菜单项和头部布局

    • menu 文件夹中新建 nav_menu.xml :
      <?xml version="1.0" encoding="utf-8"?>
      <menu xmlns:android="http://schemas.android.com/apk/res/android">
      <group android:checkableBehavior="none">
      	<item
          	android:id="@+id/nav_menu1"
          	android:icon="@drawable/nav_menu1"
          	android:title="菜单1"/>
      
      	<item
          	android:id="@+id/nav_menu2"
          	android:icon="@drawable/nav_menu2"
          	android:title="菜单2"/>
      </group>
      </menu>
      
    • layout 文件夹中新建 nav_header.xml :
      <?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="70dp"
              android:layout_height="70dp"
              android:src="@drawable/nav_icon"
              android:layout_centerInParent="true"/>
      
          <TextView
              android:id="@+id/school"
              android:layout_alignParentBottom="true"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="郑州大学"
              android:layout_centerHorizontal="true"
              android:textColor="#fff"
              android:textSize="14sp"/>
      
          <TextView
              android:id="@+id/username"
              android:layout_above="@id/school"
              android:text="ZZU"
              android:layout_centerHorizontal="true"
              android:textColor="#fff"
              android:textSize="14sp"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content" />
      </RelativeLayout>
      
  3. activity_main.xml 中使用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/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <android.support.v7.widget.Toolbar
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                android:popupTheme="@style/ThemeOverlay.AppCompat.Light"/> 
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="hello world" />
        </LinearLayout>
    
        <android.support.design.widget.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">
    
        </android.support.design.widget.NavigationView>
    
    </android.support.v4.widget.DrawerLayout>
    
  4. MainActivity 中处理菜单项点击事件:

    public class MainActivity extends AppCompatActivity {
          
          
    
        private DrawerLayout drawerLayout;
        private NavigationView navigationView;
    
    	@Override
        protected void onCreate(Bundle savedInstanceState) {
          
          
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initActivity();
    
    		// 侧边栏菜单项的点击事件
            navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
          
          
                @Override
                public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
          
          
                    switch (menuItem.getItemId()){
          
          
                        case R.id.nav_menu1:
                            drawerLayout.closeDrawers();
                            break;
                        case R.id.nav_menu2:
                            drawerLayout.closeDrawers();
                            break;
                    }
                    return true;
                }
            });
        }
    
        private void initActivity() {
          
          
            drawerLayout = findViewById(R.id.drawer_layout);
            navigationView = findViewById(R.id.nav_view);
    
            // 使用Toolbar
            Toolbar toolbar = findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);
        }
    }
    
    
  5. 使用 ActionBarDrawerToggle 控制侧边栏弹出:

    // 使用toggle控制侧边栏弹出:
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this,drawerLayout,toolbar,R.string.app_name,R.string.app_name);
    toggle.syncState();
    drawerLayout.addDrawerListener(toggle);
    
  6. 默认情况下侧边栏的头部布局是无法设置点击事件的,如果需要设置点击事件,例如点击头部布局进入个人信息界面,首先要取消 app:headerLayout ,然后在代码中设置头部布局,在对其中的控件添加点击事件

    View headerView = navigationView.inflateHeaderView(R.layout.nav_header);
    nav_header = headerView.findViewById(R.id.nav_header);
    
    nav_header.setOnClickListener(new View.OnClickListener() {
          
          
           @Override
           public void onClick(View v) {
          
          
               Intent intent = new Intent(MainActivity.this, PersonalActivity.class);
               startActivity(intent);
           }
    });
    

三、状态栏透明

不重复造轮子, 直接使用某大牛写的状态栏工具类实现透明效果:

  1. app/build.gradle 中引入:
    implementation 'com.jaeger.statusbarutil:library:1.4.0'
    
  2. 由于使用了侧边栏布局, 需要在 activity_main.xml 中为 DrawerLayout 设置 android:fitsSystemWindows="true"
  3. MainActivity 中设置状态栏, 这个步骤一定要放在控件绑定完之后:
    StatusBarUtil.setTransparentForDrawerLayout(this, drawerLayout);
    
  4. 状态栏工具类的中文主页
  5. 使用中发现了一个bug, 有侧边栏的主活动设置透明后跳转到别的活动后再设置状态栏透明会变成白色, android:fitsSystemWindows="true"也失效了, 好像是一个flag被占用了, 目前还不能理解, 解决办法是在 setContentView 之前加上一段代码
    getWindow().requestFeature(Window.FEATURE_NO_TITLE);
    Window window = getWindow();
    window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
    window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
    window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
    window.setStatusBarColor(Color.TRANSPARENT);
    

四、底部导航栏

使用 BottomNavigationView + FrameLayout 实现底部导航栏效果

  1. 准备导航栏图标
  2. menu 文件夹中新建 bottom_nav.xml :
    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
    
        <item
            android:id="@+id/navigation_home"
            android:icon="@drawable/ic_home_black_24dp"
            android:title="导航1" />
    
        <item
            android:id="@+id/navigation_dashboard"
            android:icon="@drawable/ic_dashboard_black_24dp"
            android:title="导航2" />
    
        <item
            android:id="@+id/navigation_notifications"
            android:icon="@drawable/ic_notifications_black_24dp"
            android:title="导航3" />
    
    </menu>
    
    
  3. 修改 activity_main.xml , 引入BottomNavigationView和三个FrameLayout, 默认显示第一个 :
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <View
            android:layout_width="match_parent"
            android:layout_height="18dp"
            android:background="?attr/colorPrimary"
            />
    
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            android:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
    
        <FrameLayout
            android:id="@+id/frame1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            >
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="导航1" />
        </FrameLayout>
    
        <FrameLayout
            android:id="@+id/frame2"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:visibility="gone"
            >
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="导航2" />
        </FrameLayout>
    
        <FrameLayout
            android:id="@+id/frame3"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:visibility="gone"
            >
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="导航3" />
        </FrameLayout>
    
        <android.support.design.widget.BottomNavigationView
            android:id="@+id/bottom_nav"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?android:attr/windowBackground"
            app:menu="@menu/bottom_nav"/>
    
    </LinearLayout>
    
  4. MainActivity 中控制三个FrameLayout的显示:
    private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() {
          
          
    
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
          
          
                switch (item.getItemId()) {
          
          
                    case R.id.navigation_home:
                    	// 显示第一页
                        frameLayout1.setVisibility(View.VISIBLE);
                        frameLayout2.setVisibility(View.GONE);
                        frameLayout3.setVisibility(View.GONE);
                        return true;
                    case R.id.navigation_dashboard:
                    	// 显示第二页
                        frameLayout2.setVisibility(View.VISIBLE);
                        frameLayout1.setVisibility(View.GONE);
                        frameLayout3.setVisibility(View.GONE);
                        return true;
                    case R.id.navigation_notifications:
                    	// 显示第三页
                        frameLayout1.setVisibility(View.GONE);
                        frameLayout2.setVisibility(View.GONE);
                        frameLayout3.setVisibility(View.VISIBLE);
                        return true;
                }
                return false;
            }
        };
    
    // 监听底部导航栏变化
    BottomNavigationView bottom_nav = findViewById(R.id.bottom_nav);
    bottom_nav.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
    

五、效果

在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/zzh2910/article/details/88063529
今日推荐