簡単な紹介
1.1 私たちが使っている携帯電話は基本的に画面が 1 つしかありませんが、ここでいう 2 画面とは何を意味しますか? 実際、携帯電話は現在デュアル スクリーンをサポートしており、開発者向けオプションでこのコントロールを開いてデュアル スクリーンが何であるかを確認できます。
[設定] -> [開発者向けオプション] -> [補助表示デバイスのシミュレート] を開いて、セカンダリ画面表示を有効にすることができます。また、表示サイズを選択することもできます。
1.2 ただし、携帯電話でデュアル スクリーン シナリオが使用されることは比較的まれで、一部の顔認識支払いやコードのスキャン、カードをスワイプしてこれらのデバイスに支払う場合に多く使用されます。
メイン画面は、顔認識、コード スキャン、カード スワイプに使用されます。
2 次画面にはキーボード入力があり、金額の入力と取引記録の照会に使用されます。
たとえば、次のグループ食事マシンは典型的なデュアル スクリーン サポートです。
第二に、二画面プログラムの実現
2.1 メイン画面、つまりスキャン画面は、言うまでもなく通常のアクティビティページです。セカンダリ画面 (キーボード付き) にはネイティブ API の Presentation クラスが必要です
2.2 プレゼンテーションは、補助ディスプレイ画面にコンテンツを表示することを主な目的とする特別なダイアログであり、作成時に特定のディスプレイに関連付ける必要があります。これはダイアログであるため、コンストラクターで渡されるコンテキストはアクティビティ コンテキストである必要があります。
次のソース コードは、Dialog から継承されていることを示しています。
2.3 プレゼンテーションを理解すると、後の開発は簡単になります。アクティビティを使用してダイアログを制御するだけです。
しかし、後になって、セカンダリ スクリーンにタッチできないため、入力ボックスにフォーカスが合わず、ソフト キーボードがポップアップできず、リターン キーは周辺機器を介して制御する必要があるため、まだ考えやすいことがわかります。 。
この周辺デバイスは小さなテンキーであり、実際には通常のキーボードの数字領域です。
2.4 数字キーボード領域の入力を監視するにはどうすればよいですか? このとき、キーのマッピング関係が必要です。キーボードのキーはすべて標準プロトコルに基づいているため、標準のマッピング関係を見つけるだけで済みます。以下に示すように
Android ネイティブ API は、すべてのキーボード クリック イベントを含むキーボード イベントを備えたクラス KeyEvent.java を提供します。
その後、イベント配信でキーボードのどのキーがクリックされたかを聞くことができます
次に、以下のコードとキーの関係マッピングを比較して、どのキーが押されたかを確認します。
3、ソースコード例
3.1 権限を設定するか、設定しません。プレゼンテーションがメイン アクティビティとともに終了しないようにするには、システム ポップアップ アクセス許可を追加する必要があります。
<!--显示系统窗口权限-->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<!--在屏幕最顶部显示addview-->
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />
3.2 カスタムプレゼンテーション
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 Acitivty でこのセカンダリ画面を表示します。最初にセカンダリ画面があるかどうかを判断するには、この場所に注目してください
//显示副屏幕
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 キーボード入力を監視します。これはアクティビティでのみ監視できることに注意してください。
必要なキーを監視するだけで済みます
@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 はキーボード イベントを処理します
@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();
}
4つのまとめ
4.1 プレゼンテーションはタッチできないダイアログであるため、すべてのイベントは外部デバイスをリッスンして処理する必要があります
4.2 プレゼンテーションは通常、アクティビティとともに終了します。アクティビティなしで終了したい場合は、システム ポップアップ権限を追加する必要があります。
4.3 ほとんどの場合、ダイアログの使用法に違いはありません。主なことは、キーボードのマッピング関係を理解し、キーボードを使用してページを操作することです。