Android:连续点击一到六个按钮将不同的结果串在一起

我决定开发一款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 Layout keyboard.xml

        

到目前为止我所做的代码没有按照我的意愿工作,所以我暂时将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); 

它是否正确?

我尝试使用类似于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中:

                       

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

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

要完成此操作,您只需要做大约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... } 

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

这基本上就是它的全部内容。

好吧,所以我已经给了它一个去,我相信这将帮助你走上你正在尝试的道路,因为我目前了解你的要求。 在我对课程的评论,我在做什么以及为什么这样做时,我一直很啰嗦。 我希望它有所帮助,而不是感觉像是在迎合。 这听起来可能你是Java和Android的新手,我觉得额外的解释可能有用。

我确信有错过的边缘情况和错误,但应该是一个良好的开端。

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 */ 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 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 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 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