Drew 6 lat temu
rodzic
commit
f2604da883
27 zmienionych plików z 693 dodań i 262 usunięć
  1. 2 12
      app/src/main/AndroidManifest.xml
  2. 0 14
      app/src/main/aidl/com/ht/gate/IMyAidlInterface.aidl
  3. BIN
      app/src/main/assets/video_background.mp4
  4. 21 12
      app/src/main/java/com/ht/gate/CustomKeyboardView.java
  5. 0 81
      app/src/main/java/com/ht/gate/LocalService.java
  6. 7 3
      app/src/main/java/com/ht/gate/LoginActivity.java
  7. 0 56
      app/src/main/java/com/ht/gate/MyApplication.java
  8. 130 0
      app/src/main/java/com/ht/gate/PasswordDialog.java
  9. 0 69
      app/src/main/java/com/ht/gate/RemoteService.java
  10. 34 13
      app/src/main/java/com/ht/gate/UnlockView.java
  11. 66 0
      app/src/main/java/com/ht/gate/VideoBackground.java
  12. 14 0
      app/src/main/java/com/ht/gate/WelcomeActivity.java
  13. 13 0
      app/src/main/java/com/ht/gate/activity/MainActivity.java
  14. 5 0
      app/src/main/res/anim/decelerate_interpolator.xml
  15. 11 0
      app/src/main/res/anim/dialog_enter.xml
  16. 12 0
      app/src/main/res/anim/dialog_exit.xml
  17. 7 0
      app/src/main/res/drawable/bg_welcome.xml
  18. 17 1
      app/src/main/res/layout/activity_login.xml
  19. 5 0
      app/src/main/res/layout/activity_main.xml
  20. 201 0
      app/src/main/res/layout/activity_welcome.xml
  21. 65 0
      app/src/main/res/layout/dialog_password.xml
  22. BIN
      app/src/main/res/raw/video_background.mp4
  23. BIN
      app/src/main/res/raw/video_placeholder.png
  24. 5 0
      app/src/main/res/values/attr.xml
  25. 13 0
      app/src/main/res/values/styles.xml
  26. 1 1
      app/src/main/res/xml/custom_keyboard.xml
  27. 64 0
      app/src/main/res/xml/custom_keyboard_number.xml

+ 2 - 12
app/src/main/AndroidManifest.xml

@@ -4,7 +4,6 @@
     package="com.ht.gate">
 
     <application
-        android:name=".MyApplication"
         android:allowBackup="true"
         android:icon="@mipmap/ic_launcher"
         android:label="@string/app_name"
@@ -12,7 +11,8 @@
         android:supportsRtl="false"
         android:theme="@style/AppTheme"
         tools:ignore="GoogleAppIndexingWarning">
-        <activity android:name=".activity.MainActivity"></activity>
+        <activity android:name=".WelcomeActivity"></activity>
+        <activity android:name=".activity.MainActivity" />
         <activity android:name=".LoginActivity">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -20,16 +20,6 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
-
-        <service
-            android:name=".LocalService"
-            android:enabled="true"
-            android:exported="true" />
-        <service
-            android:name=".RemoteService"
-            android:enabled="true"
-            android:exported="true"
-            android:process=":RemoteProcess" />
     </application>
 
 </manifest>

+ 0 - 14
app/src/main/aidl/com/ht/gate/IMyAidlInterface.aidl

@@ -1,14 +0,0 @@
-// IMyAidlInterface.aidl
-package com.ht.gate;
-
-// Declare any non-default types here with import statements
-
-interface IMyAidlInterface {
-    /**
-     * Demonstrates some basic types that you can use as parameters
-     * and return values in AIDL.
-     */
-    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
-            double aDouble, String aString);
-    String getServiceName();
-}

BIN
app/src/main/assets/video_background.mp4


+ 21 - 12
app/src/main/java/com/ht/gate/view/CustomKeyboardView.java → app/src/main/java/com/ht/gate/CustomKeyboardView.java

@@ -1,4 +1,4 @@
-package com.ht.gate.view;
+package com.ht.gate;
 
 import android.animation.Animator;
 import android.annotation.SuppressLint;
