仿拉钩登录界面
对于一个好的app,用户体验首先是在第一位,然而用户首先看到的就是登录界面,如果下载过拉钩的app,他的登录界面是很华丽的,我今天模仿做了一个仿拉钩界面的登录,先看一下效果图:
在软键盘弹出的时候,输入框上移,头像缩小上移,键盘隐藏时输入框下滑,头像放大。下面说一下如何实现上面的华丽登录界面:
- 自定义圆形头像:
package com.gsww.www.loginview;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
/**
* Author : luweicheng on 2017/4/7 0007 11:25
* E-mail :1769005961@qq.com
* GitHub : https://github.com/luweicheng24
* function: 自定义圆形图片
*/
public class CircleImageView extends android.support.v7.widget.AppCompatImageView {
Paint paint;//画笔
public CircleImageView(Context context) {
this(context,null);
}
public CircleImageView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public CircleImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
paint = new Paint();
paint.setAntiAlias(true);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
/**
* 绘制圆形图片
* @author caizhiming
*/
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (null != drawable) {
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
Bitmap b = getCircleBitmap(bitmap);
final Rect rectSrc = new Rect(0, 0, b.getWidth(), b.getHeight());
final Rect rectDest = new Rect(0,0,getWidth(),getHeight());
Log.e("Circle", "onDraw: b.getWidth="+b.getWidth()+"b.getHeight="+b.getHeight()+"getWidth="+getWidth()+"getHeight()="+getHeight() );
paint.reset();
canvas.drawBitmap(b, rectSrc, rectDest, paint);
} else {
super.onDraw(canvas);
}
}
/**
* 获取圆形图片方法
* @param bitmap
* @return Bitmap
* @author caizhiming
*/
private Bitmap getCircleBitmap(Bitmap bitmap) {
int length = bitmap.getHeight()>bitmap.getWidth()?bitmap.getWidth():bitmap.getHeight();
Log.e("circle", "getCircleBitmap: length=="+length );
Bitmap output = Bitmap.createBitmap(length,
length, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);//创建一个图片画布
paint.setAntiAlias(true);//去除锯齿
canvas.drawCircle(length/2 ,length/2 , length/2 , paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));//设置重叠显示模式
canvas.drawBitmap(bitmap, 0, 0, paint);
return output;
}
}
- 创建登录界面:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/login_background"
tools:context="com.gsww.www.loginview.MainActivity">
<com.gsww.www.loginview.CircleImageView
android:id="@+id/header"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="40dp"
android:src="@drawable/girl_4" />
<ScrollView
android:id="@+id/scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">//**设置ScrollerView充满屏幕
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:alpha="0.8"
android:gravity="center"
android:orientation="vertical"
android:paddingTop="80dp">
<EditText
android:id="@+id/et_name"
android:layout_width="250dp"
android:layout_height="50dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="40dp"
android:background="@drawable/login_shape"
android:hint="phone"
android:inputType="phone"
android:paddingLeft="20dp"
android:textColor="#fff"
android:textColorHint="#fff" />
<EditText
android:id="@+id/et_psw"
android:layout_width="250dp"
android:layout_height="50dp"
android:layout_below="@+id/et_name"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:background="@drawable/login_shape"
android:hint="password"
android:inputType="numberPassword"
android:paddingLeft="20dp"
android:textColor="@color/colorWhilte"
android:textColorHint="#fff" />
<Button
android:id="@+id/but_login"
android:layout_width="250dp"
android:layout_height="50dp"
android:layout_marginTop="40dp"
android:background="@drawable/but_login_shape"
android:text="login in"
android:textAllCaps="false"
android:textColor="#fff"
android:textSize="15sp" />
</LinearLayout>
</ScrollView>
<LinearLayout
android:id="@+id/ll_bottom"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10dp">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="@string/again_regist"
android:textColor="#ccc" />
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="@string/rember_psw"
android:textColor="@color/colorWhilte" />
</LinearLayout>
</RelativeLayout>
- 创建登录Activity:
package com.gsww.www.loginview;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
public class MainActivity extends AppCompatActivity implements View.OnLayoutChangeListener {
private RelativeLayout root; //根布局
private CircleImageView header;//圆形头像
private LinearLayout ll_bottom;//底部布局
private int changeHeight; //屏幕高度的1/3
private ScrollView scrollView;//滑动布局
public static final String TAG = "MainActivity";
private float scale = 0.7f; //缩放比例
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindView();
}
/**
* 绑定布局
*/
private void bindView() {
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
changeHeight = dm.heightPixels / 3;
root = (RelativeLayout) findViewById(R.id.root);
header = (CircleImageView) findViewById(R.id.header);
ll_bottom = (LinearLayout) findViewById(R.id.ll_bottom);
scrollView = (ScrollView) findViewById(R.id.scroll);
root.addOnLayoutChangeListener(this);//对根布局变化时候监听
}
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
Log.e(TAG, "onLayoutChange:bottom " + bottom + "oldBottom" + oldBottom);
final int change = bottom - oldBottom;//键盘弹出时候布局的变化值
if (bottom != 0 && oldBottom != 0 && change > changeHeight) {//键盘落下
runOnUiThread(new Runnable() {
@Override
public void run() {
scrollView.smoothScrollTo(0, scrollView.getHeight());
}
});
int length = change - changeHeight;
ZoomOut(header, length);
ll_bottom.setVisibility(View.VISIBLE);
} else if (bottom != 0 && oldBottom != 0 && -change > changeHeight) {
runOnUiThread(new Runnable() {
@Override
public void run() {
scrollView.smoothScrollTo(0, scrollView.getHeight());
}
});
int length = -change - changeHeight;
Log.e(TAG, "onLayoutChange: length=" + length);
ZoomIn(header, length);
ll_bottom.setVisibility(View.GONE);
}
}
/**
* 图像放大下移
*
* @param view
* @param length
*/
private void ZoomOut(CircleImageView view, int length) {
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(200);
mAnimatorSet.start();
}
/**
* 头像缩小上移
*
* @param view
* @param length
*/
private void ZoomIn(CircleImageView view, int length) {
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, -length);
mAnimatorSet.play(mAnimatorTranslateY).with(mAnimatorScaleX);
mAnimatorSet.play(mAnimatorScaleX).with(mAnimatorScaleY);
mAnimatorSet.setDuration(200);
mAnimatorSet.start();
}
}
上面的代码注释很详细,仔细阅读其实也不难,如果有其他问题及时评论,一起探讨。Github源码点击查看