【问题标题】:Android: Tapping one to six buttons continuously [one after another] to string together different resultsAndroid:连续点击一到六个按钮[一个接一个]将不同的结果串在一起
【发布时间】:2017-01-06 20:57:28
【问题描述】:

我决定开发一款 Android 应用,该应用使用的技术与我之前见过的应用非常相似。我想将多个按钮按下以等同于不同的不同文本结果。

Six dots - braille application (actual application to use)

我正在制作的这个原生盲文应用程序有 6 个不同的按钮,我希望每个独特的组合都能给我带来不同的字母。例如:我想按下按钮 1 来简单地将字母“A”带给我。然后连续按下按钮 1 和按钮 2 会给我带来字母“C”。我希望这 6 个按钮的每个不同按钮组合都给我带来一个单独的字母。

可以请精通Java的人解释一下这是如何完成的吗?我怎样才能在多个按钮按下时串起来给我带来不同的结果?感谢您的帮助。

Braille alphabet

我在 java 上的代码:

        public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.keyboard);

          Window window = this.getWindow();
          window.addFlags(LayoutParams.FLAG_DISMISS_KEYGUARD);
          window.addFlags(LayoutParams.FLAG_SHOW_WHEN_LOCKED);
          window.addFlags(LayoutParams.FLAG_TURN_SCREEN_ON);

          // Init GUI
          txtMessage = (EditText) findViewById(R.id.txtMesssage);
          Button buttonOne = (Button) findViewById(R.id.block1);
          Button buttonTwo = (Button) findViewById(R.id.block2);
          Button buttonThree = (Button) findViewById(R.id.block3);
          Button buttonFour = (Button) findViewById(R.id.block4);
          Button buttonFive = (Button) findViewById(R.id.block5);
          Button buttonSix = (Button) findViewById(R.id.block6);



          // Attached Click Listener
          btnSend.setOnClickListener(this);

          buttonOne.setOnClickListener(this);
          buttonTwo.setOnClickListener(this);
          buttonThree.setOnClickListener(this);
          buttonFour.setOnClickListener(this);
          buttonFive.setOnClickListener(this);
          buttonSix.setOnClickListener(this);

    }
@Override
    public void onClick(View v) {

        }

        switch (v.getId()) {
        case R.id.block1:       

             break;
        case R.id.block2:

             break;
        case R.id.block3:

            break;
        case R.id.block4:

            break;
        case R.id.block5:

            break;
        case R.id.block6:

            break;
        }
     txtMessage.setText();
    }

    //functions below.
    ....     ....
    ...       ...
    ..         ..
    .     O     .
    ..         ..
    ...       ...
    ....     ....

关于我的 XML 布局keyboard.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" 
android:background="@color/lightgrey">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

<EditText
    android:id="@+id/txtMesssage"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    android:hint="Enter Message"
    android:textColor="@color/darkbrown" >
</EditText>

</LinearLayout>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1.0"

    android:orientation="horizontal" >

    <Button
        android:id="@+id/block1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/white"
        android:layout_weight="1.0"
        android:text="Button one" />

    <Button
        android:id="@+id/block2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1.0"
        android:background="@color/blue"
        android:text="Button two" />

</LinearLayout>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1.0"
    android:orientation="horizontal" >

    <Button
        android:id="@+id/block3"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1.0"
        android:background="@color/bg_gradient_end"
        android:text="Button three" />

    <Button
        android:id="@+id/block4"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1.0"
        android:background="@color/darkgrey"
        android:text="Button four" />

</LinearLayout>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1.0"
    android:orientation="horizontal" >

    <Button
        android:id="@+id/block5"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1.0"
        android:background="@color/lightgrey"
        android:text="Button five" />

    <Button
        android:id="@+id/block6"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1.0"
        android:background="@color/bg_gradient_start"
        android:text="Button six" />

</LinearLayout>

到目前为止,我编写的代码没有按我的意愿工作,所以我暂时将switch 语句留空。请纠正我的代码或帮助我解决这个问题。谢谢