@@ -55,6 +55,7 @@ public class CustomKeyboardView extends View {
     public static final int KEYCODE_CANCEL = -3;
     public static final int KEYCODE_DONE = -4;
     public static final int KEYCODE_DELETE = -5;
+    public static final int KEYCODE_SHIFT = 16;
 
     private static final int NOT_A_KEY = -1;
     private static final int[] KEY_DELETE = {Keyboard.KEYCODE_DELETE};
@@ -113,6 +114,7 @@ public class CustomKeyboardView extends View {
     private int mBtnCancelColor = 0x80ffffff;
     private int mBtnConfirmColor = 0xFFE4BF85;
     private int mKeyBackgroundColor = 0xff444857;
+    private int mKeyBackgroundColorDisable = 0x99444857;
     private int mLegendBackground = 0xFF2B2E3A;
     private Typeface source_han_sans_sc_normal;
     private Typeface source_han_sans_sc_medium;
@@ -185,7 +187,6 @@ public class CustomKeyboardView extends View {
 
     public CustomKeyboardView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
-        setKeyboard(new Keyboard(getContext(), R.xml.custom_keyboard));
         mPaint = new Paint();
         mPaint.setAntiAlias(true);
 
@@ -220,7 +221,15 @@ public class CustomKeyboardView extends View {
         TypedArray t = getContext().obtainStyledAttributes(attrs,
                 R.styleable.CustomKeyboardView);
         mLegend = t.getString(R.styleable.CustomKeyboardView_legend);
+        int type = t.getInt(R.styleable.CustomKeyboardView_type, 0);
+        if (type == 0) {
+            setKeyboard(new Keyboard(getContext(), R.xml.custom_keyboard));
+        } else {
+            setKeyboard(new Keyboard(getContext(), R.xml.custom_keyboard_number));
+        }
         t.recycle();
+
+        setBackgroundColor(0xFF333641);
     }
 
     @SuppressLint("HandlerLeak")
@@ -258,11 +267,7 @@ public class CustomKeyboardView extends View {
         if (mKeyboard == null) {
             setMeasuredDimension(mPaddingH * 2, mPaddingV * 2);
         } else {
-            int width = mKeyboard.getMinWidth() + mPaddingH * 2;
-            if (MeasureSpec.getSize(widthMeasureSpec) < width + 10) {
-                width = MeasureSpec.getSize(widthMeasureSpec);
-            }
-            setMeasuredDimension(width, mKeyboard.getHeight() + mPaddingV * 2 + mLegendHeight);
+            setMeasuredDimension(getResources().getDisplayMetrics().widthPixels, mKeyboard.getHeight() + mPaddingV * 2 + mLegendHeight);
         }
     }
 
@@ -320,10 +325,15 @@ public class CustomKeyboardView extends View {
                 RectF dst = new RectF(bmLeft, bmTop, bmLeft + bmCap.getWidth(), bmTop + bmCap.getHeight());
                 canvas.drawBitmap(bmCap, src, dst, mBitmapPaint);
             } else {
-                mPaint.setColor(mKeyBackgroundColor);
-                canvas.drawRoundRect(left, top, right, bottom, radius, radius, mPaint);
-                mPaint.setColor(Color.WHITE);
-                drawCenterText(canvas, mPaint, cap ? key.label.toString().toUpperCase() : key.label.toString(), left, top, right, bottom);
+                if (TextUtils.isEmpty(key.label)) {
+                    mPaint.setColor(mKeyBackgroundColorDisable);
+                    canvas.drawRoundRect(left, top, right, bottom, radius, radius, mPaint);
+                } else {
+                    mPaint.setColor(mKeyBackgroundColor);
+                    canvas.drawRoundRect(left, top, right, bottom, radius, radius, mPaint);
+                    mPaint.setColor(Color.WHITE);
+                    drawCenterText(canvas, mPaint, cap ? key.label.toString().toUpperCase() : key.label.toString(), left, top, right, bottom);
+                }
             }
         }
     }
@@ -342,7 +352,6 @@ public class CustomKeyboardView extends View {
                     detectAndSendKey(mCurrentKey, touchX, touchY, eventTime);
                 } else {
                     if (e.getX() < mLegendBtnWidth) {
-                        hide();
                         if (mKeyboardActionListener != null) {
                             mKeyboardActionListener.onKey(KEYCODE_CANCEL, new int[0]);
                         }

+ 0 - 81
app/src/main/java/com/ht/gate/LocalService.java

@@ -1,81 +0,0 @@
-package com.ht.gate;
-
-import android.app.Service;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-import android.widget.Toast;
-
-import com.ht.gate.activity.MainActivity;
-
-
-public class LocalService extends Service {
-    private static final String TAG = LocalService.class.getName();
-    private MyBinder mBinder;
-
-    private ServiceConnection connection = new ServiceConnection() {
-        @Override
-        public void onServiceConnected(ComponentName name, IBinder service) {
-            IMyAidlInterface iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
-            try {
-                Log.e("LocalService", "connected with " + iMyAidlInterface.getServiceName());
-                //TODO whh 本地service被拉起,检测如果mainActivity不存在则拉起
-                if (MyApplication.getLoginActivity() == null) {
-                    Intent intent = new Intent(LocalService.this.getBaseContext(), LoginActivity.class);
-                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                    getApplication().startActivity(intent);
-                }
-            } catch (RemoteException e) {
-                e.printStackTrace();
-            }
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName name) {
-            Toast.makeText(LocalService.this, "链接断开,重新启动 RemoteService", Toast.LENGTH_LONG).show();
-            Log.e(TAG, "onServiceDisconnected: 链接断开,重新启动 RemoteService");
-            startService(new Intent(LocalService.this, RemoteService.class));
-            bindService(new Intent(LocalService.this, RemoteService.class), connection, Context.BIND_IMPORTANT);
-        }
-    };
-
-    public LocalService() {
-    }
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-    }
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        Log.e(TAG, "onStartCommand: LocalService 启动");
-        Toast.makeText(this, "LocalService 启动", Toast.LENGTH_LONG).show();
-        startService(new Intent(LocalService.this, RemoteService.class));
-        bindService(new Intent(LocalService.this, RemoteService.class), connection, Context.BIND_IMPORTANT);
-        return START_STICKY;
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        mBinder = new MyBinder();
-        return mBinder;
-    }
-
-    private class MyBinder extends IMyAidlInterface.Stub {
-
-        @Override
-        public String getServiceName() throws RemoteException {
-            return LocalService.class.getName();
-        }
-
-        @Override
-        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
-
-        }
-    }
-}

