想要实现的效果如图所示。可以划分为两个界面,启动页和登录页,动效是做在登录界面的,这样当用户登录的时候,就不会有整个动效出现。显示的界面其实是三个:
1、启动APP时会显示一个临时窗口Starting Window,所以在启动app之后会看到一个window背景,这个背景会根据theme来显示是黑屏还是白屏。所以我们要给启动页设置 android:windowBackground为启动页的Logo
2、启动页带logo以及下面的文字
3、登录界面带Logo并有上移动效
主要要解决的问题是让着三个界面里的logo能够重叠,适配不同机型。
我的想法是将三个界面的Logo都放在屏幕中间(要注意navigation bar与status bar对屏幕高度的影响,因为windowBackground里是没有navigationbar的高度的,那么启动页里也要隐藏navigationbar)这样他们就能够完美得融为一体。
因为不同的屏幕尺寸不同,所以启动页的图片没有让ui给大图,而是只给logo,通过.9的方式拉伸logo外的白色区域这样就可以填充整个区域(.9图中的黑线左上是拉伸区域,右下是显示内容区域。我因为右下黑线没有全覆盖导致启动页不是全屏)或者自定义layer-list:(参考https://blog.csdn.net/hdhhd/article/details/80828524,我不是用的这个)
<style name="AppTheme.Launcher" parent="Theme.AppCompat.Light.NoActionBar">
<!-- 通过windowBackground可以设置背景色、背景图片、能解析出图片的XML文件等-->
<item name="android:windowBackground">@drawable/layer_launcher</item>
<item name="windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
</style>
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<item>
<bitmap
android:gravity="center"
android:src="@drawable/launch_logo" />
</item>
</layer-list>
启动页布局
<android.support.constraint.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:id="@+id/cl"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/transparent"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/logo"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/copy_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="35dp"
android:gravity="center"
android:text="@string/copy_right"
android:textColor="@color/color_a0a6b3"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1" />
</android.support.constraint.ConstraintLayout>
启动页activity里要设置activity的启动动画
IntentUtils.startActivity(this, LoginWithPasswordActivity.class);
finish();
//取消界面跳转时的动画,使启动页的logo图片与注册、登录主页的logo图片完美衔接
overridePendingTransition(0, 0);
隐藏启动页的status bar和navigation bar
/**
* 隐藏navigationbar和statusbar
*/
private void hideStatusNavigationBar() {
View decordView = getWindow().getDecorView();
decordView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
登陆界面布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:fitsSystemWindows="true">
<!--<include layout="@layout/common_navigation" />-->
<ImageView
android:id="@+id/logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/normal_200"
android:layout_centerHorizontal="true"
android:layout_centerInParent="true"
android:src="@drawable/ic_logo_login"/>
<RelativeLayout
android:id="@+id/rl_user_account"
android:layout_width="@dimen/normal_562"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:alpha="0">
<com.cloudy.component.store.app.widget.ClearEditText
android:id="@+id/et_phone_number"
android:layout_width="match_parent"
android:layout_height="@dimen/normal_80"
android:background="@null"
android:ellipsize="end"
android:gravity="left|center_vertical"
android:hint="@string/login_input_account_phone_number"
android:maxLines="1"
android:textColor="@color/color_333333"
android:textColorHint="@color/color_aaaaaa"
android:textSize="@dimen/activity_set_text_30"/>
<!-- android:inputType="number"-->
<View
android:id="@+id/view_divider_1"
android:layout_width="match_parent"
android:layout_height="@dimen/normal_2"
android:layout_below="@id/et_phone_number"
android:background="@color/color_d3d3d3"/>
<com.cloudy.component.store.app.widget.ClearEditText
android:id="@+id/et_login_password"
android:layout_width="match_parent"
android:layout_height="@dimen/normal_80"
android:layout_marginTop="@dimen/normal_24"
android:layout_below="@id/view_divider_1"
android:background="@null"
android:ellipsize="end"
android:gravity="left|center_vertical"
android:hint="@string/login_input_password"
android:inputType="textPassword"
android:maxLength="16"
android:maxLines="1"
android:textColor="@color/color_333333"
android:textColorHint="@color/color_aaaaaa"
android:textSize="@dimen/activity_set_text_30"/>
<CheckBox
android:id="@+id/chb_display_psd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/et_login_password"
android:layout_alignParentRight="true"
android:button="@drawable/selector_password"
android:checked="false"/>
<View
android:id="@+id/view_divider_2"
android:layout_width="match_parent"
android:layout_height="@dimen/normal_2"
android:layout_below="@id/et_login_password"
android:background="@color/color_d3d3d3"/>
<TextView
android:id="@+id/tv_register_account"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/normal_40"
android:layout_below="@id/et_login_password"
android:text="@string/register_account"
android:textColor="@color/color_7b7b7b"
android:textSize="@dimen/activity_set_text_24"
android:visibility="gone"/>
<TextView
android:id="@+id/tv_forget_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/normal_40"
android:layout_alignParentRight="true"
android:layout_below="@id/et_login_password"
android:text="@string/login_forget_password"
android:textColor="@color/color_7b7b7b"
android:textSize="@dimen/activity_set_text_24"
android:visibility="gone"/>
</RelativeLayout>
<com.cloudy.component.store.app.widget.textview.PressEffectiveButton
android:id="@+id/btn_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/normal_220"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/selector_bg_login_button"
android:enabled="false"
android:alpha="0"
android:gravity="center"
android:text="@string/login"
android:textColor="@color/white"
android:textSize="@dimen/activity_set_text_32"/>
</RelativeLayout>
登陆界面动效
/**用户名密码输入部分**/
@InjectView(R.id.rl_user_account)
RelativeLayout mRlUserAccount;
/** 登录按钮 */
@InjectView(R.id.btn_login)
PressEffectiveButton mBtnLogin;
@InjectView(R.id.logo)
ImageView mImLogo;
/**
* 初始化logo图片以及底部注册、登录的按钮动画
*/
private void initAnims() {
//初始化底部注册、登录的按钮动画
//以控件自身所在的位置为原点,从下方距离原点200像素的位置移动到原点
ObjectAnimator tranLogin = ObjectAnimator.ofFloat(mRlUserAccount, "translationY", 200, 0);
ObjectAnimator tranRegister = ObjectAnimator.ofFloat(mBtnLogin, "translationY", 200, 0);
//将注册、登录的控件alpha属性从0变到1
ObjectAnimator alphaLogin = ObjectAnimator.ofFloat(mRlUserAccount, "alpha", 0, 1);
ObjectAnimator alphaRegister = ObjectAnimator.ofFloat(mBtnLogin, "alpha", 0, 1);
final AnimatorSet bottomAnim = new AnimatorSet();
bottomAnim.setDuration(1000);
//同时执行控件平移和alpha渐变动画
bottomAnim.play(tranLogin).with(tranRegister).with(alphaLogin).with(alphaRegister);
//获取屏幕高度
WindowManager manager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics metrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(metrics);
int screenHeight = metrics.heightPixels;
//通过测量,获取ivLogo的高度
int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
mImLogo.measure(w, h);
int logoHeight = mImLogo.getMeasuredHeight();
//初始化ivLogo的移动和缩放动画
float transY = (screenHeight - logoHeight) * 0.28f;
//ivLogo向上移动 transY 的距离
ObjectAnimator tranLogo = ObjectAnimator.ofFloat(mImLogo, "translationY", 0, -transY);
AnimatorSet logoAnim = new AnimatorSet();
logoAnim.setDuration(1000);
logoAnim.play(tranLogo);
logoAnim.start();
logoAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
//待ivLogo的动画结束后,开始播放底部注册、登录按钮的动画
bottomAnim.start();
}
});
}