我的计时器代码:

            Timer processTimer = new Timer();
        processTimer.schedule(new TimerTask() {
            public void run() {    
                processInput();    
            }

            private void processInput() {
                // TODO Auto-generated method stub
                map.put(getString(R.id.block1), "A");
                map.put(getString(R.id.block1) + getString(R.id.block2), "C");



            }
        }, 500); // Delay before processing. 

    processTimer.cancel();

    processTimer.schedule(new TimerTask() {
            public void run() {    
                processInput();    
            }

            private void processInput() {
                // TODO Auto-generated method stub
                map.get(R.id.block1);
                map.get(R.id.block1+R.id.block2);
                //this.close();


            }
        }, 500);

这对吗?

【问题讨论】:

  • 你打算实现一个“进入”按钮吗? (注册您的 6 个按钮的序列)还是您希望应用在暂停后自动接受序列?
  • @TWL 您好,您好,无需输入按钮。我希望应用程序在暂停后自动接受序列。 :)
  • 二进制和呢?按钮 1 = 100000b,按钮 2 = 010000,按钮 3 = 001000b,按钮 4 = 000100b,按钮 5 = 000010 和按钮 6 = 000001。当按下按钮 1 和按钮 2 时,只需添加 100000b 和 010000b,结果为 110000b。保持不变:110000b = 'c'。按钮 1 + 按钮 4 是 100000b + 000100b = 100100b = 'e'。你知道我的意思吗?
  • @aptyp 天哪,我没有关注.. 我真的不明白,对不起,我真的不精通 java 编程。但这听起来很酷,但是如果我必须从 A-Z 字母工作会有什么冲突吗? 编辑:我不认为如果我必须从 A-Z 生成不起作用的字母..
  • @aptyp 这有点工作,但不允许在序列中使用双按钮,因为您基本上只是对数据进行或处理。您也无法分辨首先是什么按钮。所以 button1 然后 button2 == button2 然后 button1。这不好。

标签: java android eclipse function switch-statement


【解决方案1】:

我尝试使用类似于 aptyp 建议的方法进行编码:

MainActivity.java:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
static long DELAY_TIME_INPUT = 500;
static int INPUT_TYPE_NORMAL = 0;
static int INPUT_TYPE_CAP = 1;
static int INPUT_TYPE_NUM = 2;

TextView txtMessage;
int[] mAlphabetTable1 = new int[]{1, 3, 9, 25, 17, 11, 27, 19, 10, 26,
                                5, 7, 13, 29, 21, 15, 31, 23, 14, 30,
                                37, 39, 58, 45, 61, 53};
int[] mSymbolTable1 = new int[]{2, 6, 4, 18, 36, 40, 50, 22, 38, 52, 54, 12};
/* Note: The value used below {8, 16, 20, 24} are just an example.
    I choose these values because they are not defined on the above tables.
  */
int[] mSpecialTable1 = new int[]{8, 16, 20, 24};

// char[] mAlphabetTable2 = new char[]{};
char[] mNumberTable2 = new char[]{'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'};
char[] mSymbolTable2 = new char[]{',', ';', '\'', ':','-', '.', '.', '!', '“', '”','(','/'};
int mCurrentAlphabet = 0;
int mCurrentInputType = 0;
long mLastTimeStamp;

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

    Window window = this.getWindow();
    window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
    window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
    window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
    // Init GUI
    txtMessage = (TextView) findViewById(R.id.txtMesssage);
    Button buttonOne = (Button) findViewById(R.id.block1);
    Button buttonTwo = (Button) findViewById(R.id.block2);
    Button buttonThree = (Button) findViewById(R.id.block3);
    Button buttonFour = (Button) findViewById(R.id.block4);
    Button buttonFive = (Button) findViewById(R.id.block5);
    Button buttonSix = (Button) findViewById(R.id.block6);
    // Attached Click Listener
    buttonOne.setOnClickListener(this);
    buttonTwo.setOnClickListener(this);
    buttonThree.setOnClickListener(this);
    buttonFour.setOnClickListener(this);
    buttonFive.setOnClickListener(this);
    buttonSix.setOnClickListener(this);
}

