06-Android项目搭建

工具环境

  • android studio 4.1.2
  • java8

创建工程

就普通的android工程创建就可以。

定义我们需要的依赖库的gradle文件,后面添加依赖都从这里获取,方便做统一的版本管理。新建一个version.gradle

// 配置信息,版本信息等
ext {
//android 编译版本等信息
    android = [
            applicationId    : "com.hlox.android.video",
            compileSdkVersion: 30,
            buildToolsVersion: "30.0.2",
            minSdkVersion    : 23,
            targetSdkVersion : 30,
            versionCode      : 1,
            versionName      : '1.0',
            mutidex          : true
    ]

    // 依赖版本
    depsVersion = [
            appcompat          : '1.1.0',
            junit              : '4.12',
            constraint         : '1.1.3',
            magic_indicator    : '1.7.0',
            status_bar_utils   : '1.7.5',
            okhttp             : '3.3.0',
            gson               : '2.8.6',
            glide              : '4.9.0',
            gildecompiler      : '4.9.0',
            rxjava             : '2.2.9',
            rxandroid          : '2.1.1',
            material           : '1.1.0',
            navigation_fragment: '2.2.2',
            navigation_ui      : '2.2.2',
            startup            : '1.0.0',
            androidJunit       : '1.1.1',
            expresso           : '3.2.0',
            retrofit           : '2.9.0',
            converter_gson     : '2.9.0',
            status_bar         : '1.5.1'
    ]

    // 依赖库
    depsLibs = [
            appcompat          : "androidx.appcompat:appcompat:${depsVersion.appcompat}",
            constraint         : "androidx.constraintlayout:constraintlayout:${depsVersion.constraint}",
            material           : "com.google.android.material:material:${depsVersion.material}",
            junit              : "junit:junit:${depsVersion.junit}",
            magic_indicator    : "com.github.hackware1993:MagicIndicator:${depsVersion.magic_indicator}",
            status_bar_utils   : "com.github.Ye-Miao:StatusBarUtil:${depsVersion.status_bar_utils}",
            okhttp             : "com.squareup.okhttp3:okhttp:${depsVersion.okhttp}",
            gson               : "com.google.code.gson:gson:${depsVersion.gson}",
            glide              : "com.github.bumptech.glide:glide:${depsVersion.glide}",
            gildecompiler      : "com.github.bumptech.glide:compiler:${depsVersion.gildecompiler}",
            rxjava             : "io.reactivex.rxjava2:rxjava:${depsVersion.rxjava}",
            rxandroid          : "io.reactivex.rxjava2:rxandroid:${depsVersion.rxandroid}",
            navigation_fragment: "androidx.navigation:navigation-fragment:${depsVersion.navigation_fragment}",
            navigation_ui      : "androidx.navigation:navigation-ui:${depsVersion.navigation_ui}",
            startup            : "androidx.startup:startup-runtime:${depsVersion.startup}",
            androidJunit       : "androidx.test.ext:junit:${depsVersion.androidJunit}",
            expresso           : "androidx.test.espresso:espresso-core:${depsVersion.expresso}",
            retrofit           : "com.squareup.retrofit2:retrofit:${depsVersion.retrofit}",
            converter_gson     : "com.squareup.retrofit2:retrofit:${depsVersion.converter_json}",
            status_bar         : "com.jaeger.statusbarutil:library:${depsVersion.status_bar}"
    ]
}

在项目的根目录下的build.gradle文件中引入version.gradle。

apply from: this.rootProject.file('versions.gradle')

buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.1.2"
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

之后是在我们的项目的build.gradle文件中修改依赖,修改后的文件如下

plugins {
    id 'com.android.application'
}

android {
    compileSdkVersion this.rootProject.android.compileSdkVersion
    buildToolsVersion this.rootProject.android.buildToolsVersion

    defaultConfig {
        applicationId this.rootProject.android.applicationId
        minSdkVersion this.rootProject.android.minSdkVersion
        targetSdkVersion this.rootProject.android.targetSdkVersion
        versionCode this.rootProject.android.versionCode
        versionName this.rootProject.android.versionName
        multiDexEnabled this.rootProject.android.mutidex

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildFeatures{
        viewBinding true
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {

    implementation this.rootProject.depsLibs.appcompat
    implementation this.rootProject.depsLibs.material
    implementation this.rootProject.depsLibs.constraint
    // navigation
    implementation this.rootProject.depsLibs.navigation_fragment
    implementation this.rootProject.depsLibs.navigation_ui
    // startup
    implementation this.rootProject.depsLibs.startup
    implementation this.rootProject.depsLibs.status_bar
    implementation project(path: ':net')
    implementation project(path: ':log')
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    testImplementation this.rootProject.depsLibs.junit
    androidTestImplementation this.rootProject.depsLibs.androidJunit
    androidTestImplementation this.rootProject.depsLibs.expresso
}

为了演示使用startup,我把log的工具类抽取到一个单独的module中,网络相关的也抽取在一个module中,所以我们的工程结构如下图

APP的功能点

  • 首页
  • 收藏
  • 我的

APP大概会有2个Activty,一个Splash,一个Home。首页、收藏、我的会以Fragment的方式展示出来。

首页

展示视频列表,以及顶部一个视频的分类标签,点击条目跳转到播放页面

收藏

显示收藏的视频,未登录时显示本地的收藏列表,登录后会合并本地和服务端的收藏列表

我的

这部分展示用户的登录信息,以及关于和设置选项等

Home页面搭建的问题记录

在Home页面,我们用了JetPack的Navigation组建和BottomNavigationView进行Fragment的跳转管理,绑定这两者之间的关系,有一点需要注意的是,navigation中定义的fragment的id和BottomNavigationView使用的menu的itemID必须是一样的才可以。代码如下

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  mBinding = ActivityHomeBinding.inflate(getLayoutInflater());
  setContentView(mBinding.getRoot());
  mLogger = Logger.getInstance(getClass());
  // 关联两者,使用NavigationUI的话,需要添加对应的依赖,上面的version.gradle中已经定义了
  NavController navController = Navigation.findNavController(this, R.id.frag_container);
  NavigationUI.setupWithNavController(mBinding.navigationView, navController);
}

menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/homeFragment" android:title="@string/menu_home" android:icon="@drawable/ic_home" />
    <item android:id="@+id/favoriteFragment" android:title="@string/menu_favorite" android:icon="@drawable/ic_favorite"/>
    <item android:id="@+id/mineFragment" android:title="@string/menu_mine" android:icon="@drawable/ic_mine"/>
</menu>

Navigation.xml

<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/nav_main"
    app:startDestination="@id/homeFragment">

    <fragment
        android:id="@+id/mineFragment"
        android:name="com.hlox.android.video.ui.fragment.MineFragment"
        android:label="MineFragment" />
    <fragment
        android:id="@+id/homeFragment"
        android:name="com.hlox.android.video.ui.fragment.HomeFragment"
        android:label="fragment_home"
        tools:layout="@layout/fragment_home" />
    <fragment
        android:id="@+id/favoriteFragment"
        android:name="com.hlox.android.video.ui.fragment.FavoriteFragment"
        android:label="FavoriteFragment" />
</navigation>

Github

https://github.com/huyuqiwolf/VideoApk