Android 中自定义软键盘,跳槽大厂必看

}

g.drawBitmap(keyTwo_, BORDER_TWO + (qwertyW_ + colW_one)

  • i, BORDER_CENTER + BORDER_TOP + qwertyH_, paint_);

if (!isABC_) {

g.drawText(String.valueOf(keyAbc_[resultAbc[10 + i]]),

startX1, startY + BORDER_CENTER + qwertyH_,

textPaint_);

} else {

g.drawText(String.valueOf(keyAbc_[resultAbc[10 + i]])

.toUpperCase(), startX1, startY + BORDER_CENTER

  • qwertyH_, textPaint_);

}

}

/*

  • 画字母键的第三行

*/

int startX2 = 0;

String temp2;

for (int i = 0; i <= 6; i++) {

if (!isABC_) {

temp2 = String.valueOf(keyAbc_[resultAbc[19 + i]]);

} else {

temp2 = String.valueOf(keyAbc_[resultAbc[19 + i]])

.toUpperCase();

}

startX2 = getIntX(BORDER + qwertyW_ - qwertyW_ / 4, temp2)

  • (colW_one + qwertyW_) * i;

if (column3 >= 0) {

if (i == column3) {

keyThree_ = keyBoard_one_down;

} else {

keyThree_ = keyBoard_one;

}

} else {

keyThree_ = keyBoard_one;

}

g.drawBitmap(keyThree_, BORDER + qwertyW_ - qwertyW_ / 4

  • (qwertyW_ + colW_one) * i, BORDER_TOP + 2
  • BORDER_CENTER + 2 * qwertyH_, paint_);

if (!isABC_) {

g.drawText(String.valueOf(keyAbc_[resultAbc[19 + i]]),

startX2, startY + 2

  • (BORDER_CENTER + qwertyH_),

textPaint_);

} else {

g.drawText(String.valueOf(keyAbc_[resultAbc[19 + i]])

.toUpperCase(), startX2, startY + 2

  • (BORDER_CENTER + qwertyH_), textPaint_);

}

}

/*

  • 画字母键盘功能键的切换大小写

*/

// if (!isABC_) {

// g.drawBitmap(keyBoard_shift_normal, BORDER, BORDER_TOP + 2

// * BORDER_CENTER + 2 * qwertyH_, paint_);

// } else {

// g.drawBitmap(keyBoard_shift_down, BORDER, BORDER_TOP + 2

// * BORDER_CENTER + 2 * qwertyH_, paint_);

// }

/*

  • 画字母键盘功能键的切换大小写

*/

if (!isABC_) {

g.drawBitmap(keyBoard_shift_normal, BORDER + qwertyW_

  • qwertyW_ / 4 + (qwertyW_ + colW_one) * 7,

BORDER_TOP + 2 * BORDER_CENTER + 2 * qwertyH_,

paint_);

} else {

g.drawBitmap(keyBoard_shift_down, BORDER + qwertyW_

  • qwertyW_ / 4 + (qwertyW_ + colW_one) * 7,

BORDER_TOP + 2 * BORDER_CENTER + 2 * qwertyH_,

paint_);

}

/*

  • 画功能键的切换数字键

*/

g.drawBitmap(keyBoard_gray_enter, BORDER, BORDER_TOP

  • (BORDER_CENTER + qwertyH_) * 3, paint_);

// textPaint_.setColor(Color.WHITE);

g.drawText(

“123”,

BORDER

  • (keyBoard_gray_enter.getWidth() - textPaint_

.measureText(“123”)) / 2,

(qwertyH_ + BORDER_CENTER) * 3 + BORDER_TOP

  • keyBoard_gray_enter.getHeight() / 2

  • LPUtils.getScaledValue(8), textPaint_);

/*

  • 画logo

*/

g.drawBitmap(keyBoard_jsbank,

(width_ - keyBoard_jsbank.getWidth()) >> 1, BORDER_TOP

  • 3 * BORDER_CENTER + 3 * qwertyH_, paint_);

