Android dual-screen different display control

a brief introduction

1.1 The mobile phones we use basically only have one screen, so what does the dual screen here mean? In fact, mobile phones now support dual screens. We can open this control in the developer options to see what dual screens are.

You can open Settings -> Developer Options -> Simulate Auxiliary Display Device to enable the secondary screen display, and you can also choose the display size

 1.2 However, the use of dual-screen scenarios on mobile phones is relatively seldom, and it is more used in some face recognition payment, or scanning codes, swiping cards to pay these devices.

The main screen is used for facial recognition, code scanning, and card swiping.

The secondary screen has a keyboard input, which is used to input the amount and query the transaction records.

For example, the following group meal machine is a typical dual-screen support

 Second, the realization of the dual-screen program

2.1 The main screen, that is, the scanning screen, needless to say, is a normal Activity page. The secondary screen (with keyboard) needs the Presentation class in the native API

2.2 Presentation is a special dialog whose main purpose is to display content on the auxiliary display screen. Presentation needs to be associated with a specific Display when it is created. Since it is a Dialog, the context passed in the constructor must be an activity context.

The following source code shows that it is inherited from Dialog

 2.3 After understanding the Presentation, it will be easy to develop later, just use the Activity to control the Dialog.

But later you will find that it is still easy to think, because the secondary screen cannot be touched, which also causes the input box to not get the focus, the soft keyboard to pop up, and the return key, which all need to be controlled through peripheral devices.

Then this peripheral device is a small numeric keypad, which is actually the numeric area of ​​an ordinary keyboard.

2.4 How to monitor the input of the numeric keyboard area? At this time, a key mapping relationship is needed. The keys on the keyboard are all based on standard protocols, so we only need to find a standard mapping relationship. As shown below

The android native api provides the class KeyEvent.java with keyboard events, which contains all keyboard click events

 Then we can listen to which key on the keyboard is clicked in the event distribution

 Then compare the code and key relationship mapping below to know which key we pressed

 Three, source code example

3.1 Set permissions, or not set. If you want the Presentation to not exit with the main Activity, you must add the system pop-up permission

<!--显示系统窗口权限-->
 <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
 <!--在屏幕最顶部显示addview-->
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />

3.2 Custom Presentation

public class SecondLoginPresentation extends Presentation {

	public SecondLoginPresentation(Context outerContext, Display display) {
		super(outerContext,display);

	}
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.second_screen);

	}
}

3.3 Display this secondary screen in Acitivty, pay attention to this place to first determine whether there is a secondary screen

//显示副屏幕
SecondLoginPresentation mPresentation;

private void showDisplay() {
	DisplayManager displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
	Display[] presentationDisplays = displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
	if (presentationDisplays.length > 0) {
        //判断是否有双屏
        // displays[0] 主屏
        // displays[1] 副屏
		Display display = presentationDisplays[0];

		if (mPresentation == null) {
			mPresentation = new SecondLoginPresentation(this, display);
			try {
				mPresentation.show();
			} catch (WindowManager.InvalidDisplayException e) {
				mPresentation = null;
			}
		}
	}
}

3.4 Monitor keyboard input, note that this can only be monitored in the Activity

Just need to monitor the keys we need

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
	if (keyListener != null) {
		int action = event.getAction();
		switch (action) {
			case KeyEvent.ACTION_DOWN:

				if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP) {
					return super.dispatchKeyEvent(event);
				}
				if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN) {
					return super.dispatchKeyEvent(event);
				}
				if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
					return super.dispatchKeyEvent(event);
				}
				if (event.getKeyCode() == KeyEvent.KEYCODE_MENU) {
					return super.dispatchKeyEvent(event);
				}
				if (event.getKeyCode() == KeyEvent.KEYCODE_HOME) {
					return super.dispatchKeyEvent(event);
				}
				if (event.getKeyCode() == KeyEvent.KEYCODE_POWER) {
					return super.dispatchKeyEvent(event);
				}

				if (event.getKeyCode() == KeyEvent.KEYCODE_F1) {
					keyListener.textSure("功能");
					return true;
				} else if (event.getKeyCode() == KeyEvent.KEYCODE_F2) {
					keyListener.textSure("设置");
					return true;
				} else if (event.getKeyCode() == 111 || event.getKeyCode() == 4) {
					keyListener.textSure("取消");
					return true;
				} else if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
					keyListener.textSure("删除");
					return true;
				} else if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
					keyListener.textSure("确认");
					return true;
				} else if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP) {
					keyListener.textSure("上箭头");
					return true;
				} else if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_DOWN) {
					keyListener.textSure("下箭头");
					return true;
				} else {
					int unicodeChar = event.getUnicodeChar();
					keyListener.textChange(String.valueOf((char) unicodeChar));
					return true;
				}

		}
	}
	return super.dispatchKeyEvent(event);
}

