Android简易音乐重构MVVM Java版-新增启动动画(九)
关于
本篇内容主要是启动动画和登录页面的重构。
效果图
修改color.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#FFB6C1</color>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="white33">#33FFFFFF</color>
<color name="settings_top_bg_color">#2A2A2A</color>
<color name="settings_text_notes">#828282</color>
<color name="background_gray">#1A181B</color>
<color name="text_gray_05">#E0E0E0</color>
<color name="pureBlack">#000000</color>
<color name="black25">#40000000</color>
<color name="black30">#4C000000</color>
<color name="black70">#B3000000</color>
<color name="blackB23">#B2333333</color>
<color name="black80">#CC000000</color>
<color name="white35">#59ffffff</color>
<color name="white80">#CCffffff</color>
<color name="grays_02">#787878</color>
<color name="grays_01">#333333</color>
<color name="grays_03">#979797</color>
<color name="grays_66">#66000000</color>
<color name="grays_0350">#7f979797</color>
<color name="grays_04">#e7e7e7</color>
<color name="grays_04_B3">#B3e7e7e7</color>
<color name="grays_04_4d">#4De7e7e7</color>
<color name="grays_05">#f1f1f1</color>
<color name="grays_06">#80F1F1F1</color>
<color name="primary_black">#19000000</color>
<color name="primaryBlue">#0099ff</color>
<color name="primaryBlue40">#660099ff</color>
<color name="blue_33007A">#33007AFF</color>
<color name="blue_007a">#007AFF</color>
<color name="grays_00">#00CCCCCC</color>
<color name="grays_10">#10CCCCCC</color>
<color name="grays_20">#20CCCCCC</color>
<color name="grays_30">#30CCCCCC</color>
<color name="grays_50">#50CCCCCC</color>
<color name="circle_progress_color1">#086593</color>
<color name="circle_progress_color2">#308A67</color>
<color name="circle_progress_color3">#69BE28</color>
<color name="gray_828282">#828282</color>
<color name="gray_4F4F4F">#4F4F4F</color>
<color name="transparent">#00000000</color>
<color name="tv_white">#ffffff</color>
<color name="tv_gray_01">#353636</color>
<color name="tv_black">#333333</color>
<color name="tv_hint">#c9c9c9</color>
<color name="tv_black_2c">#2c2c2c</color>
<color name="color_border">#515151</color>
<color name="dark_grey">#a9a9a9</color><!--暗灰色 -->
<color name="boundary_gray">#f0f0f0</color>
</resources>
添加dimens.xml
在values/下新增dimens.xml
:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="dp_0">0dp</dimen>
<dimen name="dp_40">40dp</dimen>
<dimen name="dp_80">80dp</dimen>
<dimen name="dp_30">30dp</dimen>
<dimen name="dp_10">10dp</dimen>
<dimen name="dp_120">120dp</dimen>
<dimen name="dp_35">35dp</dimen>
<dimen name="dp_12">12dp</dimen>
<dimen name="dp_5">5dp</dimen>
<dimen name="dp_7">7dp</dimen>
<dimen name="sp_14">14sp</dimen>
<dimen name="sp_16">16sp</dimen>
<dimen name="dp_16">16dp</dimen>
<dimen name="sp_17">17sp</dimen>
<dimen name="dp_15">15dp</dimen>
<dimen name="dp_60">60dp</dimen>
<dimen name="dp_45">45dp</dimen>
<dimen name="dp_20">20dp</dimen>
<dimen name="dp_50">50dp</dimen>
<dimen name="sp_18">18sp</dimen>
<dimen name="dp_25">25dp</dimen>
<dimen name="dp_2">2dp</dimen>
<dimen name="dp_55">55dp</dimen>
<dimen name="sp_12">12sp</dimen>
<dimen name="sp_15">15sp</dimen>
<dimen name="sp_22">22sp</dimen>
<dimen name="dp_3">3dp</dimen>
<dimen name="dp_200">200dp</dimen>
<dimen name="dp_4">4dp</dimen>
<dimen name="dp_160">160dp</dimen>
<dimen name="dp_64">64dp</dimen>
<dimen name="dp_8">8dp</dimen>
<dimen name="dp_1">1dp</dimen>
<dimen name="sp_13">13sp</dimen>
<dimen name="dp_100">100dp</dimen>
<dimen name="dp_70">70dp</dimen>
<dimen name="dp_130">130dp</dimen>
<dimen name="dp_140">140dp</dimen>
<dimen name="dp_150">150dp</dimen>
<dimen name="dp_110">110dp</dimen>
<dimen name="sp_24">24sp</dimen>
<dimen name="sp_21">21sp</dimen>
<dimen name="dp_13">13dp</dimen>
<dimen name="sp_10">10sp</dimen>
<dimen name="sp_11">11sp</dimen>
<dimen name="dp_170">170dp</dimen>
<dimen name="dp_165">165dp</dimen>
<dimen name="dp_320">320dp</dimen>
<dimen name="dp_640">640dp</dimen>
<dimen name="dp_250">250dp</dimen>
<dimen name="dp_90">90dp</dimen>
<dimen name="dp_220">220dp</dimen>
<dimen name="dp_22">22dp</dimen>
<dimen name="dp_27">27dp</dimen>
<dimen name="dp_48">48dp</dimen>
<dimen name="dp_28">28dp</dimen>
<dimen name="dp_18">18dp</dimen>
<dimen name="dp_23">23dp</dimen>
<dimen name="dp_58">58dp</dimen>
<dimen name="dp_75">75dp</dimen>
<dimen name="dp_6">6dp</dimen>
<dimen name="dp_65">65dp</dimen>
<dimen name="dp_300">300dp</dimen>
<dimen name="dp_280">280dp</dimen>
<dimen name="dp_288">288dp</dimen>
<dimen name="dp_290">290dp</dimen>
<dimen name="sp_26">26sp</dimen>
<dimen name="sp_30">30sp</dimen>
<dimen name="sp_28">28sp</dimen>
<dimen name="dp_190">190dp</dimen>
<dimen name="dp_52">52dp</dimen>
<dimen name="dp_46">46dp</dimen>
<dimen name="dp_39">39dp</dimen>
<dimen name="dp_38">38dp</dimen>
<dimen name="dp_42">42dp</dimen>
<dimen name="sp_20">20sp</dimen>
<dimen name="dp_85">85dp</dimen>
<dimen name="dp_105">105dp</dimen>
<dimen name="dp_95">95dp</dimen>
<dimen name="dp_230">230dp</dimen>
<dimen name="dp_235">235dp</dimen>
<dimen name="dp_240">240dp</dimen>
<dimen name="dp_180">180dp</dimen>
<dimen name="dp_56">56dp</dimen>
<dimen name="dp_32">32dp</dimen>
<dimen name="dp_11">11dp</dimen>
<dimen name="sp_9">9sp</dimen>
<dimen name="dp_400">400dp</dimen>
<dimen name="dp_450">450dp</dimen>
<dimen name="dp_24">24dp</dimen>
<dimen name="dp_26">26dp</dimen>
<dimen name="dp_590">590dp</dimen>
<dimen name="dp_295">295dp</dimen>
<dimen name="dp_195">195dp</dimen>
<dimen name="dp_74">74dp</dimen>
<dimen name="dp_53">53dp</dimen>
<dimen name="fab_margin">16dp</dimen>
<dimen name="dp_260">260dp</dimen>
<dimen name="dp_1000">1000dp</dimen>
<dimen name="dp_210">210dp</dimen>
<dimen name="dp_185">185dp</dimen>
<dimen name="dp_33">33dp</dimen>
</resources>
修改strings.xml
<resources>
<string name="app_name">简易音乐</string>
<string name="day_recommend">每日推荐</string>
<string name="playlist">歌单</string>
<string name="rank">排行榜</string>
<string name="radio">电台</string>
<string name="live">直播</string>
<string name="fm">私人FM</string>
<string name="recommend_playlist">推荐歌单</string>
<string name="playlist_playground">更多</string>
<string name="login_phone_number">手机号登录</string>
<string name="press_exit_again">再按一次退出应用</string>
<string name="input_phone">请输入手机号</string>
<string name="input_pwd">请输入密码</string>
<string name="toast_login">手机号和密码不能为空</string>
<string name="msg_password_error">密码错误</string>
<string name="msg_user_error">账号不存在</string>
<string name="login">立即登录</string>
<string name="permission_denied">部分权限未授予</string>
<string name="need_ask_permission">您需要去设置当中同意存储权限</string>
<string name="btn_ok">确定</string>
<string name="btn_denied">拒绝</string>
<string name="bottom_home">发现</string>
<string name="bottom_podcast">播客</string>
<string name="bottom_my">我的</string>
<string name="bottom_follow">关注</string
</resources>
添加splash主题
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.PersonalMusic" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="windowNoTitle">true</item>
<item name="colorPrimaryVariant">@color/colorPrimary</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
<style name="ThemeSplash" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">@color/colorPrimary</item>
<!--Android 5.x开始需要把颜色设置透明,否则导航栏会呈现系统默认的浅灰色-->
<item name="android:statusBarColor" tools:ignore="NewApi">#00000000</item>
</style>
</resources>
添加部分实体类
添加login_bean.java
package com.tobery.personalmusic.entity;
import java.util.List;
/**
* 手机号登录Bean
* Created By Tobey on 2020/9/9
*/
public class Login_Bean {
private int loginType;
private int code;
private AccountBean account;
private String token;
private ProfileBean profile;
private String cookie;
private List<BindingsBean> bindings;
public int getLoginType() {
return loginType;
}
public void setLoginType(int loginType) {
this.loginType = loginType;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public AccountBean getAccount() {
return account;
}
public void setAccount(AccountBean account) {
this.account = account;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public ProfileBean getProfile() {
return profile;
}
public void setProfile(ProfileBean profile) {
this.profile = profile;
}
public String getCookie() {
return cookie;
}
public void setCookie(String cookie) {
this.cookie = cookie;
}
public List<BindingsBean> getBindings() {
return bindings;
}
public void setBindings(List<BindingsBean> bindings) {
this.bindings = bindings;
}
public static class AccountBean {
private int id;
private String userName;
private int type;
private int status;
private int whitelistAuthority;
private long createTime;
private String salt;
private int tokenVersion;
private int ban;
private int baoyueVersion;
private int donateVersion;
private int vipType;
private long viptypeVersion;
private boolean anonimousUser;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public int getWhitelistAuthority() {
return whitelistAuthority;
}
public void setWhitelistAuthority(int whitelistAuthority) {
this.whitelistAuthority = whitelistAuthority;
}
public long getCreateTime() {
return createTime;
}
public void setCreateTime(long createTime) {
this.createTime = createTime;
}
public String getSalt() {
return salt;
}
public void setSalt(String salt) {
this.salt = salt;
}
public int getTokenVersion() {
return tokenVersion;
}
public void setTokenVersion(int tokenVersion) {
this.tokenVersion = tokenVersion;
}
public int getBan() {
return ban;
}
public void setBan(int ban) {
this.ban = ban;
}
public int getBaoyueVersion() {
return baoyueVersion;
}
public void setBaoyueVersion(int baoyueVersion) {
this.baoyueVersion = baoyueVersion;
}
public int getDonateVersion() {
return donateVersion;
}
public void setDonateVersion(int donateVersion) {
this.donateVersion = donateVersion;
}
public int getVipType() {
return vipType;
}
public void setVipType(int vipType) {
this.vipType = vipType;
}
public long getViptypeVersion() {
return viptypeVersion;
}
public void setViptypeVersion(long viptypeVersion) {
this.viptypeVersion = viptypeVersion;
}
public boolean isAnonimousUser() {
return anonimousUser;
}
public void setAnonimousUser(boolean anonimousUser) {
this.anonimousUser = anonimousUser;
}
}
public static class ProfileBean {
private String description;
private int userId;
private int accountStatus;
private int vipType;
private int gender;
private long avatarImgId;
private String nickname;
private long birthday;
private int city;
private int userType;
private long backgroundImgId;
private String avatarUrl;
private boolean defaultAvatar;
private int province;
private int djStatus;
private ExpertsBean experts;
private boolean mutual;
private Object remarkName;
private Object expertTags;
private int authStatus;
private boolean followed;
private String backgroundUrl;
private String detailDescription;
private String avatarImgIdStr;
private String backgroundImgIdStr;
private String signature;
private int authority;
private String avatarImgId_str;
private int followeds;
private int follows;
private int eventCount;
private int playlistCount;
private int playlistBeSubscribedCount;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public int getAccountStatus() {
return accountStatus;
}
public void setAccountStatus(int accountStatus) {
this.accountStatus = accountStatus;
}
public int getVipType() {
return vipType;
}
public void setVipType(int vipType) {
this.vipType = vipType;
}
public int getGender() {
return gender;
}
public void setGender(int gender) {
this.gender = gender;
}
public long getAvatarImgId() {
return avatarImgId;
}
public void setAvatarImgId(long avatarImgId) {
this.avatarImgId = avatarImgId;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public long getBirthday() {
return birthday;
}
public void setBirthday(long birthday) {
this.birthday = birthday;
}
public int getCity() {
return city;
}
public void setCity(int city) {
this.city = city;
}
public int getUserType() {
return userType;
}
public void setUserType(int userType) {
this.userType = userType;
}
public long getBackgroundImgId() {
return backgroundImgId;
}
public void setBackgroundImgId(long backgroundImgId) {
this.backgroundImgId = backgroundImgId;
}
public String getAvatarUrl() {
return avatarUrl;
}
public void setAvatarUrl(String avatarUrl) {
this.avatarUrl = avatarUrl;
}
public boolean isDefaultAvatar() {
return defaultAvatar;
}
public void setDefaultAvatar(boolean defaultAvatar) {
this.defaultAvatar = defaultAvatar;
}
public int getProvince() {
return province;
}
public void setProvince(int province) {
this.province = province;
}
public int getDjStatus() {
return djStatus;
}
public void setDjStatus(int djStatus) {
this.djStatus = djStatus;
}
public ExpertsBean getExperts() {
return experts;
}
public void setExperts(ExpertsBean experts) {
this.experts = experts;
}
public boolean isMutual() {
return mutual;
}
public void setMutual(boolean mutual) {
this.mutual = mutual;
}
public Object getRemarkName() {
return remarkName;
}
public void setRemarkName(Object remarkName) {
this.remarkName = remarkName;
}
public Object getExpertTags() {
return expertTags;
}
public void setExpertTags(Object expertTags) {
this.expertTags = expertTags;
}
public int getAuthStatus() {
return authStatus;
}
public void setAuthStatus(int authStatus) {
this.authStatus = authStatus;
}
public boolean isFollowed() {
return followed;
}
public void setFollowed(boolean followed) {
this.followed = followed;
}
public String getBackgroundUrl() {
return backgroundUrl;
}
public void setBackgroundUrl(String backgroundUrl) {
this.backgroundUrl = backgroundUrl;
}
public String getDetailDescription() {
return detailDescription;
}
public void setDetailDescription(String detailDescription) {
this.detailDescription = detailDescription;
}
public String getAvatarImgIdStr() {
return avatarImgIdStr;
}
public void setAvatarImgIdStr(String avatarImgIdStr) {
this.avatarImgIdStr = avatarImgIdStr;
}
public String getBackgroundImgIdStr() {
return backgroundImgIdStr;
}
public void setBackgroundImgIdStr(String backgroundImgIdStr) {
this.backgroundImgIdStr = backgroundImgIdStr;
}
public String getSignature() {
return signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
public int getAuthority() {
return authority;
}
public void setAuthority(int authority) {
this.authority = authority;
}
public String getAvatarImgId_str() {
return avatarImgId_str;
}
public void setAvatarImgId_str(String avatarImgId_str) {
this.avatarImgId_str = avatarImgId_str;
}
public int getFolloweds() {
return followeds;
}
public void setFolloweds(int followeds) {
this.followeds = followeds;
}
public int getFollows() {
return follows;
}
public void setFollows(int follows) {
this.follows = follows;
}
public int getEventCount() {
return eventCount;
}
public void setEventCount(int eventCount) {
this.eventCount = eventCount;
}
public int getPlaylistCount() {
return playlistCount;
}
public void setPlaylistCount(int playlistCount) {
this.playlistCount = playlistCount;
}
public int getPlaylistBeSubscribedCount() {
return playlistBeSubscribedCount;
}
public void setPlaylistBeSubscribedCount(int playlistBeSubscribedCount) {
this.playlistBeSubscribedCount = playlistBeSubscribedCount;
}
public static class ExpertsBean {
}
}
public static class BindingsBean {
private int userId;
private String tokenJsonStr;
private int expiresIn;
private int refreshTime;
private boolean expired;
private String url;
private long bindingTime;
private long id;
private int type;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getTokenJsonStr() {
return tokenJsonStr;
}
public void setTokenJsonStr(String tokenJsonStr) {
this.tokenJsonStr = tokenJsonStr;
}
public int getExpiresIn() {
return expiresIn;
}
public void setExpiresIn(int expiresIn) {
this.expiresIn = expiresIn;
}
public int getRefreshTime() {
return refreshTime;
}
public void setRefreshTime(int refreshTime) {
this.refreshTime = refreshTime;
}
public boolean isExpired() {
return expired;
}
public void setExpired(boolean expired) {
this.expired = expired;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public long getBindingTime() {
return bindingTime;
}
public void setBindingTime(long bindingTime) {
this.bindingTime = bindingTime;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}
}
添加SharePreferencesUtil帮助类
public class SharePreferencesUtil {
private static volatile SharePreferencesUtil mInstance;
private static SharedPreferences sharedPref;
private static SharedPreferences.Editor editor;
private SharePreferencesUtil() {
}
public static SharePreferencesUtil getInstance(Context context) {
if (mInstance == null) {
synchronized (SharePreferencesUtil.class) {
if (mInstance == null) {
init(context);
mInstance = new SharePreferencesUtil();
}
}
}
return mInstance;
}
private static void init(Context context) {
if (sharedPref == null) {
sharedPref = context.getSharedPreferences(
APP_SHARED_SAVE, Context.MODE_PRIVATE);
}
editor = sharedPref.edit();
}
public String getAuthToken(String key) {
return getString(key);
}
public void saveUserInfo(Login_Bean bean, String phoneNumber) {
if (bean.getBindings().size() > 1) {
saveAuthToken(AUTH_TOKEN,bean.getBindings().get(1).getTokenJsonStr());
}
saveAccountNum(phoneNumber);
String userInfo = new Gson().toJson(bean);
saveString(USER_INFO, userInfo);
}
public void savePermissionDeniedNum(String key,int value){
saveInt(key, value);
}
public int getPermissionDeniedNum(String key){
return getInt(key);
}
private void saveAuthToken(String key,String value) {
saveString(key, value);
}
private void saveAccountNum(String phoneNumber) {
saveString(USER_PHONE, phoneNumber);
}
private void saveString(String key, String value) {
editor.putString(key, value).apply();
}
private String getString(String key) {
return sharedPref.getString(key, "");
}
private int getInt(String key) {
return sharedPref.getInt(key,0);
}
private void saveInt(String key, int defaultValue) {
editor.putInt(key,defaultValue).apply();
}
}
添加Constant常量
public class Constant {
public static final String SONG_URL = "http://music.163.com/song/media/outer/url?id=";
public static final String KEY_LOGIN_UI = "KEY_LOGIN_UI";
public static final String APP_SHARED_SAVE = "APP_SHARED_SAVE";
public static final String USER_INFO = "USER_INFO";
public static final String AUTH_TOKEN = "AUTH_TOKEN";
public static final String USER_PHONE = "USER_PHONE";
public static final String DENIED_PERMISSION = "DENIED_PERMISSION";
//设置默认超时时间
public static final int DEFAULT_TIME=6;
public final static String BaseUrl = "http://121.5.194.180:3030/";
}
添加activity_splash.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="@color/colorPrimary"
tools:context=".ui.splash.SplashActivity">
<TextView
android:id="@+id/img_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/launcher_back"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>
<TextView
android:id="@+id/img_icon_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/launcher_back"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="@dimen/dp_120"
/>
<TextView
android:id="@+id/tv_icon_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:layout_marginTop="@dimen/dp_16"
android:textStyle="bold"
android:textSize="@dimen/sp_18"
android:textColor="@color/tv_black_2c"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/img_icon_top"
/>
<TextView
android:id="@+id/tv_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:layout_marginTop="@dimen/dp_16"
android:textStyle="bold"
android:textSize="@dimen/sp_18"
android:textColor="@color/tv_black_2c"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/img_icon"
/>
<Button
android:id="@+id/btn_phone_login"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_40"
android:layout_marginStart="@dimen/dp_80"
android:layout_marginEnd="@dimen/dp_80"
android:layout_marginBottom="@dimen/dp_120"
android:background="@drawable/shape_btn_login_white"
android:text="@string/login_phone_number"
android:textColor="@color/colorPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>
<androidx.constraintlayout.widget.Group
android:id="@+id/group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="img_icon,tv_icon"
android:visibility="visible"/>
<androidx.constraintlayout.widget.Group
android:id="@+id/group_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="img_icon_top,tv_icon_top,btn_phone_login"
android:visibility="gone"/>
</androidx.constraintlayout.widget.ConstraintLayout>
添加splash图标
图片资源
链接:https://pan.baidu.com/s/1l249MNrqRSyPq9Om_2aUgw
提取码:1234
添加ic_login_password.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="65dp"
android:height="64dp"
android:viewportWidth="1040"
android:viewportHeight="1024">
<path
android:pathData="M971.5,308.6 L228,308.6C252.7,174.2 370.4,72.4 512,72.4c113.9,0 212.4,65.9 259.4,161.7 4.2,9 13.3,15.2 23.8,15.2 14.5,0 26.3,-11.8 26.3,-26.3 0,-4.4 -1.1,-8.6 -3,-12.2l0.1,-0C762.9,97.7 646.5,19.9 512,19.9c-170.6,0 -312,125.2 -337.3,288.8L52.5,308.6c-29,0 -52.5,23.5 -52.5,52.5l0,525.2c0,29 23.5,52.5 52.5,52.5l919,0c29,0 52.5,-23.5 52.5,-52.5L1024,361.1C1024,332.1 1000.5,308.6 971.5,308.6zM971.5,860c0,14.5 -11.8,26.3 -26.3,26.3L78.8,886.3c-14.5,0 -26.3,-11.8 -26.3,-26.3L52.5,387.4c0,-14.5 11.8,-26.3 26.3,-26.3l91.9,0c0,0 0,0 0,0l52.5,0c0,-0 0,-0 0,-0l722.1,0c14.5,0 26.3,11.8 26.3,26.3L971.5,860z"
android:fillColor="#515151"/>
<path
android:pathData="M512,391.7c-58,0 -105,47 -105,105 0,48.9 33.5,90.1 78.8,101.7l0,194.6c0,14.5 11.8,26.3 26.3,26.3 14.5,0 26.3,-11.8 26.3,-26.3L538.3,598.5c45.3,-11.7 78.8,-52.8 78.8,-101.7C617,438.8 570,391.7 512,391.7zM512,549.3c-29,0 -52.5,-23.5 -52.5,-52.5 0,-29 23.5,-52.5 52.5,-52.5 29,0 52.5,23.5 52.5,52.5C564.5,525.8 541,549.3 512,549.3z"
android:fillColor="#515151"/>
</vector>
添加ic_login_user.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="65dp"
android:height="64dp"
android:viewportWidth="1040"
android:viewportHeight="1024">
<path
android:pathData="M971.5,308.6 L228,308.6C252.7,174.2 370.4,72.4 512,72.4c113.9,0 212.4,65.9 259.4,161.7 4.2,9 13.3,15.2 23.8,15.2 14.5,0 26.3,-11.8 26.3,-26.3 0,-4.4 -1.1,-8.6 -3,-12.2l0.1,-0C762.9,97.7 646.5,19.9 512,19.9c-170.6,0 -312,125.2 -337.3,288.8L52.5,308.6c-29,0 -52.5,23.5 -52.5,52.5l0,525.2c0,29 23.5,52.5 52.5,52.5l919,0c29,0 52.5,-23.5 52.5,-52.5L1024,361.1C1024,332.1 1000.5,308.6 971.5,308.6zM971.5,860c0,14.5 -11.8,26.3 -26.3,26.3L78.8,886.3c-14.5,0 -26.3,-11.8 -26.3,-26.3L52.5,387.4c0,-14.5 11.8,-26.3 26.3,-26.3l91.9,0c0,0 0,0 0,0l52.5,0c0,-0 0,-0 0,-0l722.1,0c14.5,0 26.3,11.8 26.3,26.3L971.5,860z"
android:fillColor="#515151"/>
<path
android:pathData="M512,391.7c-58,0 -105,47 -105,105 0,48.9 33.5,90.1 78.8,101.7l0,194.6c0,14.5 11.8,26.3 26.3,26.3 14.5,0 26.3,-11.8 26.3,-26.3L538.3,598.5c45.3,-11.7 78.8,-52.8 78.8,-101.7C617,438.8 570,391.7 512,391.7zM512,549.3c-29,0 -52.5,-23.5 -52.5,-52.5 0,-29 23.5,-52.5 52.5,-52.5 29,0 52.5,23.5 52.5,52.5C564.5,525.8 541,549.3 512,549.3z"
android:fillColor="#515151"/>
</vector>
添加shape_btn_login_white.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/dp_30"/>
<solid android:color="#FFFFFF"/>
</shape>
修改Androidmanifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
...
<activity
android:name=".ui.splash.SplashActivity"
android:screenOrientation="portrait"
android:theme="@style/ThemeSplash"
android:exported="true" >
修改SplashActivity.java
@SuppressLint("CustomSplashScreen")
public class SplashActivity extends BaseActivity {
private ActivitySplashBinding binding;
ActivityResultLauncher<String[]> requestPermissionLauncher;
ActivityResultLauncher<Intent> requestIntentLauncher;
private AlertDialog dialog;
private final String[] APP_PERMISSIONS = new ArrayList<String>(){
{
add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
add(Manifest.permission.READ_EXTERNAL_STORAGE);
}
}.toArray(new String[0]);
@Override
public void registerComponentCallbacks(ComponentCallbacks callback) {
super.registerComponentCallbacks(callback);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivitySplashBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
initView();
}
private void initView() {
Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
@Override
public void run() {
requestPermissionLauncher.launch(APP_PERMISSIONS);
}
},2500);
requestPermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(),result -> {
if (!result.toString().contains("false")){
String token = SharePreferencesUtil.getInstance(this).getAuthToken(AUTH_TOKEN);
if (TextUtils.isEmpty(token)) {
binding.group.setVisibility(View.GONE);
binding.groupTop.setVisibility(View.VISIBLE);
} else {
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
}
}else {
int lastDeniedNum = SharePreferencesUtil.getInstance(this).getPermissionDeniedNum(DENIED_PERMISSION);
int currentDeniedNum = lastDeniedNum +1;
SharePreferencesUtil.getInstance(this).savePermissionDeniedNum(DENIED_PERMISSION,currentDeniedNum);
ToastUtils.show(getString(R.string.permission_denied));
if (currentDeniedNum >= 2){
showExplain();
}else {
finish();
}
}
});
requestIntentLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),result -> {
if (result.getResultCode() == RESULT_OK){
requestPermissionLauncher.launch(APP_PERMISSIONS);
}
});
binding.btnPhoneLogin.setOnClickListener(view -> {
if (ClickUtil.enableClick()){
Intent intent = new Intent(this, LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
}
});
}
private void showExplain() {
dialog = new AlertDialog.Builder(this)
.setMessage(getString(R.string.need_ask_permission))
.setCancelable(false)
.setPositiveButton(getString(R.string.btn_ok), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package",getPackageName(),null);
intent.setData(uri);
requestIntentLauncher.launch(intent);
}
})
.setNegativeButton(getString(R.string.btn_denied), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
finish();
}
})
.create();
dialog.show();
}
@Override
protected void onDestroy() {
super.onDestroy();
requestPermissionLauncher = null;
if (dialog !=null){
dialog.dismiss();
dialog = null;
}
}
}
看了下markdown字数,2.5w字,所以本篇先记录到这,后续文章重构ui以及http模块。有问题欢迎批评指正,觉得不错的也请点个赞谢谢。