g.drawBitmap(

keyBoard_jsbank_logo,

(width_ - keyBoard_jsbank_logo.getWidth()) >> 1,

BORDER_TOP + 3 * BORDER_CENTER + 3 * qwertyH_

  • LPUtils.getScaledValue(4), paint_);

// g.drawText(“江苏银行”, (width_ + keyBoard_jsbank_logo.getWidth()

// - textPaint_.measureText(“江苏银行”)) / 2,

// (qwertyH_ + BORDER_CENTER) * 3 + BORDER_TOP +

// keyBoard_gray_enter.getHeight() / 2 +

// LPUtils.getScaledValue(5),

// textPaint_);

/*

  • 画功能键的删除键

*/

textPaint_.setTextSize(PAINT_SIZE);

if (isDel_) {

g.drawBitmap(keyBoard_del_down,

width_ - keyBoard_del_down.getWidth() - BORDER,

BORDER_TOP + 3 * BORDER_CENTER + 3 * qwertyH_,

paint_);

delEditAgainValue();

} else {

g.drawBitmap(keyBoard_gray_del,

width_ - keyBoard_gray_del.getWidth() - BORDER,

BORDER_TOP + 3 * BORDER_CENTER + 3 * qwertyH_,

paint_);

}

// textPaint_.setColor(Color.WHITE);

// g.drawText(“确定”, width_

// - BORDER

// - keyBoard_gray_enter.getWidth()

// + (keyBoard_gray_enter.getWidth() - textPaint_

// .measureText(“确定”)) / 2, BORDER_TOP + 3

// * BORDER_CENTER + 3 * qwertyH_ + LPUtils.getScaledValue(25),

// textPaint_);

}

}

@Override