+ 7 - 3
app/src/main/java/com/ht/gate/LoginActivity.java

@@ -11,10 +11,8 @@ import android.util.Log;
 import android.view.MotionEvent;
 import android.view.View;
 import android.widget.EditText;
-import android.widget.Toast;
 
 import com.ht.gate.activity.MainActivity;
-import com.ht.gate.view.CustomKeyboardView;
 
 import butterknife.BindView;
 import butterknife.ButterKnife;
@@ -30,6 +28,7 @@ public class LoginActivity extends AppCompatActivity {
     @BindView(R.id.unlock_view)
     UnlockView unlockView;
 
+    private boolean captalize;
     private KeyboardUtil keyboardUtil;
 
     @SuppressLint("ClickableViewAccessibility")
@@ -69,7 +68,11 @@ public class LoginActivity extends AppCompatActivity {
                 Editable editable = et.getText();
                 int start = et.getSelectionStart();
                 switch (primaryCode) {
+                    case CustomKeyboardView.KEYCODE_SHIFT:
+                        captalize = !captalize;
+                        break;
                     case CustomKeyboardView.KEYCODE_CANCEL:
+                        keyboardView.hide();
                         et.setVisibility(View.GONE);
                         unlockView.setVisibility(View.VISIBLE);
                         break;
@@ -84,7 +87,8 @@ public class LoginActivity extends AppCompatActivity {
                         }
                         break;
                     default:
-                        editable.insert(start, Character.toString((char) primaryCode));
+                        String str = Character.toString((char) primaryCode);
+                        editable.insert(start, captalize ? str.toUpperCase() : str.toLowerCase());
                         break;
                 }
             }

+ 0 - 56
app/src/main/java/com/ht/gate/MyApplication.java

@@ -1,56 +0,0 @@
-package com.ht.gate;
-
-import android.app.ActivityManager;
-import android.app.Application;
-import android.content.Context;
-import android.content.Intent;
-
-import com.ht.gate.activity.MainActivity;
-
-public class MyApplication extends Application {
-    private static LoginActivity loginActivity = null;
-
-    public static LoginActivity getLoginActivity() {
-        return loginActivity;
-    }
-
-    public static void setLoginActivity(LoginActivity loginActivity) {
-        MyApplication.loginActivity = loginActivity;
-    }
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        if (isMainProcess(getApplicationContext())) {
-            startService(new Intent(this, LocalService.class));
-        } else {
-            return;
-        }
-    }
-
-    /**
-     * 获取当前进程名
-     */
-    public String getCurrentProcessName(Context context) {
-        int pid = android.os.Process.myPid();
-        String processName = "";
-        ActivityManager manager = (ActivityManager) context.getApplicationContext().getSystemService
-                (Context.ACTIVITY_SERVICE);
-        for (ActivityManager.RunningAppProcessInfo process : manager.getRunningAppProcesses()) {
-            if (process.pid == pid) {
-                processName = process.processName;
-            }
-        }
-        return processName;
-    }
-
-    public boolean isMainProcess(Context context) {
-        /**
-         * 是否为主进程
-         */
-        boolean isMainProcess;
-        isMainProcess = context.getApplicationContext().getPackageName().equals
-                (getCurrentProcessName(context));
-        return isMainProcess;
-    }
-}

+ 130 - 0
app/src/main/java/com/ht/gate/PasswordDialog.java

