亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

Android登陸頁面仿拉鉤動效,你總會需要它!

標簽:
Android

哈哈,看到这个标题是不是JH一紧,你可能会说我就没遇到过,但是现在没遇到不代表就遇不到,毕竟设计也是变幻莫测,只有你想不到的,没有你不能实现的,说的这么吊,到底是啥效果?没错就是一个小小的登录页面,大家都有拉勾app吧,看拉勾的登录页做的很是平滑动画,而且带动画效果,所以就有了类似拉勾登录效果,如图:

5ba2082d0001c9be02810500.jpg

登录动画


我们要想监听键盘事件,首先我们想得到的是键盘弹起的时候我们可以去搞点事情,键盘搜起的时候我们再去搞点事情,知道这些还不够,我们还要知道键盘弹起了多少,以及需要平移多少的距离。我们都知道我们的一个页面弹起键盘的时候这个页面的根布局会回调他的监听方法:addOnLayoutChangeListener( );当键盘弹起的时候,我们的布局是变化了,因此会执行这个回调方法,但是前提是必须设置我们的Activity的windowSoftInputMode属性为adjustResize。

我们想让布局整体平移的距离也就是弹起时候处于最底部的view距离顶部的高度减去我们键盘的高度。现在认为只要控件将Activity向上推的高度超过了1/3屏幕高,就认为软键盘弹起

scrollView.addOnLayoutChangeListener(new ViewGroup.OnLayoutChangeListener() {
            @Override            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {              /* old是改变前的左上右下坐标点值,没有old的是改变后的左上右下坐标点值
              现在认为只要控件将Activity向上推的高度超过了1/3屏幕高,就认为软键盘弹起*/
                if (oldBottom != 0 && bottom != 0 && (oldBottom - bottom > keyHeight)) {
                    Log.e("wenzhihao", "up------>"+(oldBottom - bottom));                    int dist = btn_login.getBottom() - bottom;                    if (dist>0){
                        ObjectAnimator mAnimatorTranslateY = ObjectAnimator.ofFloat(content, "translationY", 0.0f, -dist);
                        mAnimatorTranslateY.setDuration(300);
                        mAnimatorTranslateY.setInterpolator(new LinearInterpolator());
                        mAnimatorTranslateY.start();
                        zoomIn(logo, dist);
                    }
                    service.setVisibility(View.INVISIBLE);

                } else if (oldBottom != 0 && bottom != 0 && (bottom - oldBottom > keyHeight)) {
                    Log.e("wenzhihao", "down------>"+(bottom - oldBottom));                    if ((btn_login.getBottom() - oldBottom)>0){
                        ObjectAnimator mAnimatorTranslateY = ObjectAnimator.ofFloat(content, "translationY", content.getTranslationY(), 0);
                        mAnimatorTranslateY.setDuration(300);
                        mAnimatorTranslateY.setInterpolator(new LinearInterpolator());
                        mAnimatorTranslateY.start();                        //键盘收回后,logo恢复原来大小,位置同样回到初始位置
                        zoomOut(logo);
                    }
                    service.setVisibility(View.VISIBLE);
                }
            }
        });//btn_login是登录按钮

这样我们发现是可以实现效果了,但是我想全屏显示,懵比了,发现全屏的时候不回调这个方法了,怎么办?又是查资料一看原来这个也是一个bug,但是有解决方案,AndroidBug5497Workaround。也是谷歌提供的?直接拷贝过来,会发现其实他的作用就是让Activity最外层的根布局,当有布局变化时去响应这个变化mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener();

package com.wzh.study.login;import android.app.Activity;import android.graphics.Rect;import android.view.View;import android.view.ViewTreeObserver;import android.widget.FrameLayout;public class AndroidBug5497Workaround {    // For more information, see https://code.google.com/p/android/issues/detail?id=5497
    // To use this class, simply invoke assistActivity() on an Activity that already has its content view set.

    public static void assistActivity (Activity activity) {        new AndroidBug5497Workaround(activity);
    }    private View mChildOfContent;    private int usableHeightPrevious;    private FrameLayout.LayoutParams frameLayoutParams;    private AndroidBug5497Workaround(Activity activity) {
        FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
        mChildOfContent = content.getChildAt(0);
        mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {            public void onGlobalLayout() {
                possiblyResizeChildOfContent();
            }
        });
        frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
    }    private void possiblyResizeChildOfContent() {        int usableHeightNow = computeUsableHeight();        if (usableHeightNow != usableHeightPrevious) {            int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();            int heightDifference = usableHeightSansKeyboard - usableHeightNow;            if (heightDifference > (usableHeightSansKeyboard/4)) {                // keyboard probably just became visible
                frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
            } else {                // keyboard probably just became hidden
                frameLayoutParams.height = usableHeightSansKeyboard;
            }
            mChildOfContent.requestLayout();
            usableHeightPrevious = usableHeightNow;
        }
    }    private int computeUsableHeight() {
        Rect r = new Rect();
        mChildOfContent.getWindowVisibleDisplayFrame(r);        return (r.bottom - r.top);
    }

}