@Override
public void onClick(View view) {
    switch (view.getId()){
        case R.id.block1: mCurrentAlphabet |=1; break;
        case R.id.block2: mCurrentAlphabet |=2; break;
        case R.id.block3: mCurrentAlphabet |=4; break;
        case R.id.block4: mCurrentAlphabet |=8; break;
        case R.id.block5: mCurrentAlphabet |=16; break;
        case R.id.block6: mCurrentAlphabet |=32; break;
    }
    view.setBackgroundColor(Color.BLACK);
    Button btView = (Button) view;
    btView.setTextColor(Color.WHITE);
    mLastTimeStamp = System.currentTimeMillis();
    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            long currentTimeStamp = System.currentTimeMillis();
            if(currentTimeStamp - mLastTimeStamp > DELAY_TIME_INPUT){
                genNewBrailleAlphabet();
            }
        }
    }, DELAY_TIME_INPUT + 10);
}

public void genNewBrailleAlphabet(){
    if(mCurrentAlphabet == 32 || mCurrentAlphabet == 60){ // Check if input is Cap or Num sign?
        if(mCurrentAlphabet == 32){ // Input is Cap sign.
            mCurrentInputType = INPUT_TYPE_CAP;
            TextView txtCap = (TextView) findViewById(R.id.cap);
            txtCap.setBackgroundColor(Color.GREEN);
        } else { // Input is Num sign.
            TextView txtNum = (TextView) findViewById(R.id.num);
            if(mCurrentInputType == INPUT_TYPE_NUM){
                mCurrentInputType = INPUT_TYPE_NORMAL; // Turn off Num sign.
                txtNum.setBackgroundColor(Color.TRANSPARENT);
            } else {
                mCurrentInputType = INPUT_TYPE_NUM; // Turn on Num sign.
                txtNum.setBackgroundColor(Color.GREEN);
            }
        }
    } else { // Input is not Cap or Num sign.
        byte currentAlphabetIndex = -1;
        char newAlphabet = 0;
        for (int i = 0; i < mAlphabetTable1.length; i++) {
            if (mAlphabetTable1[i] == mCurrentAlphabet) {
                currentAlphabetIndex = (byte) i;
                break;
            }
        }
        if(currentAlphabetIndex != -1) { // Check if input is Numbers or Alphabets?
            if (mCurrentInputType == INPUT_TYPE_NUM) { // Input is Numbers.
                if(currentAlphabetIndex < 10) {
                    newAlphabet = mNumberTable2[currentAlphabetIndex];
                }
            } else if (mCurrentInputType == INPUT_TYPE_CAP) // Input is Alphabets.
                newAlphabet = (char) (currentAlphabetIndex + 'A');
            else newAlphabet = (char) (currentAlphabetIndex + 'a');

            String msg = txtMessage.getText().toString() + newAlphabet;
            txtMessage.setText(msg);
        } else { // Input is not Numbers or Alphabets.
            for (int i = 0; i < mSymbolTable1.length; i++) {
                if (mSymbolTable1[i] == mCurrentAlphabet) {
                    currentAlphabetIndex = (byte) i;
                    break;
                }
            }
            if(currentAlphabetIndex != -1) { // Check if input is Punctuations?
                newAlphabet = mSymbolTable2[currentAlphabetIndex];
                if(currentAlphabetIndex == 8){ // Open Quote, Question Mark have the same pattern.
                    String tmpString = txtMessage.getText().toString();
                    if(tmpString.length() > 0 && !tmpString.endsWith(" ")){
                        // Last typed alphabet is not space, so this is Question Mark.
                        newAlphabet = '?';
                    }
                }
                String msg = txtMessage.getText().toString() + newAlphabet;
                txtMessage.setText(msg);
            } else { // Input is not Punctuations, so it is Special Action or undefined.
                for (int i = 0; i < mSpecialTable1.length; i++) {
                    if (mSpecialTable1[i] == mCurrentAlphabet) {
                        currentAlphabetIndex = (byte) i;
                        break;
                    }
                }
                if(currentAlphabetIndex != -1) { // Check if input is Special Action?
                    String msg = txtMessage.getText().toString();
                    // Input is Special Action
                    switch (currentAlphabetIndex) {
                        case 0: // Change focus here
                            // Change focus code
                            /* if (txtNumber.hasFocus()) {
                                txtMessage.requestFocus();
                            } else {
                                txtNumber.requestFocus();
                            } */
                            break;
                        case 1: // BackSpace
                            msg = msg.substring(0, msg.length() - 1);
                            txtMessage.setText(msg);
                            break;
                        case 2: // Space
                            msg = msg + " ";
                            txtMessage.setText(msg);
                            break;
                        case 3: // New Line
                            msg = msg + "\n";
                            break;
                    }
                    txtMessage.setText(msg);
                } else { // Input not defined.
                    Toast.makeText(getApplicationContext(), "Clicked button combination not defined!!", Toast.LENGTH_SHORT).show();
                }
            }
        }

        if(mCurrentInputType == INPUT_TYPE_CAP){
            TextView txtCap = (TextView) findViewById(R.id.cap);
            txtCap.setBackgroundColor(Color.TRANSPARENT);
            mCurrentInputType = INPUT_TYPE_NORMAL;
        }
    }
    // Reset button views ana variable for next alphabet.
    Button buttonOne = (Button) findViewById(R.id.block1);
    Button buttonTwo = (Button) findViewById(R.id.block2);
    Button buttonThree = (Button) findViewById(R.id.block3);
    Button buttonFour = (Button) findViewById(R.id.block4);
    Button buttonFive = (Button) findViewById(R.id.block5);
    Button buttonSix = (Button) findViewById(R.id.block6);
    buttonOne.setBackgroundColor(Color.WHITE);
    buttonTwo.setBackgroundColor(Color.WHITE);
    buttonThree.setBackgroundColor(Color.WHITE);
    buttonFour.setBackgroundColor(Color.WHITE);
    buttonFive.setBackgroundColor(Color.WHITE);
    buttonSix.setBackgroundColor(Color.WHITE);
    buttonOne.setTextColor(Color.BLACK);
    buttonTwo.setTextColor(Color.BLACK);
    buttonThree.setTextColor(Color.BLACK);
    buttonFour.setTextColor(Color.BLACK);
    buttonFive.setTextColor(Color.BLACK);
    buttonSix.setTextColor(Color.BLACK);
    mCurrentAlphabet = 0;
}}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<ScrollView
    android:layout_weight="4.0"
    android:background="@color/lightgrey"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/txtMesssage"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:textColor="@color/darkbrown" >
        </TextView>
    </LinearLayout>
