由于本人在自学Android开发,所以准备记下学习过程中的一些琐碎的知识点,本篇文章主要是介绍一些UI方面的知识点,(登录界面)总的UI实现效果如下,自行与下述各部分一一对应



一.设置statusBar的颜色

* 先在app/res/values/color.xml中,添加自定义的颜色变量 <color
name="colorStatusBar">#EBBD16</color>
* 打开app/res/values/style.xml,将原先的 <item
name="colorPrimaryDark">@color/colorPrimaryDark</item>
  改为我们设计的颜色:
<item name="colorPrimaryDark">@color/colorStatusBar</item>
  或者直接增加一条item
<item name="android:statusBarColor">@color/colorStatusBar</item>
  当item<android:statusBarColor>和item<colorPrimaryDark>同时出现时,前者优先级更高,会覆盖后者的设置

colorPrimaryDark和statusBarColor两者的异同点:

相同点:

都用来修改StatusBar的颜色

Android5.0以上才支持的

不同点:

statusbarColor具有更高的优先级

statusBarColor在Android5.0以下会出现警告提示

默认情况下,statusBarColor的值会继承自colorPrimaryDark

 二.欢迎界面的逻辑

     设置欢迎界面在一定的延迟时间后,跳转到指定界面的步骤:

     (1)创建Timer对象

     (2)调用Timer的schedule,重写TimerTask并设置延迟时间
private Timer skipTimer; skipTimer = new Timer(); skipTimer.schedule(new
TimerTask() { @Override public void run() { Intent intent = new
Intent(WelcomeActivity.this,XXXActivity.class); //XXXActivity为指定的跳转Activity
startActivity(intent); } },3 * 1000);
 三.NavigationBar

      在app/src/main/res/layout中创建nav_bar.xml,代码自定义如下:

      
<?xml version="1.0" encoding="utf-8"?> <FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="@dimen/navBarHeight"
android:background="@color/mainColor" android:paddingLeft="@dimen/marginSize"
android:paddingRight="@dimen/marginSize"> <ImageView
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:src = "@mipmap/back" android:layout_gravity="center_vertical"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:textSize="@dimen/navBarTitleSize"
android:textColor="@android:color/white" android:text="@string/initNavBarTitle"
android:layout_gravity="center"/> <ImageView
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:src="@mipmap/me" android:layout_gravity="right|center_vertical"/>
</FrameLayout>
    其中@mimap/back和@mimap/me为app/src/main/res/mipmap-hdpi下的自己引入的图片

    @string/initNavBarTitle为app/src/main/res/values/string.xml下定义的字符串变量
<string name="initNavBarTitle">测试</string>
   
@dimen/navBarTitleSize、@dimen/navBarHeight、@dimen/marginSize为app/src/main/res/values/dimen.xml中自定义的变量,其中
@dimen/navBarTitleSize为navigationBar中的TextView的文本大小,@dimen/navBarHeight为navigationBar的高度,@dimen/marginSize为navigationBar的内间距,

定义示例:
<dimen name="navBarHeight">56dp</dimen> <dimen name="marginSize">12dp</dimen>
<dimen name="navBarTitleSize">22sp</dimen>
   在其他界面引入布局文件中,只需使用include方法,示例如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout
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" tools:context=".activities.LoginActivity">
<include layout="@layout/nav_bar"/> </LinearLayout>
 四.自定义View(自定义登录框)

   1.自定义属性

         (1)确定需要自定义的属性后,在app/main/res/values中新建一个命名为attrs的xml文档(如果已经存在则不需要重新创建)

         (2)添加自定义变量
<?xml version="1.0" encoding="utf-8"?> <resources> <!--声明样式-->
<declare-styleable name="inputView"> <!--声明变量--> <!--输入框前面的小图标--> <attr
name="input_icon" format="reference"></attr> <!--输入框内的提示内容--> <attr
name="input_hint" format="string"></attr> <!--输入框内容是否需要以密文形式展示--> <attr
name="is_password" format="boolean"></attr> </declare-styleable> </resources>
   2.自定义控件

         (1)代码

                  创建一个InputView继承FrameLayout,然后重写方法,并且绑定自定义布局和布局关联自定义属性,代码如下