@@ -0,0 +1,130 @@
+package com.ht.gate;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.text.TextUtils;
+import android.view.Gravity;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.TextView;
+
+import androidx.appcompat.app.AppCompatDialog;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+
+public class PasswordDialog extends AppCompatDialog {
+
+    private final int MSG_HIDE_PASSWORD = 1;
+
+    @BindView(R.id.keyboard_view)
+    CustomKeyboardView keyboardView;
+    @BindView(R.id.tv1)
+    TextView tv1;
+    @BindView(R.id.tv2)
+    TextView tv2;
+    @BindView(R.id.tv3)
+    TextView tv3;
+    @BindView(R.id.tv4)
+    TextView tv4;
+
+    private TextView[] textViews;
+    private String password = "";
+    private String passwordStr = "";
+
+    private Handler mHandler = new Handler(msg -> {
+        switch (msg.what) {
+            case MSG_HIDE_PASSWORD:
+                passwordStr = passwordStr.replaceAll(".", "●");
+                updatePasswordTv();
+                break;
+        }
+        return true;
+    });
+
+    public PasswordDialog(Context context) {
+        super(context, R.style.DialogStyle);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.dialog_password);
+        ButterKnife.bind(this);
+        Window window = getWindow();
+        WindowManager.LayoutParams wlp = window.getAttributes();
+        wlp.gravity = Gravity.BOTTOM;
+        window.setAttributes(wlp);
+        window.setWindowAnimations(R.style.DialogAnimation);
+        window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT);
+        View decorView = getWindow().getDecorView();
+        int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+                | View.SYSTEM_UI_FLAG_FULLSCREEN
+                | View.SYSTEM_UI_FLAG_IMMERSIVE;
+        decorView.setSystemUiVisibility(uiOptions);
+
+        textViews = new TextView[]{tv1, tv2, tv3, tv4};
+
+        keyboardView.setKeyboardActionListener(new CustomKeyboardView.OnKeyboardActionListener() {
+            @Override
+            public void onPress(int primaryCode) {
+
+            }
+
+            @Override
+            public void onRelease(int primaryCode) {
+
+            }
+
+            @Override
+            public void onKey(int primaryCode, int[] keyCodes) {
+                switch (primaryCode) {
+                    case CustomKeyboardView.KEYCODE_CANCEL:
+                        dismiss();
+                        break;
+                    case CustomKeyboardView.KEYCODE_DONE:
+                        dismiss();
+                        getContext().startActivity(new Intent(getContext(), WelcomeActivity.class));
+                        break;
+                    case CustomKeyboardView.KEYCODE_DELETE:
+                        if (password.length() > 0) {
+                            password = password.substring(0, password.length() - 1);
+                            passwordStr = password.replaceAll(".", "●");
+                            updatePasswordTv();
+                        }
+                        break;
+                    default:
+                        String str = Character.toString((char) primaryCode);
+                        if (!TextUtils.isEmpty(str) && password.length() < 4) {
+                            str = str.substring(0, 1);
+                            password += str;
+                            passwordStr = password.substring(0, password.length() - 1).replaceAll(".", "●") + str;
+                            updatePasswordTv();
+                        }
+                        mHandler.removeMessages(MSG_HIDE_PASSWORD);
+                        mHandler.sendEmptyMessageDelayed(MSG_HIDE_PASSWORD, 1000);
+                        break;
+                }
+            }
+
+            @Override
+            public void onText(CharSequence text) {
+
+            }
+        });
+    }
+
+    private void updatePasswordTv() {
+        for (int i = 0; i < textViews.length; i++) {
+            if (passwordStr.length() > i) {
+                textViews[i].setText(passwordStr.charAt(i) + "");
+            } else {
+                textViews[i].setText("");
+            }
+        }
+    }
+}

+ 0 - 69
app/src/main/java/com/ht/gate/RemoteService.java

@@ -1,69 +0,0 @@
-package com.ht.gate;
-
-import android.app.Service;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-import android.widget.Toast;
-
-
-
-public class RemoteService extends Service {
-    private static final String TAG = RemoteService.class.getName();
-    private MyBinder mBinder;
-
-    private ServiceConnection connection = new ServiceConnection() {
-        @Override
-        public void onServiceConnected(ComponentName name, IBinder service) {
-            IMyAidlInterface iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
-            try {
-                Log.e(TAG, "connected with " + iMyAidlInterface.getServiceName());
-            } catch (RemoteException e) {
-                e.printStackTrace();
-            }
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName name) {
-            Log.e(TAG, "onServiceDisconnected: 链接断开,重新启动 LocalService");
-            Toast.makeText(RemoteService.this, "链接断开,重新启动 LocalService", Toast.LENGTH_LONG).show();
-            startService(new Intent(RemoteService.this, LocalService.class));
-            bindService(new Intent(RemoteService.this, LocalService.class), connection, Context.BIND_IMPORTANT);
-        }
-    };
-
-    public RemoteService() {
-    }
-
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        Log.e(TAG, "onStartCommand: RemoteService 启动");
-        Toast.makeText(this, "RemoteService 启动", Toast.LENGTH_LONG).show();
-        bindService(new Intent(this, LocalService.class), connection, Context.BIND_IMPORTANT);
-        return START_STICKY;
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        mBinder = new MyBinder();
-        return mBinder;
-    }
-
-    private class MyBinder extends IMyAidlInterface.Stub {
-
-        @Override
-        public String getServiceName() throws RemoteException {
-            return RemoteService.class.getName();
-        }
-
-        @Override
-        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
-
-        }
-    }
-}

+ 34 - 13
app/src/main/java/com/ht/gate/UnlockView.java

@@ -1,5 +1,6 @@
 package com.ht.gate;
 