</ScrollView>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1.0"
    android:orientation="horizontal"
    android:baselineAligned="false"
    android:layout_marginTop="15dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1.0"
        android:background="#000000"
        android:orientation="vertical" >

        <TextView
            android:text="CAP"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/cap"
            android:layout_weight="1.3"
            android:gravity="center"
            android:textSize="20sp" />

        <Button
            android:id="@+id/block1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1.0"
            android:background="#ffffff"
            android:text="Button one" />

        <Button
            android:id="@+id/block2"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1.0"
            android:background="#ffffff"
            android:text="Button two" />

        <Button
            android:id="@+id/block3"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1.0"
            android:background="#ffffff"
            android:text="Button three" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1.0"
        android:orientation="vertical"
        android:background="#000000">

        <TextView
            android:text="Num"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/num"
            android:layout_weight="1.3"
            android:gravity="center"
            android:textSize="20sp" />

        <Button
            android:id="@+id/block4"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1.0"
            android:background="#ffffff"
            android:text="Button four" />

        <Button
            android:id="@+id/block5"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1.0"
            android:background="#ffffff"
            android:text="Button five" />

        <Button
            android:id="@+id/block6"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1.0"
            android:background="#ffffff"
            android:text="Button six" />

    </LinearLayout>

</LinearLayout>

请注意,我使用的是处理程序而不是计时器。希望对您有所帮助!