import android.content.Context; import android.content.res.TypedArray; import
android.os.Build; import android.support.annotation.NonNull; import
android.support.annotation.Nullable; import
android.support.annotation.RequiresApi; import android.text.InputType; import
android.util.AttributeSet; import android.view.LayoutInflater; import
android.view.View; import android.widget.EditText; import
android.widget.FrameLayout; import android.widget.ImageView; import
com.musicplaer.eminemmusic.R; /**自定义控件 * 以下是自定义的属性: * input_icon:输入框前的提示图标 *
input_hint:输入框内的提示文字 * is_password:确定输入框的内容需不需要以密文的形式展示 */ public class
InputView extends FrameLayout { //声明与自定义属性相对应的变量\ private int inputIcon;
private String inputHint; private boolean isPassword; //控件 private View mView;
private ImageView iv_icon; private EditText ed_input; public InputView(
@NonNull Context context) { super(context); init(context,null); } public
InputView( @NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs); init(context,attrs); } public InputView(@NonNull Context
context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context,
attrs, defStyleAttr); init(context,attrs); } @RequiresApi(api =
Build.VERSION_CODES.LOLLIPOP) public InputView(@NonNull Context context,
@Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes); init(context,attrs); } /** *
初始化方法 * @param context 上下文组件 * @param attrs 自定义变脸 */ private void init(Context
context,AttributeSet attrs){ if(attrs == null){ return; } //获取自定义属性 TypedArray
typedArray = context.obtainStyledAttributes(attrs, R.styleable.inputView);
inputIcon =
typedArray.getResourceId(R.styleable.inputView_input_icon,R.mipmap.logo);
inputHint = typedArray.getString(R.styleable.inputView_input_hint); isPassword
= typedArray.getBoolean(R.styleable.inputView_is_password,false);
typedArray.recycle();//方便后期再次调用,相当于清空的功能 //绑定layout布局 mView =
LayoutInflater.from(context).inflate(R.layout.input_view,this,false); iv_icon =
mView.findViewById(R.id.iv_icon); ed_input = mView.findViewById(R.id.ed_input);
//布局关联属性 iv_icon.setImageResource(inputIcon); ed_input.setHint(inputHint);
ed_input.setInputType(isPassword ? InputType.TYPE_CLASS_TEXT |
InputType.TYPE_TEXT_VARIATION_PASSWORD : InputType.TYPE_CLASS_PHONE); //添加视图
addView(mView); } //获取自定义View的输入内容 public String getInputStr(){ return
ed_input.getText().toString().trim(); } }
         (2)View布局

               在app/src/main/res/layout中创建input_view.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/inputViewHeight" android:orientation="horizontal"
android:gravity="center_vertical" android:paddingRight="@dimen/marginSize"
android:paddingLeft="@dimen/marginSize"> <ImageView android:id="@+id/iv_icon"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:src="@mipmap/phone"/> <EditText android:id="@+id/ed_input"
android:layout_width="match_parent" android:layout_height="match_parent"
android:hint="@string/username" android:background="@null"
android:paddingLeft="@dimen/marginSize"
android:paddingRight="@dimen/marginSize"
android:textSize="@dimen/inputTextView"/> </LinearLayout>
         (2)添加自定义View,"android:"是使用系统定义属性时使用,"app:"使用自定义属性时使用
<?xml version="1.0" encoding="utf-8"?> <LinearLayout
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" tools:context=".activities.LoginActivity">
<include layout="@layout/nav_bar"/> <ImageView android:layout_width="295dp"
android:layout_height="235dp" android:layout_gravity="center_horizontal"
android:layout_marginTop="@dimen/marginSize" android:src="@mipmap/logo" />
<com.musicplaer.eminemmusic.views.InputView android:layout_width="match_parent"
android:layout_height="@dimen/inputViewHeight"
android:layout_marginTop="@dimen/marginSize" app:input_icon="@mipmap/phone"
app:input_hint="@string/phone" app:is_password="false">
</com.musicplaer.eminemmusic.views.InputView> </LinearLayout>
 四.自定义全局控件(区别于自定义View)

     在app/src/main/res/values/styles.xml中中添加自定义控件,下文分别为,自定义直线和自定义按钮格式的style标签