public boolean onTouchEvent(MotionEvent event) {

// TODO Auto-generated method stub

// 按下去的横坐标

int x = (int) event.getX();

// 按下去的纵坐标

int y = (int) event.getY();

int rowFirst = BORDER_TOP + qwertyH_;

int rowSecond = rowFirst + BORDER_CENTER + qwertyH_;

int rowThird = rowSecond + BORDER_CENTER + qwertyH_;

int rowFourth = rowThird + BORDER_CENTER + qwertyH_;

// 触摸的方式

int toucheEvent = event.getAction();

switch (toucheEvent) {

case MotionEvent.ACTION_DOWN:

String isWhat_ = null;

String isOut_ = null;

keyDownTime = System.currentTimeMillis();

if (isNum_) {

y = y - BORDER_TOP;

if (y >= 0 && y <= (numH_ + BORDER_NUMBER_CENTER) * 4) {

key_row = y / (numH_ + BORDER_NUMBER_CENTER);

key_column = x / (numW_ + BORDER_NUMBER_CENTER);

}

} else {

if (y > BORDER_TOP && y <= rowFirst) {

// 第一行

if (x > BORDER && x < width_) {

column1 = x / (qwertyW_ + colW_one);

if (isABC_) {

// 大写字母

isWhat_ = String.valueOf(

keyAbc_[resultAbc[column1]])

.toUpperCase();

} else {

// 小写字母

isWhat_ = String

.valueOf(keyAbc_[resultAbc[column1]]);

}

if (column1 == 0) {

isOut_ = “left”;

} else if (column1 == 9) {

isOut_ = “right”;

}

// showPopWindow(BORDER + (column1) * (qwertyW_

// + colW_one) - (column1 == 0 ? qwertyW_ :

// windownShow_W),

// BORDER_TOP + qwertyH_ / 2, isWhat_,isOut_);

}

} else if (y > (rowFirst + BORDER_CENTER)

&& y < rowSecond) {

// 第二行

if (x > BORDER_TWO && x < (width_ - BORDER_TWO)) {

column2 = (x - BORDER_TWO)

/ (qwertyW_ + colW_one);

if (isABC_) {

isWhat_ = String.valueOf(

keyAbc_[resultAbc[10

  • (x - BORDER_TWO)

/ (qwertyW_ + colW_one)]])

.toUpperCase();

} else {

isWhat_ = String

.valueOf(keyAbc_[resultAbc[10

  • (x - BORDER_TWO)

/ (qwertyW_ + colW_one)]]);

}

// showPopWindow(BORDER_TWO + (column2) *

// (qwertyW_ + colW_one) - windownShow_W,

// BORDER_TOP + BORDER_CENTER + qwertyH_

// + qwertyH_ / 2, isWhat_,isOut_);

}

} else if (y > (rowSecond + BORDER_CENTER)

&& y < rowThird) {

// 第三行

if (x > (BORDER + qwertyW_ - qwertyW_ / 4 + (qwertyW_ + colW_one) * 7)

&& x < (BORDER + qwertyW_ - qwertyW_ / 4

  • (qwertyW_ + colW_one) * 7 + keyBoard_shift_normal

.getWidth())) {

isABC_ = !isABC_;

} else if (x > (BORDER + qwertyW_ - qwertyW_ / 4)

&& x < (BORDER + qwertyW_ - qwertyW_ / 4 + (qwertyW_ + colW_one) * 7)) {

column3 = (x - (BORDER + qwertyW_ - qwertyW_ / 4))

/ (qwertyW_ + colW_one);

if (isABC_) {

isWhat_ = String.valueOf(

keyAbc_[resultAbc[19 + column3]])

.toUpperCase();

} else {

isWhat_ = String

.valueOf(keyAbc_[resultAbc[19 + column3]]);

}

// showPopWindow(

// column3

// * (qwertyW_ + colW_one)

// + (BORDER

// + qwertyW_ - qwertyW_ / 4) - windownShow_W

// , BORDER_TOP + qwertyH_ * 2

// + BORDER_CENTER * 2 + qwertyH_ / 2,

// isWhat_,isOut_);

}

} else if (y > (rowThird + BORDER_CENTER)

&& y < rowFourth) {

// 第四行

if (x > BORDER

&& x < (BORDER + keyBoard_gray_enter

.getWidth())) {

isNum_ = true;

} else if (x > (width_ - BORDER - keyBoard_gray_enter

.getWidth()) && x < (width_ - BORDER)) {

isDel_ = true;

keyEnter_ = true;

}

}

}

invalidate();

return true;

case MotionEvent.ACTION_MOVE:

// if(Math.abs(x - 2) > 2 || Math.abs(y - 2) > 2 ){

// column1 = -1;

// column2 = -1;

// column3 = -1;

// column4 = -1;

// column5 = -1;

// }

invalidate();

return true;

case MotionEvent.ACTION_UP:

if (isNum_) {

if (key_row != -1 && key_column != -1) {

isDelete_ = false;

if (key_row == 3) {

switch (key_column) {

case 0:

if (inputTypeNumber_) {

keyEnter_ = false;

dlg_.dismiss();

} else {

isDelete_ = true;

isNum_ = false;

}

break;

case 1:

textBuffer_ = appendBuffer(

String.valueOf(resultNum[9]),

true);

break;

case 2:

isDel_ = false;

isDelete_ = true;

if (null != textBuffer_

&& textBuffer_.length() > 0

&& tempEdit_.getText() != null

&& tempEdit_.getText()

.toString().trim()

.length() > 0) {

try {

int k = tempEdit_

.getSelectionEnd();

textBuffer_ = textBuffer_

.deleteCharAt(k - 1);

} catch (Exception e) {

// TODO: handle exception

}

}

break;

default:

break;

}

} else {

int index = key_row * 3 + key_column;

if (index < resultNum.length) {

textBuffer_ = appendBuffer(

String.valueOf(resultNum[index]),

true);

}

}

key_row = -1;

key_column = -1;

} else {

isDelete_ = true;

}

} else {

isDel_ = false;

keyEnter_ = false;

if (column1 != -1) {

// 第一行

if (isABC_) {

// 大写字母

textBuffer_ = appendBuffer(

String.valueOf(

keyAbc_[resultAbc[column1]])

.toUpperCase(), false);

} else {

// 小写字母

textBuffer_ = appendBuffer(

String.valueOf(keyAbc_[resultAbc[column1]]),

false);

}

} else if (column2 != -1) {

// 第二行

if (isABC_) {

textBuffer_ = appendBuffer(

String.valueOf(

keyAbc_[resultAbc[10 + column2]])

.toUpperCase(), false);

} else {

textBuffer_ = appendBuffer(

String.valueOf(keyAbc_[resultAbc[10 + column2]]),

false);

}

} else if (column3 != -1) {

// 第三行

if (isABC_) {

textBuffer_ = appendBuffer(

String.valueOf(

keyAbc_[resultAbc[19 + column3]])

.toUpperCase(), false);

} else {

textBuffer_ = appendBuffer(

String.valueOf(keyAbc_[resultAbc[19 + column3]]),

false);

}

} else if (y > (rowThird + BORDER_CENTER)

&& y < rowFourth) {

isDelete_ = true;

// 第四行

if (x > (width_ - BORDER - keyBoard_gray_del

.getWidth()) && x < (width_ - BORDER)) {

isDel_ = false;

isDelete_ = true;

if (null != textBuffer_

&& textBuffer_.length() > 0

&& tempEdit_.getText() != null

&& tempEdit_.getText().toString()

.trim().length() > 0) {

try {

int k = tempEdit_.getSelectionEnd();

textBuffer_ = textBuffer_

.deleteCharAt(k - 1);

} catch (Exception e) {

// TODO: handle exception

}

}

keyEnter_ = false;

}

} else if (y > rowFourth) {

isDelete_ = true;

}

}

// 每按一次键盘刷新一次

// resultAbc = getRandomNumber(26);

// resultNum = getRandomNumber(10);

column1 = -1;

column2 = -1;

column3 = -1;

column4 = -1;

column5 = -1;

tempEdit_.setText(getStringBuffer(textBuffer_, true)

.toString());

if (null != getStringBuffer(textBuffer_, true)) {

tempEdit_.setSelection(getStringBuffer(textBuffer_,

true).length());

}

// 用户输入的内容显示一秒后变为*号

new CountDownTimer(1000, 1000) {

public void onFinish() {

tempEdit_.setText(getStringBuffer(textBuffer_,

false).toString());

if (null != getStringBuffer(textBuffer_, false)) {

tempEdit_.setSelection(getStringBuffer(

textBuffer_, false).length());

}

}

@Override

public void onTick(long millisUntilFinished) {

// TODO Auto-generated method stub

}

}.start();

edit_.setText(textBuffer_);

if (null != textBuffer_) {

edit_.setSelection(textBuffer_.length());

}

dismissPopWindow();

invalidate();

vibrator_.vibrate(2 * VIBRATE_DURATION);

return true;

}

return false;

}