【讨论】:

  • +1 这也有效,这比以前的答案好得多。但更复杂,我可以问吗?你是从哪里开始生成字母的?
  • 因为我要添加commaquestion markpunctuation markexclamation pointnew linebackspacespace@I_A_Mok
  • 顺便说一句,我想在if (txtNumber.hasFocus()) { txtMessage.requestFocus(); } else { txtNumber.requestFocus(); } 上添加它,但问题是当我每次单击/点击R.id.block4 时添加'switch:case R.id.block4' 它会移动到另一个editText [反之亦然]。 PS:我有两个editTexts..你知道把这个“代码”放在哪里吗
  • 显示数字的编辑答案应该会给你更多关于符号编码的提示。关于EditText,焦点没有变吗?或者重点不是你所期望的?另外,能说说为什么有2个EditText,需要切换焦点吗?
  • 好的,谢谢,请问您在哪里实现了字母表?我想修改其中一些,可以吗?而关于EditText,焦点发生了变化,但只要有包含R.id.block4的组合,它就会移动到其他EditText。而有2个EditText需要关注的原因是最终用户是盲人。所以他们只是依靠“语音命令”。
【解决方案2】:

我不会写很多java,所以我只能给你伪代码,但我会为你指出正确的方向。

要完成这项工作,您只需要做大约 3 件事: 1. 收集您的输入数据(点击按钮),您几乎已经完成了。 2. 知道什么时候处理输入。 3. 处理输入到正确的输出。

  1. 收集您的意见。
    此时,您希望将这些压力存储在一个 id 数组中,不需要切换。几次按下后,您应该有输入数组。

    输入[R.id.block1, R.id.block2, R.id.block2];

  2. 知道什么时候处理。
    在您的按钮按下处理程序中,添加一个倒数计时器。每按一次按钮,取消计时器并开始一个新的计时器。

    Timer processTimer = new Timer().schedule(new TimerTask() {
            public void run() {    processInput();    }
        }, 500); // Delay before processing. 
    
    
    processTimer.cancel();
    processtimer.schedule(new TimerTask() {
            public void run() {    processInput();    }
        }, 500);  
    

当调用 processInput() 时,您知道用户已停止按下按钮。

  1. 处理输入。
    为您的结果创建键/值对。

    map = {[R.id.block1],'A',
        [R.id.block1, R.id.block2],'B',
        [R.id.block1, R.id.block2, R.id.block2],'C',
      etc...
    }  
    

    搜索用户的输入并获得您的价值。

基本上就这些了。

【讨论】:

  • 达斯在正确的道路上;您需要将按钮点击保存到与您的盲文字母匹配的数组中;设置一个计时器来监听那个暂停;然后是将该数组转换为字符的逻辑。
  • 达斯先生,您好,我对在 #1 中“存储这些印刷机”的位置感到有些困惑。并在#2中通过“按钮按下处理程序”可以找到它?对不起,我真的不好。
  • @pjforum 数组将被声明在 onCreate() 和 onClick() 可以访问的地方;无论您在哪里存储应用程序/类状态。在onCreate()中,初始化它;在 onClick() 中添加;并在 processInput() 保存/处理后将其清空,以清除输入缓冲区。
  • 是的,我尝试过声明“输入[R.id.block1,R.id.block2,R.id.block3,R.id.block4,R.id.block5,R. id.block6];" onCreate(),但我收到此错误语法错误,插入“AssignmentOperator Expression”以完成表达式
  • 哦该死的,反正我已经在 onClick() 上启动了。但是当我尝试导入 TimerTask 时,我得到 - 类型不匹配:无法从 void 转换为 Timer - TimerTask 无法解析为类型 - 方法 schedule( Timer 类型中的 TimerTask, Date) 不适用于参数 (new TimerTask(){}, int)
【解决方案3】:

好的,所以我已经尝试过了,我相信这将帮助您走上您正在尝试的道路,因为我目前对您的要求的理解。我对课堂的评论、我在做什么以及为什么会非常冗长。我希望它是有帮助的,并且不喜欢迎合。听起来您可能对 Java 和 Android 还很陌生,我觉得添加的解释可能很有用。