<!--定义分割线--> <style name="line"> <item
name="android:layout_height">1dp</item> <item
name="android:layout_width">match_parent</item> <item
name="android:background">@color/lineColor</item> <item
name="android:layout_margin">@dimen/marginSize</item> </style> <!--登录注册按钮-->
<style name="commitButton"> <item
name="android:layout_width">match_parent</item> <item
name="android:layout_height">@dimen/commitButtonHeight</item> <item
name="android:textColor">@android:color/white</item> <item
name="android:textSize">@dimen/textSize</item> <item
name="android:layout_marginLeft">@dimen/marginSize</item> <item
name="android:layout_marginRight">@dimen/marginSize</item> <item
name="android:gravity">center</item> <!--背景颜色要实现点击和未点击的区别--> <item
name="android:background">@drawable/btn_commit_selector</item> </style>
五.自定义控件颜色和形状

     
上面代码中的@drawable/btn_commit_selector是自定义的空间颜色,在该xml中设定了控件在不同情况下的不同显示结果,该xml的路径为app/src/main/res/drawable/btn_commit_selector,代码如下
<?xml version="1.0" encoding="utf-8"?> <selector
xmlns:android="http://schemas.android.com/apk/res/android"> <!--View处于高亮状态-->
<item android:state_focused="true" android:drawable="@drawable/commit_btn_h"/>
<item android:state_pressed="true" android:drawable="@drawable/commit_btn_h"/>
<item android:state_selected="true" android:drawable="@drawable/commit_btn_h"/>
<!--View处于默认状态--> <item android:drawable="@drawable/commit_btn_n"/> </selector>
        @drawable/commit_btn_n和@drawable/commit_btn_h为按钮默认和高亮两种情况下对应的空间形状,对应如下
@drawable/btn_commit_n <?xml version="1.0" encoding="utf-8"?> <shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"> <!--实体颜色--> <solid
android:color="@color/mainColor"/> <!--弧度--> <corners
android:radius="@dimen/radius"/> </shape> @drawable/btn_commit_h <?xml
version="1.0" encoding="utf-8"?> <shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"> <!--实体颜色--> <solid
android:color="@color/mainColorH"/> <!--弧度--> <corners
android:radius="@dimen/radius"/> </shape>
六.用户输入合法性验证

     
由于在登录注册时,都要把用户填写的数据传送要服务器进行验证,所以如果在客户端先进行用户输入合法性验证,那么就可以减少原先用来传送不合法数据的资源,使得资源利用率更高。

      第三方包地址为:https://github.com/Blankj/AndroidUtilCode
<https://github.com/Blankj/AndroidUtilCode>

      由此使用AndroidUtilCode包来进行验证,步骤如下

      (1) 引入第三方库

                 在当前模块的build.gradle中引入第三方库
implementation 'com.blankj:utilcode:1.23.7'
      (2)初始化AndroidUtilCode

               
 使用AndroidUtilCode库要先初始化,初始化方法为Utils.init(Application),所以在我们自定义的Application中初始化
public class MyApplication extends Application { @Override public void
onCreate(){ super.onCreate(); //初始化第三方AndroidUtilCode包:Utils.init(application)
Utils.init(this); } }
      (3) 创建静态类方法,用于传入参数进行验证

                 由于验证手机号输入合法性和密码合法性是全局使用的方法,所以新创建一个全局静态类,在其中创建静态方法,以供调用验证