+import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
@@ -42,6 +43,9 @@ public class UnlockView extends View {
     private DrawFilter drawFilter;
     private Typeface source_han_sans_sc_normal;
     private Typeface source_han_sans_sc_light;
+    private int colorLight = 0xFFFFFFFF;
+    private int colorDark = 0xFF222639;
+    private boolean dark;
 
     private String hint;
 
@@ -70,18 +74,27 @@ public class UnlockView extends View {
 
     public UnlockView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
+
+        TypedArray t = getContext().obtainStyledAttributes(attrs,
+                R.styleable.UnlockView);
+        hint = t.getString(R.styleable.UnlockView_hint);
+        if (TextUtils.isEmpty(hint)) {
+            hint = "滑动解锁";
+        }
+        dark = t.getBoolean(R.styleable.UnlockView_darkMode, false);
+        t.recycle();
+
         source_han_sans_sc_normal = Typeface.createFromAsset(this.getContext().getAssets(), "font/source_han_sans_sc_normal.otf");
         source_han_sans_sc_light = Typeface.createFromAsset(this.getContext().getAssets(), "font/source_han_sans_sc_light.otf");
         borderPaint = new Paint();
         borderPaint.setAntiAlias(true);
-        borderPaint.setColor(Color.WHITE);
         borderWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getContext().getResources().getDisplayMetrics());
         borderPaint.setStrokeWidth(borderWidth);
         borderPaint.setStyle(Paint.Style.STROKE);
         borderPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
         borderPath = new Path();
         padding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 7, getContext().getResources().getDisplayMetrics());
-        bmUnlock = BitmapFactory.decodeResource(getResources(), R.mipmap.icon_unlock);
+        bmUnlock = BitmapFactory.decodeResource(getResources(), dark ? R.mipmap.icon_unlock_dark : R.mipmap.icon_unlock);
         src = new Rect(0, 0, bmUnlock.getWidth(), bmUnlock.getHeight());
         dst = new RectF();
 
@@ -93,18 +106,9 @@ public class UnlockView extends View {
 
         textPaint = new Paint();
         textPaint.setAntiAlias(true);
-        textPaint.setColor(Color.WHITE);
         textPaint.setTextSize(sp2px(25));
         textPaint.setStyle(Paint.Style.FILL);
         textPaint.setTypeface(source_han_sans_sc_light);
-
-        TypedArray t = getContext().obtainStyledAttributes(attrs,
-                R.styleable.UnlockView);
-        hint = t.getString(R.styleable.UnlockView_hint);
-        if (TextUtils.isEmpty(hint)) {
-            hint = "滑动解锁";
-        }
-        t.recycle();
     }
 
     @Override
@@ -112,6 +116,7 @@ public class UnlockView extends View {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
     }
 
