Java 安卓:连续[一个接一个]点击一到六个按钮,将不同的结果串在一起

Java 安卓:连续[一个接一个]点击一到六个按钮,将不同的结果串在一起,java,android,eclipse,function,switch-statement,Java,Android,Eclipse,Function,Switch Statement,我决定开发一款Android应用程序,它使用的技术与我以前见过的应用程序非常相似。我想将多个按钮组合在一起,以等同于不同的文本结果 我正在制作的这款本地盲文应用程序有6个不同的按钮,我希望每一个独特的组合都能为我带来不同的字母。例如:我想点击按钮1,给我简单的字母“A”。然后连续点击按钮1和按钮2,我会看到字母“C”。我希望这6个按钮的每一个不同的按钮组合给我带来一封单独的信 能否请精通Java的人解释一下这是如何做到的?我如何在多个按钮按下时串入字符串以获得不同的结果?谢谢你的帮助 我的j

我决定开发一款Android应用程序,它使用的技术与我以前见过的应用程序非常相似。我想将多个按钮组合在一起,以等同于不同的文本结果

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

能否请精通Java的人解释一下这是如何做到的?我如何在多个按钮按下时串入字符串以获得不同的结果?谢谢你的帮助

我的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>

这是正确的吗?

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

要完成此任务,您只需做三件事: 1.收集你的输入数据(点击按钮),你几乎已经完成了。 2.知道什么时候该处理输入。 3.将输入处理为正确的输出

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

    输入[R.id.block1、R.id.block2、R.id.block2]

  • 知道什么时候该处理。
    在按钮按下处理程序中,添加一个倒计时计时器。每次按下按钮,取消计时器并启动一个新的计时器

    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()时,您知道用户已停止按按钮

  • 处理输入。
    为您的成果创建关键/价值对

    map = {[R.id.block1],'A',
        [R.id.block1, R.id.block2],'B',
        [R.id.block1, R.id.block2, R.id.block2],'C',
      etc...
    }  
    
    搜索用户的输入并获取您的值


  • 这基本上就是它的全部。

    好吧,我已经试过了,我相信这将帮助您走上您正在尝试的道路,因为我目前了解您的需求。我对这门课的评论、我在做什么以及为什么要这样做都非常冗长。我希望这是有益的,而不是像迎合。听起来你可能对Java和Android相当陌生,我觉得补充的解释可能有用

    我确信有一些边缘案例和bug已经被遗漏,但这应该是一个好的开始

    Android活动类--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.os.Bundle;
    导入android.os.Handler;
    导入android.support.v7.app.AppActivity;
    导入android.view.view;
    导入android.widget.Button;
    导入android.widget.EditText;
    导入java.util.HashMap;
    导入java.util.LinkedList;
    导入java.util.Map;
    导入java.util.Queue;
    公共类MainActivity扩展AppCompatActivity实现View.OnClickListener{
    /**
    *如果希望在logcat中查看调试/错误信息,则标记通常用于日志类
    */
    公共静态最终字符串标记=MainActivity.class.getSimpleName();
    /**
    *尝试将按钮按下解析为输入之前的延迟常量
    */
    公共静态最终整数输入\u句柄\u延迟\u MS=500;
    /**
    *按钮具有命名约定按钮
    */
    私人按钮mButton00;
    专用按钮mButton10;
    私人按钮mButton01;
    专用按钮mButton11;
    专用按钮mButton02;
    专用按钮mButton12;
    /**
    *我们将在其中存储由按钮按下生成的输入
    */
    私有EditText-mEditText;
    /**
    *其中将发生基于ID的查找,并将其转换为字符
    */
    私有静态映射mLookupMap;
    /**
    *我不能100%确定是否需要这样做,但因为我们将尝试写入mInputQueue,
    *从中读取,我创建了一个锁
    */
    私有静态最终对象mLock=新对象();
    /**
    *我们将在其中存储由按钮按下生成的输入
    */
    private Queue mInputQueue=new LinkedList();
    /**
    *Android处理程序类来帮助计时器,并执行我们的runnable来处理
    *按钮分辨率
    */
    私有处理程序mHandler=新处理程序();
    /**
    *Runnable使应用程序检查是否存在有效输入
    */
    私有可运行的mhandleinputrunable;
    @凌驾
    创建时受保护的void(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(右布局按钮);
    //方法调用以初始化查找映射
    初始化lookup();
    //从布局中获取我们需要使用的所有参考
    mEditText=(EditText)findViewById(R.id.edit_text);
    mButton00=(按钮)findViewById(R.id.Button\u 0\u 0);
    mButton10=(按钮)findViewById(R.id.Button\u 1\u 0);
    mButton01=(按钮)findViewById(R.id.Button\u 0\u 1);
    mButton11=(按钮)findViewById(R.id.Button\u 1\u 1);
    mButton02=(按钮)findViewById(R.id.Button\u 0\u 2);
    mButton12=(按钮)findViewById(R.id.Button\u 1\u 2);
    //在上面,活动实现OnClickListener接口,将活动设置为handle
    //所有按钮的点击
    mButton00.setOnClickListener(此);
    mButton10.setOnClickListener(此);
    mButton01.setOnClickListener(此);
    mButton11.setOnClickListener(此);
    mButton02.setOnClickListener(此);
    mButton12.setOnClickListener(此);
    //初始化Runnable,以便在得到“勾号”时执行我们需要它执行的操作
    mhandleinputrunable=newrunnable(){
    @凌驾
    公开募捐{
    手拉式起重器();
    }
    };
    }
    @凌驾
    公共void onClick(视图v){
    if(null!=mInputQueue){
    已同步(mLock){
    add(v.getId());
    }
    }
    resetHandler();
    }
    /**
    *帮助器方法来初始化映射。很抱歉按钮的顺序
    *印刷品。它们有点零散,没有真正的韵律或理由。
    */
    private void initializeLookup(){
    我
    
    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();
            }
        }
    }
    }
    
    <?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>
    
    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;
    }}
    
    <?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>