public class UserUtils { /** * 验证登录用户输入的合法性 */ public static boolean
validateLogin(Context context,String phone,String password){ //精确地匹配手机号码
if(!RegexUtils.isMobileExact(phone)){
Toast.makeText(context,"无效手机号",Toast.LENGTH_SHORT).show(); return false; }
//验证输入密码是否为空 if(TextUtils.isEmpty(password)){
Toast.makeText(context,"请输入密码",Toast.LENGTH_SHORT).show(); return false; }
return true; } }
      (4) 验证手机号提供了"简单"和"精确"两种方法

               
 AndroidUtilCode提供的验证手机号码的犯法有两种RegexUtils.isMobileExact()和RegexUtils.isMobileSimple():前者是精准匹配(即确认已发布的码段),而后者是简单匹配(即验证输入手机号是否为1开头且11位),两者主要的区别就是内部调用的正则表达式不同

 

七.Activity过渡动画分类

        定义全局动画的步骤:

        1. 自定义动画

               在app/src/main/res/anim(没有便自己创建)下,创建动画

* open_enter <?xml version="1.0" encoding="utf-8"?> <set
xmlns:android="http://schemas.android.com/apk/res/android"> <!--平移-->
<translate android:fromXDelta="100%" android:toXDelta="0%"
android:duration="@integer/animation_time"/> </set>
             
android:fromXDelta="100%"表示activity的起始位置为最右边,android:toXDelta="0%"表示activity的停止位置为最左边,android:duration为动画时间,@integer/animation_time为我们自己在app/src/main/res/values/integers.xml下自定义的变量的
<integer name="animation_time">2000</integer>
*
open_exit
<?xml version="1.0" encoding="utf-8"?> <set
xmlns:android="http://schemas.android.com/apk/res/android"> <!--缩放--> <scale
android:fromXScale="1.0" android:fromYScale="1.0" android:toXScale="0.8"
android:toYScale="0.8" android:pivotX="50%" android:pivotY="50%"
android:duration="@integer/animation_time"/> </set>
     
 android:fromXScale、android:fromYScale为原始尺寸Y,android:toXScale、android:toYScale为缩放尺寸;android:pivotX,android:pivotY指定缩放中心,这里指明缩放中心是界面中心

*
close_exit
<?xml version="1.0" encoding="utf-8"?> <set
xmlns:android="http://schemas.android.com/apk/res/android"> <!--平移-->
<translate android:fromXDelta="0%" android:toXDelta="100%"
android:duration="@integer/animation_time"/> </set>
*
close_enter
<?xml version="1.0" encoding="utf-8"?> <set
xmlns:android="http://schemas.android.com/apk/res/android"> <!--缩放--> <scale
android:fromXScale="0.8" android:fromYScale="0.8" android:toXScale="1.0"
android:toYScale="1.0" android:pivotX="50%" android:pivotY="50%"
android:duration="@integer/animation_time"/> </set>
       2. 定义全局动画的步骤:   
 在app/src/main/res/values/styles.xml定义劝酒全局动画AnimationActivity

      (1)打开Activity时

*  新进入的Activity执行动画
* 原activity执行动画
      (2)退出Activity时

* 退出Activity执行动画
* 重新进入的activity执行动画 <resources> <!-- Base application theme. --> <style
name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize
your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item
name="colorPrimaryDark">@color/colorStatusBar</item> <item
name="colorAccent">@color/colorAccent</item> <item
name="android:windowAnimationStyle">@style/AnimationActivity</item> </style>
<!--定义全局动画--> <style name="AnimationActivity"
parent="android:style/Animation.Activity"> <!--打开Activity时,新进入的Activity执行动画-->
<item name="android:activityOpenEnterAnimation">@anim/open_enter</item>
<!--打开Activity时,退出的Activity执行动画--> <item
name="android:activityOpenExitAnimation">@anim/open_exit</item>
<!--退出Activity时,退出Acitivity执行的动画--> <item
name="android:activityCloseExitAnimation">@anim/close_exit</item>
<!--退出Activity时,进入的Acitivity执行的动画--> <item
name="android:activityCloseEnterAnimation">@anim/close_enter</item> </style>
 

友情链接
ioDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信