-
Notifications
You must be signed in to change notification settings - Fork 0
/
LoginActivity.java
211 lines (183 loc) · 7.26 KB
/
LoginActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
package wang.relish.textsample;
import android.animation.ObjectAnimator;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import androidx.appcompat.app.AppCompatActivity;
import butterknife.BindView;
import butterknife.ButterKnife;
import wang.relish.textsample.keyboard.GlobalLayoutListener;
import wang.relish.textsample.keyboard.PixelUtil;
/**
* 登录页
*
* @author Relish Wang
* @since 2019/03/06
*/
public class LoginActivity extends AppCompatActivity {
public static final String KEY_HISTORY_ACCOUNTS = "__accounts__";
@BindView(R.id.ll_root)
View rootView;
@BindView(R.id.act_account)
WXAutoCompleteTextView mPhoneView;
@BindView(R.id.et_pwd)
EditText mPasswordView;
AccountAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//设置状态栏文字颜色及图标为深色
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
} else {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
setContentView(R.layout.activity_login);
ButterKnife.bind(this);
initData();
initViews();
}
private AnimHandler mHandler;
private void initViews() {
mHandler = new AnimHandler(this);
mPhoneView.setOnShowWindowListener(new WXAutoCompleteTextView.OnShowWindowListener() {
@Override
public boolean beforeShow() {
// 屏幕没空间了 或 键盘收起来了
if (Math.abs(mScreenHeight) < 0.1 || Math.abs(mKeyboardHeight) < 0.1) {
return false; // 键盘收起且需要滑动的页面的的时候拒绝展示PopupWindow
}
// 没数据的时候 不显示
if (mAdapter == null || mAdapter.getCount() == 0) return false;
mHeightNeeded = ACTVHeightUtil.setDropDownHeight(mPhoneView, 3);
if (mHeightNeeded == -1) return true;
Log.d(App.TAG, "mHeightNeeded = " + mHeightNeeded);
Rect rect = Util.getLocation(mPhoneView);
float freeHeightInFact = mScreenHeight/*这个屏幕高度已经减去mKeyBoardHeight了*/ - rect.bottom - PixelUtil.toPixelFromDIP(10)/*android:dropDownVerticalOffset="2dp"*/;
Log.d(App.TAG, "freeHeightInFact = " + freeHeightInFact);
if (freeHeightInFact >= mHeightNeeded - 15) return true;// 误差大概在10.75左右, 不需要执行动画
animatorFromY2Y(-(mHeightNeeded - freeHeightInFact));// 300ms上移动画
return true;
}
});
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new GlobalLayoutListener(rootView,
(isShow, keyboardHeight, screenWidth, screenHeight) -> {
if (isShow) {
mKeyboardHeight = keyboardHeight;// 当前键盘高度
mScreenHeight = screenHeight;// 当前键盘可用高度
} else {
mScreenHeight = 0;
}
Log.d(App.TAG, "mScreenHeight = " + mScreenHeight);
mIsShow = isShow;
mHandler.removeMessages(AnimHandler.KEYBOARD_CHANGE);
mHandler.sendEmptyMessageDelayed(AnimHandler.KEYBOARD_CHANGE, 100);
}));
}
private boolean mIsShow; // 键盘是否展示
public void handleKeyboardEvent() {
if (!mIsShow) {
// 用100ms隐藏弹窗, 用300ms做下滑动画, 再过50ms显示弹窗
if (mPhoneView.isPopupShowing()) {
mPhoneView.dismissDropDown();
}
animatorFromY2Y(0);// 回归初始状态
} else {
if (mPhoneView.isFocused() && mAdapter != null && mAdapter.getCount() > 0) {
mPhoneView.showDropDown();
}
}
}
private void initData() {
final String cacheDataJson = Util.getString(KEY_HISTORY_ACCOUNTS, "[]");
List<Util.User> users = new Gson().fromJson(cacheDataJson, new TypeToken<List<Util.User>>() {
}.getType());
setViewWithInfo(users == null ? new ArrayList<>() : users);
}
/**
* 设置预填充数据
*
* @param users 账号信息
*/
private void setViewWithInfo(List<Util.User> users) {
if (users == null) return;
mAdapter = new AccountAdapter(users, user -> {
// 点击了某条候选账号,自动填充手机号和密码
final String phone = user.phone;
final String password = user.password;
mPhoneView.setText(phone);
mPhoneView.setSelection(phone == null ? 0 : phone.length());
mPasswordView.setText(password);
mPasswordView.setSelection(password == null ? 0 : password.length());
mPhoneView.dismissDropDown();
});
mPhoneView.setAdapter(mAdapter);
final Util.User user = users.get(users.size() - 1);
if (user == null) return;
final String loginName = user.phone;
// mPhoneView.setText(loginName);
// mPhoneView.setSelection(loginName == null ? 0 : loginName.length());
final String password = user.password;
// mPasswordView.setText(password);
// mPasswordView.setSelection(password == null ? 0 : password.length());
}
/**
* 监听物理返回键,优先关闭候选账号列表窗口
*/
@Override
public void onBackPressed() {
if (mPhoneView != null && mPhoneView.isPopupShowing()) {
mPhoneView.dismissDropDown();
} else {
super.onBackPressed();
}
}
private float mKeyboardHeight;
private float mScreenHeight;// 屏幕可用高度
private float mHeightNeeded = -1;
/**
* 记录动画移动到的位置
*/
private float mOldY = 0;
private void animatorFromY2Y(float newY) {
ObjectAnimator animator = Util.objectAnimator(
rootView,
"translationY",
mOldY,
newY,
0,
null);
animator.start();
Log.d(App.TAG, "执行动画: " + mOldY + "->" + newY);
mOldY = newY;
}
}
final class AnimHandler extends Handler {
static final int KEYBOARD_CHANGE = 0xebad;
private final WeakReference<LoginActivity> aty;
AnimHandler(LoginActivity aty) {
this.aty = new WeakReference<LoginActivity>(aty);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case KEYBOARD_CHANGE: {
LoginActivity activity = aty.get();
if (activity != null) {
activity.handleKeyboardEvent();
}
break;
}
}
}
}