Ввод работает только один раз в Android

#java #android #input

#java #Android #ввод

Вопрос:

Подобный вопрос (ID 1606993) был опубликован, но на самом деле не ответил на мой, так что вот:

В приложении для Android, которое я создаю, пользователь должен вводить цифры с клавиатуры, чтобы приложение продолжало работу. Когда они закончат вводить свои номера, они могут либо нажать клавишу возврата, либо главную кнопку. Проблема в том, что он работает только один раз.

Вот мой метод прослушивания:

 public boolean onKeyDown(int key, KeyEvent event)//Listens for key events
{
    if(key==KeyEvent.KEYCODE_0)
        add(0);
    else if(key==KeyEvent.KEYCODE_1)
        add(1);
    else if(key==KeyEvent.KEYCODE_2)
        add(2);
    else if(key==KeyEvent.KEYCODE_3)
        add(3);
    else if(key==KeyEvent.KEYCODE_4)
        add(4);
    else if(key==KeyEvent.KEYCODE_5)
        add(5);
    else if(key==KeyEvent.KEYCODE_6)
        add(6);
    else if(key==KeyEvent.KEYCODE_7)
        add(7);
    else if(key==KeyEvent.KEYCODE_8)
        add(8);
    else if(key==KeyEvent.KEYCODE_9)
        add(9);
    else if(key==KeyEvent.KEYCODE_ENTER)
        setNum();
    else if(key==KeyEvent.KEYCODE_DPAD_CENTER)
        setNum();
    return true;
}
  

Метод add (int numb) добавляет num к текстовому полю, которое занимает экран, это не вызывает никаких проблем.

Вот setNum() :

 protected void setNum()//Sets the number and tells the Runner it is set.
{
    if(ray.size()==1)
        num=ray.get(0);
    else if(ray.size()==0)
        num=0;
    else
        num=(ray.get(0)*10) ray.get(1);
    ray=new ArrayList<Integer>();//or ray.clear(), I've tried both
    ready=true;
}
  

ArryayList ray — это место, где хранятся числа. Вычисление работает нормально.
Int num — это число, которое использует код. Логическое значение ready присутствует, потому что в классе runner есть цикл while, ожидающий, когда ready примет значение true, чтобы продолжить код.

 while(!a.ready)
{
    for(int x=0;x<100;x  );
}
  

Есть идеи?

Редактировать: Вот метод в Runner, который вызывается:

 while(!go)
    {
        addText("It is White's move");
        addText("Possible pieces to move");
        for(int x=0;x<b.getWhite().getPiecesWithMoves(b).size();x  )//Loop to print White's pieces that can move
        {
            addText("" (x 1) ") " b.getWhite().getPiecesWithMoves(b).get(x));
        }   
        got=false;
        p=0;
        while(!got)//Loop to enter number
        {
            addText("Input the number of the piece you want to move");
            while(!a.ready)
            {
                for(int x=0;x<100;x  );
            }
            p=a.num-1;
            if(p<b.getWhite().getPiecesWithMoves(b).size()amp;amp;p>=0)//Checks to make sure that p is valid
                got=true;
            a.num=0;
            a.ready=false;
        }
        gl=b.getWhite().getPiecesWithMoves(b).get(p).getLocation();//Makes a location that is where the piece currently is
        addText("Possible moves");
        for(int x=0;x<b.getPiece(gl).getMoves(b).size();x  )//Loop to print where the piece can go
        {
            addText("" (x 1) ") " b.genL(b.getPiece(gl).getMoves(b).get(x)));
        }
        got=false;//reset
        while(!got)//Loop to enter number
        {
            addText("Input the number of one of these moves.");
            addText("If you wish to change, enter 0.");
            while(!a.ready)
            {
                for(int x=0;x<100;x  );
            }
            p=a.num-1;
            if(p==-1)
                got=true;
            else if(p<b.getPiece(gl).getMoves(b).size()amp;amp;p>=0)//Checks to make sure that p is valid
            {
                got=true;
                go=true;
            }
            a.num=0;
            a.ready=false;
        }
    }
    gk=b.getPiece(gl).getMoves(b).get(p);//The location that the piece is going to
    b.move(gk, b.getPiece(gl),gk.isTaken(),gk.isCastle());//Moves the piece
  

Комментарии:

1. в чем смысл цикла запуска? Не будет ли это просто существовать как бесконечный цикл? Или это в асинхронном потоке? Лучшим способом обработки подобных событий было бы использование широковещательного приемника

2. Какая часть не работает во второй раз? Ошибка? Исключение? Неправильный номер? Нет числа? Бесконечный цикл? Демоны?

3. @John: Я попытался приостановить его, чтобы дождаться сообщения от основного действия, но это начало вызывать прерывающиеся исключения. Класс Runner отправляет сообщения в основной класс, если это вообще помогает.

4. попробуйте отладить функцию setNum, чтобы увидеть, что внутри ray. Просто запустите приложение в режиме отладки на своем устройстве с точкой останова, установленной в верхней части инструкции if

5. Столько, сколько необходимо. Мы здесь, чтобы помочь.

Ответ №1:

 public class MyView {
  int num;
  int currentState = 1; //much, much more pretty if you'd use Enum, 
                        //but I'll keep it simple now.

  public boolean onKeyDown(int key, KeyEvent event) {
    //no changes here
  }

  protected void setNum(){
    if(ray.size()==1)
        num=ray.get(0);
    else if(ray.size()==0)
        num=0;
    else
        num=(ray.get(0)*10) ray.get(1);
    ray=new ArrayList<Integer>();
    if (currentState == 1) //(TODO:should really use Enum here....)
       part1();
    else if (currentState == 2)
       part2();
    else if (...
  }

  void part1() {
    addText("It is White's move");
    addText("Possible pieces to move");
    for(int x=0;x<b.getWhite().getPiecesWithMoves(b).size();x  )
    {
      addText("" (x 1) ") " b.getWhite().getPiecesWithMoves(b).get(x));
    }

    addText("Input the number of the piece you want to move");
    currentState = 2;//now we do nothing, we wait untill user finishes input
  }
  void part2()
  {//will be called after part1 finishes and a number has been entered
    p=a.num-1;
    if(p<b.getWhite().getPiecesWithMoves(b).size()amp;amp;p>=0) {
      gl=b.getWhite().getPiecesWithMoves(b).get(p).getLocation();
      addText("Possible moves");
      //and more code
      //Need input? stop and set next entry point
      currentState = 3;//continue to part 3
    }
    else
    {
      addText("Input the number of the piece you want to move");
      currentState = 2;//oops, stay at part2, we didn't get a good number!
    }
  }

}
  

Идея состоит в том, чтобы ничего не делать, когда пользователь должен вводить. В этот момент не выполняется код, например, после завершения part1(). Когда пользователь завершает ввод и нажимает клавишу, вы должны убедиться, что выполняется правильный код, после чего вызывается часть 2. А затем просто прекратите выполнение кода, когда вам снова понадобится ввод.

Удачи!

Комментарии:

1. Спасибо, Иштар, это имеет гораздо больше смысла, чем то, что я делал!