private int getIntX(int left, String str) {

int startX = 0;

startX = (int) (left + (qwertyW_ - textPaint_.measureText(str)) / 2);

return startX;

}

private void showPopWindow(int eventX, int eventY, String isWhat,

String isOut) {

ShowView show = null;

show = new ShowView(bv_, isWhat, isOut);

LinearLayout ll = new LinearLayout(bv_);

ll.addView(show);

if (null != isOut) {

if (isOut.equalsIgnoreCase(“left”)) {

eventX = eventX + LPUtils.getScaledValue(10);

} else if (isOut.equalsIgnoreCase(“right”)) {

eventX = eventX + colW_one - LPUtils.getScaledValue(3);

}

}

popWindow_ = new PopupWindow(ll,

ViewGroup.LayoutParams.WRAP_CONTENT,

ViewGroup.LayoutParams.WRAP_CONTENT);

if (!popWindow_.isShowing()) {

popWindow_.showAtLocation(this, Gravity.AXIS_X_SHIFT,

eventX + 1, eventY - LPUtils.getScaledValue(20));

}

}

private void dismissPopWindow() {

if (null != popWindow_ && popWindow_.isShowing()) {

popWindow_.dismiss();

}

}

// 得到一个拼接的buffer,用来显示点还是实际内容

public StringBuffer getStringBuffer(StringBuffer text, boolean isShow) {

if (text == null) {

return text;

}

StringBuffer buf = new StringBuffer();

if (isShow) {

if (null != text && !“”.equalsIgnoreCase(text.toString())) {

for (int i = 0; i <= text.length() - 2; i++) {

buf = buf.append(“*”);

}

if (isDelete_) {

buf = buf.append(“*”);

} else {

buf = buf.append(text.charAt(text.length() - 1));

}

}

} else {

if (null != text) {

for (int i = 0; i <= text.length() - 1; i++) {

buf = buf.append(“*”);

}

}

}

isDelete_ = false;

return buf;

}