+    @SuppressLint("DrawAllocation")
     @Override
     protected void onDraw(Canvas canvas) {
         canvas.setDrawFilter(drawFilter);
@@ -119,6 +124,13 @@ public class UnlockView extends View {
         float height = getHeight();
         float d = (height - borderWidth);
         float r = d / 2;
+        if (dark) {
+            borderPaint.setColor(colorDark);
+            textPaint.setColor(colorDark);
+        } else {
+            borderPaint.setColor(colorLight);
+            textPaint.setColor(colorDark);
+        }
         borderPath.reset();
         borderPath.moveTo(r + borderWidth / 2, borderWidth / 2);
         borderPath.lineTo(width - r, borderWidth / 2);
@@ -131,8 +143,17 @@ public class UnlockView extends View {
         int dd = (int) Math.max(0, Math.min(distance, getWidth() - padding * 2 - size));
 
         linePaint.setStrokeWidth(height - padding * 2);
-        lineShader = new LinearGradient(0, 0, width, 0,
-                new int[]{Color.argb(0, 255, 255, 255), Color.argb(30, 255, 255, 255), Color.argb(117, 255, 255, 255), Color.argb(255, 255, 255, 255)},
+        lineShader = dark ? new LinearGradient(0, 0, width, 0,
+                new int[]{0x00222639,
+                        0x1F222639,
+                        0x78222639,
+                        0xD4222639},
+                new float[]{0, 0.19f, 0.42f, 1}, Shader.TileMode.CLAMP)
+                : new LinearGradient(0, 0, width, 0,
+                new int[]{Color.argb(0, 255, 255, 255),
+                        Color.argb(30, 255, 255, 255),
+                        Color.argb(117, 255, 255, 255),
+                        Color.argb(255, 255, 255, 255)},
                 new float[]{0, 0.19f, 0.42f, 1}, Shader.TileMode.CLAMP);
         linePaint.setShader(lineShader);
         canvas.drawLine(r, height / 2, r + dd, height / 2, linePaint);

+ 66 - 0
app/src/main/java/com/ht/gate/VideoBackground.java

@@ -0,0 +1,66 @@
+package com.ht.gate;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.drawable.BitmapDrawable;
+import android.media.MediaMetadataRetriever;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.widget.VideoView;
+
+import java.util.HashMap;
+
+public class VideoBackground extends VideoView {
+    public VideoBackground(Context context) {
+        this(context, null);
+    }
+
+    public VideoBackground(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public VideoBackground(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        Uri videoUri = Uri.parse("android.resource://" + getContext().getPackageName() + "/" + R.raw.video_background);
+
+        setBackground(new BitmapDrawable(getResources(), BitmapFactory.decodeResource(getResources(), R.raw.video_placeholder)));
+
+        setVideoURI(videoUri);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        //我们重新计算高度
+        int width = getDefaultSize(0, widthMeasureSpec);
+        int height = getDefaultSize(0, heightMeasureSpec);
+        setMeasuredDimension(width, height);
+    }
+
+    @Override
+    public void setOnPreparedListener(MediaPlayer.OnPreparedListener l) {
+        super.setOnPreparedListener(l);
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        return super.onKeyDown(keyCode, event);
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        setOnPreparedListener(mp -> {
+            mp.start();
+            mp.setLooping(true);
+            mp.setOnInfoListener((mp1, what, extra) -> {
+                if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START)
+                    setBackgroundColor(Color.TRANSPARENT);
+                return true;
+            });
+        });
+    }
+}

+ 14 - 0
app/src/main/java/com/ht/gate/WelcomeActivity.java

@@ -0,0 +1,14 @@
+package com.ht.gate;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import android.os.Bundle;
+
+public class WelcomeActivity extends AppCompatActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_welcome);
+    }
+}

+ 13 - 0
app/src/main/java/com/ht/gate/activity/MainActivity.java

@@ -5,14 +5,27 @@ import androidx.appcompat.app.AppCompatActivity;
 import android.os.Bundle;
 import android.view.View;
 
+import com.ht.gate.PasswordDialog;
 import com.ht.gate.R;
+import com.ht.gate.UnlockView;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
 
 public class MainActivity extends AppCompatActivity {
 
+    @BindView(R.id.unlock_view)
+    UnlockView unlockView;
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
+        ButterKnife.bind(this);
+        unlockView.setUnlockListener(() -> {
+            PasswordDialog passwordDialog = new PasswordDialog(MainActivity.this);
+            passwordDialog.show();
+        });
     }
 
     @Override

+ 5 - 0
app/src/main/res/anim/decelerate_interpolator.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<decelerateInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:factor="1.5">
+
+</decelerateInterpolator>

+ 11 - 0
app/src/main/res/anim/dialog_enter.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:interpolator="@anim/decelerate_interpolator">
+
+    <translate
+        android:duration="200"
+        android:fromYDelta="100%" />
+    <alpha
+        android:fromAlpha="0"
+        android:toAlpha="1" />
+</set>

+ 12 - 0
app/src/main/res/anim/dialog_exit.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:interpolator="@anim/decelerate_interpolator">
+
+    <translate
+        android:duration="200"
+        android:toYDelta="100%" />
+
+    <alpha
+        android:duration="200"
+        android:toAlpha="0" />
+</set>

+ 7 - 0
app/src/main/res/drawable/bg_welcome.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#222639" />
+    <corners
+        android:topLeftRadius="36dp"
+        android:topRightRadius="36dp" />
+</shape>

+ 17 - 1
app/src/main/res/layout/activity_login.xml

@@ -8,6 +8,22 @@
     android:keepScreenOn="true"
     tools:context=".LoginActivity">
 
+    <com.ht.gate.VideoBackground
+        android:id="@+id/video_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+
+    <ImageButton
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="18dp"
+        android:layout_marginRight="18dp"
+        android:background="@android:color/transparent"
+        android:padding="0dp"
+        android:src="@mipmap/icon_setting"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
     <ImageView
         android:id="@+id/iv_logo"
         android:layout_width="162dp"
@@ -58,7 +74,7 @@
         app:layout_constraintRight_toRightOf="parent"
         app:layout_constraintTop_toTopOf="parent" />
 
-    <com.ht.gate.view.CustomKeyboardView
+    <com.ht.gate.CustomKeyboardView
         android:id="@+id/keyboard_view"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"

+ 5 - 0
app/src/main/res/layout/activity_main.xml

@@ -6,6 +6,10 @@
     android:layout_height="match_parent"
     tools:context=".activity.MainActivity">
 
+    <com.ht.gate.VideoBackground
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+
     <ImageButton
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
@@ -56,6 +60,7 @@
         app:layout_constraintTop_toBottomOf="@id/tv1" />
 
     <com.ht.gate.UnlockView
+        android:id="@+id/unlock_view"
         android:layout_width="338dp"
         android:layout_height="71dp"
         android:layout_marginTop="41dp"

+ 201 - 0
app/src/main/res/layout/activity_welcome.xml

@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.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:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".WelcomeActivity">
+
+    <com.ht.gate.VideoBackground
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="260dp"
+        android:background="@android:color/white"
+        android:orientation="vertical"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent">
+
+        <TextView
+            android:id="@+id/tv1"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="68dp"
+            android:fontFamily="@font/fzqkbysjw"
+            android:text="财富管理室"
+            android:textColor="#222639"
+            android:textSize="32sp"
+            app:layout_constraintHorizontal_chainStyle="packed"
+            app:layout_constraintLeft_toLeftOf="parent"
+            app:layout_constraintRight_toLeftOf="@id/tv_room_name"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <TextView
+            android:id="@+id/tv_room_name"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="12dp"
+            android:fontFamily="@font/fzqkbysjw"
+            android:text="A101"
+            android:textColor="#222639"
+            android:textSize="80sp"
+            app:layout_constraintBaseline_toBaselineOf="@id/tv1"
+            app:layout_constraintHorizontal_chainStyle="packed"
+            app:layout_constraintLeft_toRightOf="@id/tv1"
+            app:layout_constraintRight_toRightOf="parent" />
+
+        <com.ht.gate.UnlockView
+            android:layout_width="338dp"
+            android:layout_height="71dp"
+            android:layout_marginTop="129dp"
+            app:darkMode="true"
+            app:layout_constraintLeft_toLeftOf="parent"
+            app:layout_constraintRight_toRightOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <ImageButton
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="18dp"
+        android:layout_marginRight="18dp"
+        android:background="@android:color/transparent"
+        android:padding="0dp"
+        android:src="@mipmap/icon_setting_dark"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:layout_marginTop="223dp"
+        android:background="@drawable/bg_welcome"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent">
+
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="44dp"
+            android:layout_marginTop="73dp"
+            android:orientation="vertical"
+            app:layout_constraintLeft_toLeftOf="parent"
+            app:layout_constraintTop_toTopOf="parent">
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:fontFamily="@font/fzqkbysjw"
+                android:text="欢迎,黄先生"
+                android:textColor="#E4BF85"
+                android:textSize="64sp" />
+
+            <TextView
+                android:id="@+id/tv3"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="18dp"
+                android:fontFamily="@font/fzqkbysjw"
+                android:text="财富管理专属服务"
+                android:textColor="#E4BF85"
+                android:textSize="38sp" />
+
+            <View
+                android:layout_width="44dp"
+                android:layout_height="2dp"
+                android:layout_marginTop="35dp"
+                android:background="#E4BF85" />
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="12sp"
+                android:fontFamily="@font/source_han_sans_sc_light"
+                android:text="您的专属投顾"
+                android:textColor="@android:color/white"
+                android:textSize="21sp" />
+
+            <androidx.constraintlayout.widget.ConstraintLayout
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content">
+
+                <TextView
+                    android:id="@+id/tv_adviser_name"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:fontFamily="@font/source_han_sans_sc_medium"
+                    android:text="黄展涛"
+                    android:textColor="@android:color/white"
+                    android:textSize="39sp"
+                    app:layout_constraintLeft_toLeftOf="parent"
+                    app:layout_constraintTop_toTopOf="parent" />
+
+                <TextView
+                    android:id="@+id/tv_rate"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="4dp"
+                    android:fontFamily="@font/source_han_sans_sc_light"
+                    android:text="4.9分"
+                    android:textColor="@android:color/white"
+                    android:textSize="24sp"
+                    app:layout_constraintBaseline_toBaselineOf="@id/tv_adviser_name"
+                    app:layout_constraintLeft_toRightOf="@id/tv_adviser_name" />
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:fontFamily="@font/source_han_sans_sc_light"
+                    android:text="/5分"
+                    android:textColor="#90ffffff"
+                    android:textSize="12sp"
+                    app:layout_constraintBaseline_toBaselineOf="@id/tv_rate"
+                    app:layout_constraintLeft_toRightOf="@id/tv_rate" />
+            </androidx.constraintlayout.widget.ConstraintLayout>
+
+            <TextView
+                android:layout_width="192dp"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="11dp"
+                android:fontFamily="@font/source_han_sans_sc_light"
+                android:text="20年从业经验,经历多次牛能转换磨练,对市场具有一定的敏感度,注重价值投资,资产配置,秉承专业的投资理念服务客户"
+                android:textColor="#80ffffff"
+                android:textSize="12sp" />
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="21dp"
+                android:text="执业证书编号:S0570116120025"
+                android:textColor="#80ffffff"
+                android:textSize="12sp" />
+
+            <RelativeLayout
+                android:layout_width="72dp"
+                android:layout_height="72dp"
+                android:layout_marginTop="36dp">
+
+                <ImageView
+                    android:layout_width="72dp"
+                    android:layout_height="72dp"
+                    android:src="@mipmap/icon_award" />
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_centerHorizontal="true"
+                    android:layout_marginTop="14dp"
+                    android:fontFamily="@font/source_han_sans_sc_medium"
+                    android:text="20年"
+                    android:textColor="#ffe4bf85"
+                    android:textSize="15sp" />
+            </RelativeLayout>
+        </LinearLayout>
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 65 - 0
app/src/main/res/layout/dialog_password.xml

@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="#23283C"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="138dp"
+        android:gravity="center">
+
+        <TextView
+            android:id="@+id/tv1"
+            android:layout_width="71dp"
+            android:layout_height="71dp"
+            android:layout_marginLeft="11dp"
+            android:layout_marginRight="11dp"
+            android:background="@drawable/bg_edit"
+            android:gravity="center"
+            android:textColor="@android:color/black"
+            android:textSize="37sp" />
+
+        <TextView
+            android:id="@+id/tv2"
+            android:layout_width="71dp"
+            android:layout_height="71dp"
+            android:layout_marginLeft="11dp"
+            android:layout_marginRight="11dp"
+            android:background="@drawable/bg_edit"
+            android:gravity="center"
+            android:textColor="@android:color/black"
+            android:textSize="37sp" />
+
+        <TextView
+            android:id="@+id/tv3"
+            android:layout_width="71dp"
+            android:layout_height="71dp"
+            android:layout_marginLeft="11dp"
+            android:layout_marginRight="11dp"
+            android:background="@drawable/bg_edit"
+            android:gravity="center"
+            android:textColor="@android:color/black"
+            android:textSize="37sp" />
+
+        <TextView
+            android:id="@+id/tv4"
+            android:layout_width="71dp"
+            android:layout_height="71dp"
+            android:layout_marginLeft="11dp"
+            android:layout_marginRight="11dp"
+            android:background="@drawable/bg_edit"
+            android:gravity="center"
+            android:textColor="@android:color/black"
+            android:textSize="37sp" />
+    </LinearLayout>
+
+    <com.ht.gate.CustomKeyboardView
+        android:id="@+id/keyboard_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:legend="请输入密码"
+        app:type="number" />
+</LinearLayout>

BIN
app/src/main/res/raw/video_background.mp4


BIN
app/src/main/res/raw/video_placeholder.png


+ 5 - 0
app/src/main/res/values/attr.xml

@@ -1,10 +1,15 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
     <declare-styleable name="CustomKeyboardView">
+        <attr name="type" format="enum">
+            <enum name="text" value="0" />
+            <enum name="number" value="1" />
+        </attr>
         <attr name="legend" format="string" />
     </declare-styleable>
 
     <declare-styleable name="UnlockView">
         <attr name="hint" format="string" />
+        <attr name="darkMode" format="boolean"/>
     </declare-styleable>
 </resources>

+ 13 - 0
app/src/main/res/values/styles.xml

@@ -11,4 +11,17 @@
 <!--        <item name="android:fontFamily">@font/source_han_sans_sc_normal</item>-->
     </style>
 
+    <style name="DialogStyle" parent="Theme.AppCompat.Dialog">
+        <item name="android:windowFrame">@null</item>
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:background">@android:color/transparent</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:windowIsFloating">true</item>
+        <item name="android:windowIsTranslucent">true</item>
+    </style>
+
+    <style name="DialogAnimation" parent="Animation.AppCompat.Dialog">
+        <item name="android:windowEnterAnimation">@anim/dialog_enter</item>
+        <item name="android:windowExitAnimation">@anim/dialog_exit</item>
+    </style>
 </resources>

+ 1 - 1
app/src/main/res/xml/custom_keyboard.xml

@@ -92,7 +92,7 @@
 
     <Row>
         <Key
-            android:codes="65"
+            android:codes="45"
             android:keyWidth="8.25%p"
             android:keyLabel="-" />
         <Key

+ 64 - 0
app/src/main/res/xml/custom_keyboard_number.xml

@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
+    android:horizontalGap="1.590909%p"
+    android:keyWidth="31.212121%p"
+    android:keyHeight="7.5%p"
+    android:verticalGap="1.3125%p">
+    <Row>
+        <Key
+            android:codes="49"
+            android:keyWidth="31.212121%p"
+            android:keyLabel="1" />
+        <Key
+            android:codes="50"
+            android:keyWidth="31.212121%p"
+            android:keyLabel="2" />
+        <Key
+            android:codes="51"
+            android:keyWidth="31.212121%p"
+            android:keyLabel="3" />
+    </Row>
+    <Row>
+        <Key
+            android:codes="52"
+            android:keyWidth="31.212121%p"
+            android:keyLabel="4" />
+        <Key
+            android:codes="53"
+            android:keyWidth="31.212121%p"
+            android:keyLabel="5" />
+        <Key
+            android:codes="54"
+            android:keyWidth="31.212121%p"
+            android:keyLabel="6" />
+    </Row>
+    <Row>
+        <Key
+            android:codes="55"
+            android:keyWidth="31.212121%p"
+            android:keyLabel="7" />
+        <Key
+            android:codes="56"
+            android:keyWidth="31.212121%p"
+            android:keyLabel="8" />
+        <Key
+            android:codes="57"
+            android:keyWidth="31.212121%p"
+            android:keyLabel="9" />
+    </Row>
+    <Row>
+        <Key
+            android:codes="-1"
+            android:keyWidth="31.212121%p"
+            android:keyLabel="" />
+        <Key
+            android:codes="48"
+            android:keyWidth="31.212121%p"
+            android:keyLabel="0" />
+        <Key
+            android:codes="-5"
+            android:isRepeatable="true"
+            android:keyWidth="31.212121%p"
+            android:keyLabel="del" />
+    </Row>
+</Keyboard>