我确信有一些边缘情况和错误被遗漏了,但应该是一个好的开始。

Android Activity 类 -- MainActivity.java

import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

/**
 * TAG is typically used for the Log class if you want to see debug/error information in logcat
 */
public static final String TAG = MainActivity.class.getSimpleName();

/**
 * Constant to delay before attempting to resolve button presses to an input
 */
public static final int INPUT_HANDLE_DELAY_MS = 500;
/**
 * Buttons have naming convention button<column><row>
 */
private Button mButton00;
private Button mButton10;
private Button mButton01;
private Button mButton11;
private Button mButton02;
private Button mButton12;

/**
 * Where we are going to store the input generated by button presses
 */
private EditText mEditText;

/**
 * Where the lookup based on ids is going to happen and convert it to a character
 */
private static Map<String, String> mLookupMap;

/**
 * I am not 100% sure if this is needed, but because we will be attempting to write to the mInputQueue,
 * and read from it, i've created a lock
 */
private static final Object mLock = new Object();

/**
 * Where we are going to store the input generated by button presses
 */
private Queue<Integer> mInputQueue= new LinkedList<>();

/**
 * Android Handler class to help with the timer, and executing our runnable to handle the
 * button resolution
 */
private Handler mHandler = new Handler();

/**
 * Runnable to cause the application to check if there is valid input
 */
private Runnable mHandleInputRunnable;

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

    // method call to initialize the lookup map
    initializeLookup();

    // Obtain all the references from the layout that we are going to need to use
    mEditText = (EditText) findViewById(R.id.edit_text);
    mButton00 = (Button) findViewById(R.id.button_0_0);
    mButton10 = (Button) findViewById(R.id.button_1_0);
    mButton01 = (Button) findViewById(R.id.button_0_1);
    mButton11 = (Button) findViewById(R.id.button_1_1);
    mButton02 = (Button) findViewById(R.id.button_0_2);
    mButton12 = (Button) findViewById(R.id.button_1_2);

    // above, the activity implements the OnClickListener interface, set the activity to handle
    // the clicks of all of the buttons
    mButton00.setOnClickListener(this);
    mButton10.setOnClickListener(this);
    mButton01.setOnClickListener(this);
    mButton11.setOnClickListener(this);
    mButton02.setOnClickListener(this);
    mButton12.setOnClickListener(this);

    // initialize the Runnable to do what we need it to do when we get a 'tick'
    mHandleInputRunnable = new Runnable() {
        @Override
        public void run() {
            handleAlarmTrigger();
        }
    };
}

@Override
public void onClick(View v) {
    if (null != mInputQueue) {
        synchronized (mLock) {
            mInputQueue.add(v.getId());
        }
    }
    resetHandler();
}

/**
 * Helper method to do the initialization of the map. Sorry about the order for the button
 * presses. They are a little sporadic, no real rhyme or reason.
 */