3.5 SecondLoginPresentation handles keyboard events

@Override
public void textChange(String text) {
    //数字输入
	addTextValue(text);
}

@Override
public void textSure(String value) {
    //除数字之外按键
	switch (value) {
		case "功能":
			break;
		case "设置":
			break;
		case "删除":
			popTextValue();
			break;
		case "取消":
		   
			break;
		case "确认":
		   
			//开始支付逻辑
			//....................................
			break;
		case "上箭头":
			break;
		case "下箭头":
			break;
	}
}

//输入键盘监听-添加
private Stack<String> mNumberStack = new Stack<>();


public void addTextValue(String value) {
	//限制输入数字或者小数点
	if (!Utils.isNumeric(value)) {
		return;
	}

	String moneyString = etInputContent.getText().toString();
	//确保第一位不是.和+
	if ((value.equals(".") || value.equals("+")) && moneyString.length() <= 0) {
		return;
	}
	//确保不输入连续的+
	if (value.equals("+") && moneyString.endsWith("+")) {
		return;
	}
	//确保不是连续小数点
	if (value.equals(".") && moneyString.endsWith(".")) {
		return;
	}
	//确保一个小数点,后面两位
	//获取最后一个加号的索引
	String lastPartString="";
	if (moneyString.length() > 0 && moneyString.contains("+")) {
		lastPartString = moneyString.substring(moneyString.lastIndexOf("+"));
	}else {
		//如果长度小于0表示还没输入过加号,那最后一段就是完整内容
		lastPartString = moneyString;
	}
	if (!value.equals("+") && lastPartString.contains(".") && lastPartString.substring(lastPartString.indexOf(".")).length() > 2) {
		return;
	}
	//确保当前段不包含两个小数点
	if (value.equals(".") && lastPartString.contains(".")) {
		return;
	}

	//限制最大金额-7位
//        if (!TextUtils.isEmpty(moneyString) && moneyString.length() >= 7) {
//            return;
//        }


	//确保第一位不为0
	if (moneyString.length() == 1 && moneyString.startsWith("0") && !value.equals(".")) {
		mNumberStack.clear();
	}

	mNumberStack.push(value);

	showTextValue();
}

//输入键盘监听-删除
public void popTextValue() {
	if (mNumberStack.empty()) {
		return;
	}
	mNumberStack.pop();
	showTextValue();
}

//显示输入内容
public void showTextValue() {
	StringBuilder codeBuilder = new StringBuilder();
	for (String value : mNumberStack) {
		codeBuilder.append(value);
	}
	etInputContent.setText(codeBuilder.toString());

	moneyInputResult();
}

//计算总金额
public void moneyInputResult() {
	String inputString = etInputContent.getText().toString();
	String moneyResult = "";
	if (!TextUtils.isEmpty(inputString)) {
		if (inputString.contains("+")) {
			String[] stringsArray = inputString.split("\\+");
			for (String ss : stringsArray) {
				moneyResult = add(TextUtils.isEmpty(moneyResult) ? "0" : moneyResult, ss);
			}
		} else {
			moneyResult = inputString;
		}
	}
	etMoney.setText(moneyResult);
}

/**
 * 加减法精确计算类
 */

/**
 * 加法
 */
public static String add(String parms1, String param2) {
	return new BigDecimal(parms1).add(new BigDecimal(param2)).toString();
}

Four summary

4.1 Presentation is a Dialog that cannot be touched, so all events must be handled by listening to external devices

4.2 Normally, Presentation exits with the Activity. If you want to exit without the Activity, you need to add the system pop-up permission

4.3 In most cases, there is no difference between the usage of dialog and the main thing is to understand the mapping relationship of the keyboard, and use the keyboard to operate the page

Guess you like

Origin blog.csdn.net/qq_29848853/article/details/130362129