// 删除文本内容

public void delEditValue(StringBuffer sb) {

if (sb.length() == 0

&& edit_.getText().toString().trim().length() > 0) {

sb.append(edit_.getText().toString().trim());

}

if (sb.length() > 0) {

sb = sb.deleteCharAt(sb.length() - 1);

edit_.setText(sb);

edit_.setSelection(edit_.getText().toString().trim().length());

}

}

// 连删操作

public void delEditAgainValue() {

StringTicker.instance().notifyTicker();

this.postInvalidate();

if ((System.currentTimeMillis() - keyDownTime) / 100 > 1) {

// 按下时间大于0.1秒 则执行连删输入框

delEditValue(textBuffer_);

}

}

public StringBuffer appendBuffer(String buf, boolean isAppend) {

// 判断是否输入框有限制输入长度

if (null != textBuffer_ && textBuffer_.length() >= maxSize) {

isDelete_ = true;

return textBuffer_;

} else {

if (inputTypeNumber_) {

if (isAppend) {

textBuffer_ = textBuffer_.append(buf);

} else {

isDelete_ = true;

}

} else {

textBuffer_ = textBuffer_.append(buf);

}

return textBuffer_;

}

}

public int[] getRandomNumber(int limit) {

int[] result = new int[limit];

for (int i = 0; i < limit; i++) {

result[i] = i;

}

int w;

Random rand = new Random();

for (int i = limit - 1; i > 0; i–) {

w = rand.nextInt(i);

int t = result[i];

result[i] = result[w];

result[w] = t;

}

return result;

}

}

/**

  • 确定按钮

  • @author brookess

*/

class buttonOk extends LinearLayout {

TextView tv;

boolean isSubmit_ = false;

public buttonOk(Context context, boolean isSubmit) {

super(context);

isSubmit_ = isSubmit;

tv = new TextView(context);

tv.setTextSize(22);

tv.setText(“确定”);

// tv.setTypeface(Typeface.DEFAULT_BOLD);

tv.setTextColor(Color.WHITE);

this.setBackgroundResource(R.drawable.keyboard_num_down);

this.addView(tv);

this.setLayoutParams(new LinearLayout.LayoutParams(

LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

this.setGravity(Gravity.CENTER);

}

@Override

public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

// this.setBackgroundResource(R.drawable.keyboard_abc_down);

break;

case MotionEvent.ACTION_UP:

// this.setBackgroundResource(R.drawable.keyboard_abc_up);

dlg_.dismiss();

break;

default:

// this.setBackgroundResource(R.drawable.keyboard_abc_up);

break;

}

return true;

}

}