private void initializeLookup() {
    if (null != mLookupMap) {
        return;
    }

    mLookupMap = new HashMap<>();

    /*
    1 button characters, use String.valueOf() instead of buildStringFromIds() as there is only
    one id
     */
    mLookupMap.put(String.valueOf(R.id.button_0_0), "A");
    mLookupMap.put(String.valueOf(R.id.button_1_0), "B");
    mLookupMap.put(String.valueOf(R.id.button_0_1), "C");
    mLookupMap.put(String.valueOf(R.id.button_1_1), "D");
    mLookupMap.put(String.valueOf(R.id.button_0_2), "E");
    mLookupMap.put(String.valueOf(R.id.button_1_2), "F");

    /*
    2 button characters
     */

    mLookupMap.put(buildStringFromIds(R.id.button_0_0, R.id.button_1_0), "G");
    mLookupMap.put(buildStringFromIds(R.id.button_0_0, R.id.button_0_1), "H");
    mLookupMap.put(buildStringFromIds(R.id.button_0_0, R.id.button_1_1), "I");
    mLookupMap.put(buildStringFromIds(R.id.button_0_0, R.id.button_0_2), "J");
    mLookupMap.put(buildStringFromIds(R.id.button_0_0, R.id.button_1_2), "K");
    mLookupMap.put(buildStringFromIds(R.id.button_0_0, R.id.button_0_0), "L");

    /*
    3 button characters
     */
    mLookupMap.put(buildStringFromIds(R.id.button_0_0, R.id.button_1_0, R.id.button_0_1), "M");
    mLookupMap.put(buildStringFromIds(R.id.button_0_0, R.id.button_0_1, R.id.button_0_2), "N");
    mLookupMap.put(buildStringFromIds(R.id.button_1_0, R.id.button_1_1, R.id.button_1_2), "O");
    mLookupMap.put(buildStringFromIds(R.id.button_1_0, R.id.button_0_1, R.id.button_1_2), "P");
    mLookupMap.put(buildStringFromIds(R.id.button_1_2, R.id.button_1_2, R.id.button_0_1), "Q");
    mLookupMap.put(buildStringFromIds(R.id.button_1_2, R.id.button_1_2, R.id.button_0_1), "R");

    /*
    4 button characters
     */
    mLookupMap.put(buildStringFromIds(R.id.button_0_0, R.id.button_0_0, R.id.button_0_0, R.id.button_0_0), "S");
    mLookupMap.put(buildStringFromIds(R.id.button_0_0, R.id.button_1_0, R.id.button_0_1, R.id.button_1_0), "T");
    mLookupMap.put(buildStringFromIds(R.id.button_0_0, R.id.button_0_1, R.id.button_0_2, R.id.button_0_1), "U");
    mLookupMap.put(buildStringFromIds(R.id.button_1_0, R.id.button_1_1, R.id.button_1_2, R.id.button_1_1), "V");
    mLookupMap.put(buildStringFromIds(R.id.button_1_0, R.id.button_0_1, R.id.button_1_2, R.id.button_0_2), "W");
    mLookupMap.put(buildStringFromIds(R.id.button_1_2, R.id.button_1_2, R.id.button_0_1, R.id.button_1_2), "X");

    /*
    5 button characters
     */

    mLookupMap.put(buildStringFromIds(R.id.button_0_0, R.id.button_0_0, R.id.button_0_0, R.id.button_0_0, R.id.button_0_0), "Y");
    mLookupMap.put(buildStringFromIds(R.id.button_0_0, R.id.button_1_0, R.id.button_0_1, R.id.button_1_0, R.id.button_1_1), "Z");
}

/**
 * Helper method to poll all of the values out of the queue, and create a key. This may or may
 * not be a valid key into the map. It depends on the button presses.
 *
 * @param queue the input queue where we store the id correlating to the button that was pressed
 * @return String representing a key into the map
 */
private String buildStringFromQueue(Queue<Integer> queue) {
    StringBuilder sb = new StringBuilder();
    if (null != queue) {
        Integer pollValue;
        synchronized (mLock) {
            while ((pollValue = queue.poll()) != null) {
                sb.append(pollValue);
            }
        }
    }
    return sb.toString();
}

/**
 * Helper method to turn 1 to many R.id.button* into a string for a key as a lookup for a character
 * value
 *
 * The "..." means that the method can accept 1 or more values of the defined type
 *
 * @param ids 1 or more ids
 * @return String representing the ids as key into the map
 */
private String buildStringFromIds(int... ids) {
    StringBuilder sb = new StringBuilder();
    for (int id : ids) {
        sb.append(id);
    }

    return sb.toString();
}

/**
 * Helper method that is called each time there is a button click to either start or re-start
 * the time before resolving input
 */
private void resetHandler() {
    // null checks for the values we will be operating on
    if (null != mHandler && null != mHandleInputRunnable) {
        /**
         * remove the current runnable the handler may/may not have set, and reset it with the
         * delay. This is essentially resetting the time before the app takes the button press
         * and tries to do a lookup in the map.
         */
        mHandler.removeCallbacks(mHandleInputRunnable);
        mHandler.postDelayed(mHandleInputRunnable, INPUT_HANDLE_DELAY_MS);
    }
}

