• Diycode开源项目 LoginActivity分析


    1.首先看一下效果

    1.1.预览一下真实页面

      

      

    1.2.分析一下:

        要求输入Email或者用户名,点击编辑框,弹出键盘,默认先进入输入Email或用户名编辑框。

        点击密码后,密码字样网上浮动一段距离,Email编辑框也是一样的,不过第一次默认是第一个。

        没有账号?点击注册后跳转到一个网页,采用手机默认浏览器跳转。


    2.LoginActivity布局分析

    2.1.首先看一下activity_login源代码

    <?xml version="1.0" encoding="utf-8"?>
    <!--
      ~ Copyright 2017 GcsSloop
      ~
      ~ Licensed under the Apache License, Version 2.0 (the "License");
      ~ you may not use this file except in compliance with the License.
      ~ You may obtain a copy of the License at
      ~
      ~    http://www.apache.org/licenses/LICENSE-2.0
      ~
      ~ Unless required by applicable law or agreed to in writing, software
      ~ distributed under the License is distributed on an "AS IS" BASIS,
      ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      ~ See the License for the specific language governing permissions and
      ~ limitations under the License.
      ~
      ~ Last modified 2017-03-19 01:27:22
      ~
      ~ GitHub:  https://github.com/GcsSloop
      ~ Website: http://www.gcssloop.com
      ~ Weibo:   http://weibo.com/GcsSloop
      -->
    <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:id="@+id/activity_login"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.gcssloop.diycode.activity.LoginActivity">
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:paddingLeft="14dp"
            android:paddingRight="14dp">
            <View
                android:id="@+id/span1"
                android:layout_width="0dp"
                android:layout_height="10dp"
                android:visibility="invisible"/>
    
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:scaleType="centerInside"
                android:src="@drawable/ic_logo"/>
            
            <View
                android:id="@+id/span2"
                android:layout_width="0dp"
                android:layout_height="80dp"
                android:visibility="invisible"/>
    
            <android.support.design.widget.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                >
    
                <EditText
                    android:id="@+id/username"
                    android:layout_width="match_parent"
                    android:layout_height="36dp"
                    android:layout_marginLeft="6dp"
                    android:background="@null"
                    android:hint="Email / 用户名"
                    android:inputType="textEmailAddress|text"
                    android:textSize="16sp"/>
    
                <View
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:layout_below="@id/username"
                    android:layout_marginTop="2dp"
                    android:background="@drawable/horizontal_line"/>
    
            </android.support.design.widget.TextInputLayout>
    
            <android.support.design.widget.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                >
    
                <EditText
                    android:id="@+id/password"
                    android:layout_width="match_parent"
                    android:layout_height="36dp"
                    android:layout_marginLeft="6dp"
                    android:background="@null"
                    android:hint="密码"
                    android:inputType="textPassword"
                    android:textSize="16sp"/>
    
                <View
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:layout_below="@id/password"
                    android:layout_marginTop="2dp"
                    android:background="@drawable/horizontal_line"/>
            </android.support.design.widget.TextInputLayout>
    
            <View
                android:id="@+id/span3"
                android:layout_width="0dp"
                android:layout_height="20dp"
                android:visibility="invisible"/>
    
            <Button
                android:id="@+id/login"
                android:layout_width="match_parent"
                android:layout_height="48dp"
                android:layout_marginTop="6dp"
                android:background="@drawable/bg_longin_btn"
                android:text="登  录"
                android:textColor="@color/diy_white"
                android:textSize="18sp"/>
    
            <TextView
                android:layout_marginTop="20dp"
                android:padding="12dp"
                android:layout_gravity="center_horizontal"
                android:id="@+id/sign_up"
                android:text="没有账号?点击注册"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
    
        </LinearLayout>
    </LinearLayout>
    View Code

      

    2.2.代码和布局对应关系

      

    2.3.从上之下分析布局

       最外层是一个LinearLayout==>一个线性布局,一般登录都是这样做的。

       然后是一个toolbar,自带返回按钮的标题栏。

       标题栏下面的布局也是一个线性布局,它将标题栏和下方登录界面分隔开了。

       下方的线性布局就很简单了。

       首先是一个view,就是一个最基本的视图,这里用作类似于占空间控件。

       有时候view可以当做一条分割线,这里讲将宽度设置为0,高度不等,巧妙利用了这个特点。

    2.4.值得关注的是编辑框外层的一个TextInputLayout布局

      这里的编辑框布局都是外层的TextInputLayout,然后里面是一个EditText+View。

      

      TextInputLayout支持悬浮实现hint效果。给用户体验比较好。

      一个TextInputLayout只能包含一个EditText。

      参考文章:android新特性:TextInputLayout使用方法。


    3.LoginActivity活动源代码分析

    3.1.成员变量分析

      

      这里仅仅需要两个变量。一个是用户名的编辑框,一个是密码的编辑框。

    3.2.实现两个在BaseActivity中定义的抽象方法

      

      首先确定登录活动的布局==>activity_login.xml

      然后将标题栏设空,获得用户名+密码的资源id

      最后将这两个资源id添加监听器。

    3.3.实现登录接口,利用EventBus实现。 

      

      这个onLogin其实是只在点击了登录按钮后才执行。

      这里我思考了一下EventBus执行方式。

      首先在活动开始即onStart中注册EventBus.getDefault().register(this)即可。

      然后在活动的停止或者销毁中反注册EventBus.getDefault().unregister(this)即可。

      然后就是写一些只会在UI线程中执行的函数--要用@Subscribe(threadMode=ThreadMode.MAIN)定义。

      因为之前也碰到这种类似的方法,我还以为是多余,不会执行呢。

      没想到就是要执行的,只是换了一种方式。

      安装完Android Studio3.0之后,这个this前面也自动添加了subscriber字样。

      

      这里从SDK的API中获得了个人信息之后,直接finish,交给MainActivity来处理。

    3.4.处理软键盘弹起

      

      在onStart中,就是默认点开之后,会弹出软键盘,用户即可输入用户名。

      

      注意点:获取当前布局的根布局用下面这种方法。

      

      如何理解ViewTreeObserver.OnGlobalLayoutListener?

      参考一下这篇文章:android利用OnGlobalLayoutListener获取视图高度。

      

      作用:当视图树中全局视图发生改变,配合View.GONE和View.INVISIBLE来实现布局上下移动。

          本例就是点击了第一个编辑框,整个布局会往上移动,不过这是利用视图的隐藏和显示完成的。

      具体的判断软键盘是否显示==>

      

      首先根布局已经获取,且已经作为一个参数了。

      这里如何获取根布局可视区域大小,这里采用了一个函数:

      rootView.getWindowVisibleDisplayFrame(存放到一个矩形)

      打印了一下:

      

      根布局获取到的getBottom:1857

      矩形获取到的getBottom:1920

      所以两者相减<软键盘高度,所有这里就没有弹出软键盘

      

      根布局获取到的getBottom:1857

      矩形获取到的getBottom:1285

      所以两者相减>软键盘高度,所有这里就弹出软键盘

    3.5.处理点击事件

      

      这里我发现我上面写错了一点。

      就是处理登录接口的函数,就是点击登录之后,会执行这个API函数,而不是上面那个EventBus的onLogin。

      上面那个onLogin其实应该类似于回调效果吧。可能EventBus就是处理类似回调的东西吧。

      然后另外一个点击事件是注册,打开网页版才能注册,所以这里直接是打开一个链接。


    4.总结一下

    4.1.终于对EventBus有一定了解了。本篇文章一开始对于EventBus的了解是错误的,之后才发现EventBus就是用于

      SDK的API的函数回调效果,比如登录,首先去请求一个接口,API提供的login接口,然后后台通过Event来回调

      结果,之前我处理的都是网络请求,但是这个是采用Event事件的方式来回调,更加简单易懂。注意:有那个注

      解的地方@Subscribe(threadMode=ThreadMode.MAIN)的地方一定就是用了Event的地方,这里便是回调。

    4.2.然后就是对于EventBus一定要先注册,一般在onStart中注册,然后反注册,一般在onStop或者onDestroy中反

      注册。

    4.3.然后就是对于软键盘的弹起方式有了新的理解,这里采用view的invisible或者gone来实现,当然同时要确定

      什么时候invisible,什么时候gone,这里用了一个视图树来配合。如果视图树中某个视图发生改变,采用了

      addOnGlobalLayoutListener的方式复写了一个onGlobalLayout的方法来确定什么时候。

    4.4.问题在于怎么确定软键盘是否弹起。这里也是采用了根布局rootView和Rect矩形和屏幕分辨率dm来配合,首先

      设软键盘高度为100,然后将根视图的可视区域存放到一个Rect中,然后根视图的bottom和矩形的bottom之差

      和软键盘高度的大小互相比较,以此为依据确定键盘是否弹出。

    4.5.点击事件相对来说,更加容易一些,记得要判断String是否为空,这里直接用.isEmpty即可。然后注册采用了

      请求一个网址,用手机默认浏览器打开即进入相应页面。这个IntentUtil基本上每个项目都可以参考。

     

    既然选择了,便不顾风雨兼程。Just follow yourself.
  • 相关阅读:
    左偏树
    论在Windows下远程连接Ubuntu
    ZOJ 3711 Give Me Your Hand
    SGU 495. Kids and Prizes
    POJ 2151 Check the difficulty of problems
    CodeForces 148D. Bag of mice
    HDU 3631 Shortest Path
    HDU 1869 六度分离
    HDU 2544 最短路
    HDU 3584 Cube
  • 原文地址:https://www.cnblogs.com/Jason-Jan/p/7861490.html
Copyright © 2020-2023  润新知