美文网首页程序员
安卓支付键盘三种方式优劣

安卓支付键盘三种方式优劣

作者: Master_文 | 来源:发表于2017-12-22 19:09 被阅读0次
    苍老师带你们过圣诞

    闲来无聊研究了下微信支付键盘,大致有三种实现方式

    第一种

    • 自定义view实现,主要用到onDraw和onTouchEvent这两个,这种实现起来是真的烦,很少有人用这种方式,不推荐(大屌除外)

    @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            int width = getWidth();
            int height = getHeight();
            mCanvas = canvas;
            Log.d(TAG, "onDraw: width=" + width + "\theight=" + height);
            // 画竖线
            mPaint.setColor(Color.BLACK);
            mAvgWidth = width / WIDTH_LINES;
            for (int i = 1; i < WIDTH_LINES; i++) {
                canvas.drawLine(mAvgWidth * i, 0, mAvgWidth * i, height, mPaint);
            }
            // 画横线
            mAvgHeight = height / HEIGHT_LINES;
            for (int i = 0; i < HEIGHT_LINES; i++) {
                canvas.drawLine(0, mAvgHeight * i, width, mAvgHeight * i, mPaint);
            }
            // 画数字
            mPaint.setTextSize(40);
            Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt();
            // 画1-3
            drawNum(1, 1, "1", fontMetrics);
            drawNum(1, 2, "2", fontMetrics);
            drawNum(1, 3, "3", fontMetrics);
            // 画4-6
            drawNum(2, 1, "4", fontMetrics);
            drawNum(2, 2, "5", fontMetrics);
            drawNum(2, 3, "6", fontMetrics);
            // 画7-9
            drawNum(3, 1, "7", fontMetrics);
            drawNum(3, 2, "8", fontMetrics);
            drawNum(3, 3, "9", fontMetrics);
            // 画底部
            drawNum(4, 2, "0", fontMetrics);
            mPaint.setColor(Color.GRAY);
            //        canvas.drawRect(0, mAvgHeight * 3, mAvgWidth, mAvgHeight * 4, mPaint);
            //        canvas.drawRect(mAvgWidth * 2, mAvgHeight * 3, mAvgWidth * 3, mAvgHeight * 4, mPaint);
    //        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.back);
    //        int bWidth = bitmap.getWidth();
    //        int bHeight = bitmap.getHeight();
    //        canvas.drawBitmap(bitmap, (float) (mAvgWidth * 2.5 - bWidth / 2), (float) (mAvgHeight * 3.5 - bHeight / 2), mPaint);
        }
    
     @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    mStartX = event.getX();
                    mStartY = event.getY();
                    if (mStartX <= mAvgWidth) {
                        if (mStartY <= mAvgHeight) {
                            Log.d(TAG, "onTouchEvent: " + "1");
                        } else if (mStartY > mAvgHeight && mStartY <= mAvgHeight * 2) {
                            Log.d(TAG, "onTouchEvent: " + "4");
                        } else if (mStartY > mAvgHeight * 2 && mStartY <= mAvgHeight * 3) {
                            Log.d(TAG, "onTouchEvent: " + "7");
                        } else {
                            Log.d(TAG, "onTouchEvent: " + " ");
                        }
                    } else if (mStartX > mAvgWidth && mStartX <= mAvgWidth * 2) {
                        if (mStartY <= mAvgHeight) {
                            Log.d(TAG, "onTouchEvent: " + "2");
                        } else if (mStartY > mAvgHeight && mStartY <= mAvgHeight * 2) {
                            Log.d(TAG, "onTouchEvent: " + "5");
                        } else if (mStartY > mAvgHeight * 2 && mStartY <= mAvgHeight * 3) {
                            Log.d(TAG, "onTouchEvent: " + "8");
                        } else {
                            Log.d(TAG, "onTouchEvent: " + "0");
                        }
                    } else {
                        if (mStartY <= mAvgHeight) {
                            Log.d(TAG, "onTouchEvent: " + "3");
                        } else if (mStartY > mAvgHeight && mStartY <= mAvgHeight * 2) {
                            Log.d(TAG, "onTouchEvent: " + "6");
                        } else if (mStartY > mAvgHeight * 2 && mStartY <= mAvgHeight * 3) {
                            Log.d(TAG, "onTouchEvent: " + "9");
                        } else {
                            Log.d(TAG, "onTouchEvent: " + "删除");
                        }
                    }
                    //                invalidate();
                    break;
                case MotionEvent.ACTION_MOVE:
                    break;
                case MotionEvent.ACTION_UP:
                    mStartX = 0;
                    mStartY = 0;
                    //                invalidate();
                    break;
            }
            return true;
        }
    

    第二种

    • 用keyboard和keyboardview实现,这种的缺陷是,你按住4,然后移动到1或者7,他显示的是1或者7,很显然不符合微信这种,微信是移动到1或7的时候直接取消当前这个,不推荐(你个渣渣,肯定没找到相应的API)

    1. 在res下面创建xml包


    2. 创建keyboard.xml文件
    <?xml version="1.0" encoding="utf-8"?>
    <Keyboard
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:horizontalGap="1dp"
        android:keyHeight="8%p"
        android:keyWidth="33.3333%p"
        android:verticalGap="1dp">
    
        <Row>
            <Key
                android:keyLabel="1"/>
            <Key
                android:keyLabel="2"/>
            <Key
                android:keyLabel="3"/>
        </Row>
    
        <Row>
            <Key
                android:keyLabel="4"/>
            <Key
                android:keyLabel="5"/>
            <Key
                android:keyLabel="6"/>
        </Row>
    
        <Row>
            <Key
                android:keyLabel="7"/>
            <Key
                android:keyLabel="8"/>
            <Key
                android:keyLabel="9"/>
        </Row>
    
        <Row>
            <Key
                android:codes="-10"
                android:keyLabel=""
                />
            <Key
                android:keyLabel="0"/>
            <Key
                android:codes="-5"
                android:isRepeatable="true"/>
        </Row>
    </Keyboard>
    
    1. 自定义view继承KeyboardView
    • 绘制空格键和删除键
     @Override
        public void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            List<Keyboard.Key> keys = getKeyboard().getKeys();
            for (Keyboard.Key key : keys) {
                //绘制空白键
                if (key.codes[0] == KEYCODE_EMPTY) {
                    drawKeyBackGround(key, canvas);
                } else if (key.codes[0] == Keyboard.KEYCODE_DELETE) {
                    //绘制删除键背景
                    drawKeyBackGround(key, canvas);
                    //                //绘制按键图片
                    drawkeyDelete(key, canvas);
                }
            }
            mCanvas = canvas;
        }
    
        private void drawKeyBackGround(Keyboard.Key key, Canvas canvas) {
            Drawable drawable = mContext.getResources().getDrawable(R.drawable.keyboard_empty);
            // 选择器效果
            int[] state = key.getCurrentDrawableState();
            drawable.setState(state);
            // TODO: 2017/12/21 减去key的间距,很难控制,而且有按键问题
            //        drawable.setBounds(key.x, key.y, key.x + key.width, key.y + key.height);
            drawable.setBounds(key.x, key.y + mSpace, key.x + key.width, key.y + key.height + mSpace);
            drawable.draw(canvas);
        }
    
        private void drawkeyDelete(Keyboard.Key key, Canvas canvas) {
            DisplayMetrics dm = getResources().getDisplayMetrics();
            int width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, dm);
            int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 11, dm);
            int[] state = key.getCurrentDrawableState();
            mDeleteDrawable.setState(state);
            mDeleteDrawable.setBounds(key.x + width, key.y + height, key.x + key.width - width, key.y + key.height - height);
            mDeleteDrawable.draw(canvas);
        }
    
    • key的回调
    @Override
        public void onKey(int primaryCode, int[] keyCodes) {
            Log.d(TAG, "onKey: " + primaryCode);
            if (primaryCode == Keyboard.KEYCODE_DELETE && mOnkeyPressListener != null) {
                if (mOnkeyPressListener != null) {
                    mOnkeyPressListener.onDeleteKey();
                }
            } else if (primaryCode != KEYCODE_EMPTY) {
                if (mOnkeyPressListener != null) {
                    Log.d(TAG, "数字: " + Character.toString((char) primaryCode));
                    mOnkeyPressListener.onInertKey(Character.toString((char) primaryCode));
                }
            }
        }
    
    1. xml中布局
      <cn.gongwebo.payview.widget.KeyView
            android:id="@+id/keyview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:keyBackground="@drawable/keyboard_num"
            android:keyTextColor="@android:color/black"
            android:shadowColor="@color/white"
            android:shadowRadius="0.0"
            app:keyView_delete="@drawable/keyboard_delete"/>
    

    需要注意的如果没有在KeyView设置以下两行代码,会导致字体模糊

    第三种

    • 用ViewGroup添加,我认为是三种里面最符合微信的,推荐

    1. item的布局
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/rl"
        android:layout_width="match_parent"
        android:layout_height="60dp">
    
        <TextView
            android:id="@+id/tv"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_centerInParent="true"
            android:gravity="center"
            android:textColor="@color/black"
            android:textSize="18sp"
            tools:text="1"/>
    
        <!--头部的黑边-->
        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="@color/black"/>
    
        <!--右边的黑边-->
        <View
            android:id="@+id/view_right"
            android:layout_width="1dp"
            android:layout_height="match_parent"
            android:layout_alignParentRight="true"
            android:background="@color/black"/>
    
        <ImageView
            android:id="@+id/iv_delete"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_centerInParent="true"
            android:visibility="gone"
            tools:src="@drawable/delete_normal"/>
    </RelativeLayout>
    
    1. 对item的操作
      @Override
        public void onBindViewHolder(KeyBoardViewHolder holder, int position) {
            final Integer code = mList.get(position);
            // 数字
            TextView tv = holder.tv;
            // 点击
            View view = holder.view;
            // 删除
            ImageView iv_delete = holder.iv_delete;
            iv_delete.setVisibility(code == DELETE ? View.VISIBLE : View.GONE);
            if (code == EMPTY) {
                view.setBackgroundResource(R.drawable.keyboard_empty);
            } else if (code == DELETE) {
                view.setBackgroundResource(R.drawable.keyboard_empty);
                iv_delete.setBackgroundResource(R.drawable.keyboard_delete);
            } else {
                view.setBackgroundResource(R.drawable.keyboard_num);
                tv.setText(mList.get(position) + "");
            }
            // 最右边的不显示
            if (holder.getPosition() % 3 == 2) {
                holder.view_right.setVisibility(View.GONE);
            }
            view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mKeyBoardAdapterListener != null) {
                        mKeyBoardAdapterListener.click(code);
                    }
                }
            });
        }
    
    1. 动画效果
    @OnClick({R.id.iv_close, R.id.fl_close, R.id.payview})
        public void onViewClicked(View view) {
            switch (view.getId()) {
                case R.id.iv_close:
                    dismiss();
                    break;
                case R.id.fl_close:
                    if (!keyHide) {
                        Animation exit = AnimationUtils.loadAnimation(getActivity(), R.anim.exit_anim);
                        mLlKey.setAnimation(exit);
                        mLlKey.startAnimation(exit);
                        exit.setFillAfter(true);
                        keyHide = true;
                        // 影藏的时候要等动画执行完
                        exit.setAnimationListener(new Animation.AnimationListener() {
                            @Override
                            public void onAnimationStart(Animation animation) {
    
                            }
    
                            @Override
                            public void onAnimationEnd(Animation animation) {
                                // 因为是补间动画所以把控件隐藏
                                mRv.setVisibility(View.GONE);
                                mFlClose.setVisibility(View.GONE);
                            }
    
                            @Override
                            public void onAnimationRepeat(Animation animation) {
    
                            }
                        });
                    }
                    break;
                case R.id.payview:
                    if (keyHide) {
                        Animation enter = AnimationUtils.loadAnimation(getActivity(), R.anim.enter_anim);
                        mLlKey.setAnimation(enter);
                        mLlKey.startAnimation(enter);
                        enter.setFillAfter(true);
                        keyHide = false;
                        // 因为是补间动画所以把控件显示
                        mRv.setVisibility(View.VISIBLE);
                        mFlClose.setVisibility(View.VISIBLE);
                    }
                    break;
            }
        }
    

    传送门https://gitee.com/gongwenbo/payKeyboard.git

    结尾:自己感觉有很多不足的地方,望大伙多多指点

    我都看你怎么久了,不发言好意思吗!!!

    相关文章

      网友评论

        本文标题:安卓支付键盘三种方式优劣

        本文链接:https://www.haomeiwen.com/subject/sugowxtx.html