/**
 * Helper method that is called from the Runnable to attempt to handle the input
 */
private void handleAlarmTrigger() {
    // just to be safe, always check the queue for null, and don't handle if empty. Also
    // we will be setting values on the EditText, ensure it is non-null as well
    if (null != mEditText &&
            null != mInputQueue &&
            !mInputQueue.isEmpty()) {

        // Obtain the key from the input we have stored. This will provide a look up into the
        // map
        String mapKey = buildStringFromQueue(mInputQueue);

        // only try and append this if it was a valid set of button presses, and the map
        // actually has a value
        if (null != mapKey &&
                !mapKey.isEmpty() &&
                mLookupMap.containsKey(mapKey)) {
            mEditText.append(mLookupMap.get(mapKey));
        }

        // remove all stored values from the queue so we may restart the button presses
        synchronized (mLock) {
            mInputQueue.clear();
        }
    }
}
}

Android 布局 --buttons.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="vertical"
          android:layout_width="match_parent"
          android:layout_height="match_parent">

<EditText android:id="@+id/edit_text"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

<GridLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:columnCount="2"
    android:rowCount="3">

    <Button android:id="@+id/button_0_0"
        android:layout_column="0"
        android:layout_row="0"
        android:layout_gravity="fill"
        android:layout_columnWeight=".5"
        android:layout_rowWeight=".5"
        android:background="@android:color/holo_red_dark"/>

    <Button android:id="@+id/button_1_0"
        android:layout_column="1"
        android:layout_row="0"
        android:layout_gravity="fill"
        android:layout_columnWeight=".5"
        android:layout_rowWeight=".5"
        android:background="@android:color/holo_blue_bright"/>

    <Button android:id="@+id/button_0_1"
        android:layout_column="0"
        android:layout_row="1"
        android:layout_gravity="fill"
        android:layout_columnWeight=".5"
        android:layout_rowWeight=".5"
        android:background="@android:color/holo_green_dark"/>

    <Button android:id="@+id/button_1_1"
        android:layout_column="1"
        android:layout_row="1"
        android:layout_gravity="fill"
        android:layout_columnWeight=".5"
        android:layout_rowWeight=".5"
        android:background="@android:color/holo_orange_dark"/>

    <Button android:id="@+id/button_0_2"
        android:layout_column="0"
        android:layout_row="2"
        android:layout_gravity="fill"
        android:layout_columnWeight=".5"
        android:layout_rowWeight=".5"
        android:background="@android:color/holo_purple"/>

    <Button android:id="@+id/button_1_2"
        android:layout_column="1"
        android:layout_row="2"
        android:layout_gravity="fill"
        android:layout_columnWeight=".5"
        android:layout_rowWeight=".5"
        android:background="@android:color/darker_gray"/>

</GridLayout>

【讨论】:

  • 您好,请问有什么问题吗?我有两个 EditText,如果我想转移到另一个 EditText,这怎么可能?还有如果我必须执行“发送功能”?使用按钮怎么可能先生? PS:我已经有一个发送代码,我只需要使用按钮来执行它。
  • @pjforum 如果我对您的理解正确,您是在问如果您按下一系列按钮,它会将输入的文本从一个 EditText 移动/复制到另一个 EditText?
  • 它不会将输入的文本从一个编辑文本移动/复制到不同的编辑文本。我想要的只是移动到另一个editText并再次输入值/数据。
  • @pjforum,您所指的是所谓的焦点。在此处查看 Android 开发人员文档developer.android.com/reference/android/view/…。接下来,您需要检查该序列的 handleAlarmTrigger()。如果检测到,您可以在新的 EditText 上 requestFocus(),如果没有,您可以继续尝试将按钮按下解析为 Map 中的查找。
猜你喜欢
  • 1970-01-01
  • 2019-07-25
  • 2016-01-11
  • 1970-01-01
  • 2019-09-28
  • 1970-01-01
  • 1970-01-01
  • 2013-12-04
  • 1970-01-01
相关资源
最近更新 更多