使用方式,如果我们设置了全屏,就去加载它,不设置不管:

if(isFullScreen(this)){
            AndroidBug5497Workaround.assistActivity(this);
}
...public boolean isFullScreen(Activity activity) {    return (activity.getWindow().getAttributes().flags &
            WindowManager.LayoutParams.FLAG_FULLSCREEN)==WindowManager.LayoutParams.FLAG_FULLSCREEN;
}

接下来就看具体动画事件了,键盘弹起来的时候整体向上平移,LOGO缩小,键盘收起的时候整体下移,并且LOGO恢复原来大小。这里用到的都是属性动画,只有属性动画我们才可以实现真正平移效果。

我看网上很多人使用addOnLayoutChangeListener()去监听键盘事件,但是这个方法回调的太频繁,比如本例特效,输入框后面有文字时候显示清除的图标,如果用这个方法那么也会执行一次,可能会影响你的动画,当然你也可以去记录第一次的高度让他不会走逻辑,但是我觉得也不是很靠谱,虽然我这个方法也不是很棒 ๑乛乛๑~。

最后贴上源码:

package com.wzh.study.login;import android.animation.AnimatorSet;import android.animation.ObjectAnimator;import android.app.Activity;import android.os.Bundle;import android.support.annotation.Nullable;import android.support.v4.app.FragmentActivity;import android.support.v4.view.animation.LinearOutSlowInInterpolator;import android.text.Editable;import android.text.InputType;import android.text.TextUtils;import android.text.TextWatcher;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.view.WindowManager;import android.view.animation.LinearInterpolator;import android.widget.Button;import android.widget.EditText;import android.widget.ImageView;import android.widget.ScrollView;import android.widget.TextView;import android.widget.Toast;import com.wzh.study.R;/**
 * Created by WZH on 2017/3/25.
 */public class OtherLoginAct  extends FragmentActivity implements View.OnClickListener  {    private ImageView logo;    private ScrollView scrollView;    private EditText et_mobile;    private EditText et_password;    private ImageView iv_clean_phone;    private ImageView clean_password;    private ImageView iv_show_pwd;    private Button btn_login;    private TextView forget_password;    private int screenHeight = 0;//屏幕高度
    private int keyHeight = 0; //软件盘弹起后所占高度
    private float scale = 0.6f; //logo缩放比例
    private View service,content;    private int height = 0 ;    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_other_login);        if(isFullScreen(this)){
            AndroidBug5497Workaround.assistActivity(this);
        }
        initView();
        initListener();
    }    public boolean isFullScreen(Activity activity) {        return (activity.getWindow().getAttributes().flags &
                WindowManager.LayoutParams.FLAG_FULLSCREEN)==WindowManager.LayoutParams.FLAG_FULLSCREEN;
    }    private void initView() {
        logo = (ImageView) findViewById(R.id.logo);
        scrollView = (ScrollView) findViewById(R.id.scrollView);
        et_mobile = (EditText) findViewById(R.id.et_mobile);
        et_password = (EditText) findViewById(R.id.et_password);
        iv_clean_phone = (ImageView) findViewById(R.id.iv_clean_phone);
        clean_password = (ImageView) findViewById(R.id.clean_password);
        iv_show_pwd = (ImageView) findViewById(R.id.iv_show_pwd);
        btn_login = (Button) findViewById(R.id.btn_login);
        forget_password = (TextView) findViewById(R.id.forget_password);
        service = findViewById(R.id.service);
        content = findViewById(R.id.content);
        screenHeight = this.getResources().getDisplayMetrics().heightPixels; //获取屏幕高度
        keyHeight = screenHeight / 3;//弹起高度为屏幕高度的1/3
    }    private void initListener() {
        iv_clean_phone.setOnClickListener(this);
        clean_password.setOnClickListener(this);
        iv_show_pwd.setOnClickListener(this);
        et_mobile.addTextChangedListener(new TextWatcher() {            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }            @Override
            public void afterTextChanged(Editable s) {                if (!TextUtils.isEmpty(s) && iv_clean_phone.getVisibility() == View.GONE) {
                    iv_clean_phone.setVisibility(View.VISIBLE);
                } else if (TextUtils.isEmpty(s)) {
                    iv_clean_phone.setVisibility(View.GONE);
                }
            }
        });
        et_password.addTextChangedListener(new TextWatcher() {            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }            @Override
            public void afterTextChanged(Editable s) {                if (!TextUtils.isEmpty(s) && clean_password.getVisibility() == View.GONE) {
                    clean_password.setVisibility(View.VISIBLE);
                } else if (TextUtils.isEmpty(s)) {
                    clean_password.setVisibility(View.GONE);
                }                if (s.toString().isEmpty())                    return;                if (!s.toString().matches("[A-Za-z0-9]+")) {
                    String temp = s.toString();
                    Toast.makeText(OtherLoginAct.this, R.string.please_input_limit_pwd, Toast.LENGTH_SHORT).show();
                    s.delete(temp.length() - 1, temp.length());
                    et_password.setSelection(s.length());
                }
            }
        });        /**
         * 禁止键盘弹起的时候可以滚动
         */
        scrollView.setOnTouchListener(new View.OnTouchListener() {            @Override
            public boolean onTouch(View v, MotionEvent event) {                return true;
            }
        });
        scrollView.addOnLayoutChangeListener(new ViewGroup.OnLayoutChangeListener() {            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {              /* old是改变前的左上右下坐标点值,没有old的是改变后的左上右下坐标点值
              现在认为只要控件将Activity向上推的高度超过了1/3屏幕高,就认为软键盘弹起*/
                if (oldBottom != 0 && bottom != 0 && (oldBottom - bottom > keyHeight)) {
                    Log.e("wenzhihao", "up------>"+(oldBottom - bottom));                    int dist = content.getBottom() - bottom;                    if (dist>0){
                        ObjectAnimator mAnimatorTranslateY = ObjectAnimator.ofFloat(content, "translationY", 0.0f, -dist);
                        mAnimatorTranslateY.setDuration(300);
                        mAnimatorTranslateY.setInterpolator(new LinearInterpolator());
                        mAnimatorTranslateY.start();
                        zoomIn(logo, dist);
                    }
                    service.setVisibility(View.INVISIBLE);

                } else if (oldBottom != 0 && bottom != 0 && (bottom - oldBottom > keyHeight)) {
                    Log.e("wenzhihao", "down------>"+(bottom - oldBottom));                    if ((content.getBottom() - oldBottom)>0){
                        ObjectAnimator mAnimatorTranslateY = ObjectAnimator.ofFloat(content, "translationY", content.getTranslationY(), 0);
                        mAnimatorTranslateY.setDuration(300);
                        mAnimatorTranslateY.setInterpolator(new LinearInterpolator());
                        mAnimatorTranslateY.start();                        //键盘收回后,logo恢复原来大小,位置同样回到初始位置
                        zoomOut(logo);
                    }
                    service.setVisibility(View.VISIBLE);
                }
            }
        });
    }    /**
     * 缩小
     * @param view
     */
    public void zoomIn(final View view, float dist) {
        view.setPivotY(view.getHeight());
        view.setPivotX(view.getWidth() / 2);
        AnimatorSet mAnimatorSet = new AnimatorSet();
        ObjectAnimator mAnimatorScaleX = ObjectAnimator.ofFloat(view, "scaleX", 1.0f, scale);
        ObjectAnimator mAnimatorScaleY = ObjectAnimator.ofFloat(view, "scaleY", 1.0f, scale);
        ObjectAnimator mAnimatorTranslateY = ObjectAnimator.ofFloat(view, "translationY", 0.0f, -dist);

        mAnimatorSet.play(mAnimatorTranslateY).with(mAnimatorScaleX);
        mAnimatorSet.play(mAnimatorScaleX).with(mAnimatorScaleY);
        mAnimatorSet.setDuration(300);
        mAnimatorSet.start();
    }    /**
     * f放大
     * @param view
     */
    public void zoomOut(final View view) {
        view.setPivotY(view.getHeight());
        view.setPivotX(view.getWidth() / 2);
        AnimatorSet mAnimatorSet = new AnimatorSet();

        ObjectAnimator mAnimatorScaleX = ObjectAnimator.ofFloat(view, "scaleX", scale, 1.0f);
        ObjectAnimator mAnimatorScaleY = ObjectAnimator.ofFloat(view, "scaleY", scale, 1.0f);
        ObjectAnimator mAnimatorTranslateY = ObjectAnimator.ofFloat(view, "translationY", view.getTranslationY(), 0);

        mAnimatorSet.play(mAnimatorTranslateY).with(mAnimatorScaleX);
        mAnimatorSet.play(mAnimatorScaleX).with(mAnimatorScaleY);
        mAnimatorSet.setDuration(300);
        mAnimatorSet.start();
    }    @Override
    public void onClick(View v) {        int id = v.getId();        switch (id) {            case R.id.iv_clean_phone:
                et_mobile.setText("");                break;            case R.id.clean_password:
                et_password.setText("");                break;            case R.id.iv_show_pwd:                if (et_password.getInputType() != InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) {
                    et_password.setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
                    iv_show_pwd.setImageResource(R.drawable.pass_visuable);
                } else {
                    et_password.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
                    iv_show_pwd.setImageResource(R.drawable.pass_gone);
                }
                String pwd = et_password.getText().toString();                if (!TextUtils.isEmpty(pwd))
                    et_password.setSelection(pwd.length());                break;
        }
    }
}

如果有什么问题欢迎指出,我将给出例子地址,包含另一种实现方式就是用scrollview滑动到最底部的方式来实现平移效果~
github地址

原文链接:http://www.apkbus.com/blog-719059-63447.html

點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消