private class ShowView extends TextView {

private Bitmap keyBoard_show_window;

private Bitmap keyBoard_show_window_left;

private Bitmap keyBoard_show_window_right;

private int width_;

private int height_;

private TextPaint paint_;

private String isWhat_;

private String isOut_;

public ShowView(Context context, String isWhat, String isOut) {

super(context);

// TODO Auto-generated constructor stub

isWhat_ = isWhat;

isOut_ = isOut;

init();

}

private void init() {

// TODO Auto-generated method stub

paint_ = new TextPaint();

paint_.setAntiAlias(true);

paint_.setTextSize(LPUtils.getScaledValue(18));

paint_.setTypeface(Typeface.DEFAULT_BOLD);

paint_.setColor(Color.BLACK);

keyBoard_show_window = BitmapFactory.decodeResource(getResources(),

R.drawable.keyboard_show_window);

keyBoard_show_window_left = BitmapFactory.decodeResource(

getResources(), R.drawable.keyboard_show_window_left);

keyBoard_show_window_right = BitmapFactory.decodeResource(

getResources(), R.drawable.keyboard_show_window_right);

int w = LPUtils.screenWidth_ / 8;

int h = w * keyBoard_show_window.getHeight()

/ keyBoard_show_window.getWidth();

keyBoard_show_window = Bitmap.createScaledBitmap(

keyBoard_show_window, w, h, true);

keyBoard_show_window_left = Bitmap.createScaledBitmap(

keyBoard_show_window_left, w, h, true);

keyBoard_show_window_right = Bitmap.createScaledBitmap(

keyBoard_show_window_right, w, h, true);

if (null != isOut_) {

width_ = keyBoard_show_window_left.getWidth();

} else {

width_ = keyBoard_show_window.getWidth();

}

height_ = keyBoard_show_window.getHeight();

LayoutParams lp = (android.widget.LinearLayout.LayoutParams) this

.getLayoutParams();

if (lp == null) {

setLayoutParams(new LayoutParams(width_, height_));

} else {

lp.height = height_;

lp.width = width_;

setLayoutParams(lp);

}

}

public void onDraw(Canvas g) {

if (null != isOut_) {

if (isOut_.equalsIgnoreCase(“left”)) {

g.drawBitmap(keyBoard_show_window_left, 0, 0, paint_);

} else if (isOut_.equalsIgnoreCase(“right”)) {

g.drawBitmap(keyBoard_show_window_right, 0, 0, paint_);

}

} else {

g.drawBitmap(keyBoard_show_window, 0, 0, paint_);

}

if (null != isWhat_) {

g.drawText(isWhat_, (width_ - paint_.measureText(isWhat_)) / 2,

height_ / 2 - LPUtils.getScaledValue(8), paint_);

}

}

}

}

源码下载:http://download.csdn.net/download/gao_chun/8741237

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

keyBoard_show_window.getHeight();

LayoutParams lp = (android.widget.LinearLayout.LayoutParams) this

.getLayoutParams();

if (lp == null) {

setLayoutParams(new LayoutParams(width_, height_));

} else {

lp.height = height_;

lp.width = width_;

setLayoutParams(lp);

}

}

public void onDraw(Canvas g) {

if (null != isOut_) {

if (isOut_.equalsIgnoreCase(“left”)) {

g.drawBitmap(keyBoard_show_window_left, 0, 0, paint_);

} else if (isOut_.equalsIgnoreCase(“right”)) {

g.drawBitmap(keyBoard_show_window_right, 0, 0, paint_);

}

} else {

g.drawBitmap(keyBoard_show_window, 0, 0, paint_);

}

if (null != isWhat_) {

g.drawText(isWhat_, (width_ - paint_.measureText(isWhat_)) / 2,

height_ / 2 - LPUtils.getScaledValue(8), paint_);

}

}

}

}

源码下载:http://download.csdn.net/download/gao_chun/8741237

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-Zlij2vIJ-1710915477283)]
[外链图片转存中…(img-KcdDOwyz-1710915477283)]
[外链图片转存中…(img-JX8YBOiE-1710915477284)]
[外链图片转存中…(img-0C9qlpCQ-1710915477284)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
[外链图片转存中…(img-MQzryIxJ-1710915477284)]

  • 14
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值