2010-12-07 6 views
34

대화 상자를 표시하고 대화 상자가 닫힐 때까지 기다린 다음 대화 상자 내용에 따라 결과를 반환하는 메서드를 구현하고 싶습니다. 이것이 가능한가? Android : 대화 상자에서 사용자 입력을 기다리시겠습니까?

public String getUserInput() 
{ 
    //do something to show dialog 
    String input = //get input from dialog 
    return input; 
} 

내가 실제로 방법이있는 인터페이스를 구현하기 위해 노력하고 있습니다 "공공 문자열 getUserInput()", 반환 된 문자열은 대화 상자를 통해 검색해야하는 경우. 이것은 자바에서 쉽게 이루어지며, 안드로이드에서는 불가능한 것처럼 보입니까?

편집 : 백그라운드 스레드 (내가 AsynchTask에서 호출)에서 호출되어야 코멘트

getInput()의 요청에 따라 몇 가지 예제 코드를 게시. getInput()은 대화 상자를 표시하고 wait를 호출합니다. 대화 상자에서 확인 버튼을 누르면 대화 상자에서 사용자 변수를 멤버 변수로 설정하고 알림을 호출합니다. notify가 호출되면 getInput()이 계속 진행되고 멤버 변수가 반환됩니다.

/** 
* 
*/ 

import android.app.Activity; 
import android.content.Intent; 
import android.os.Bundle; 
import android.view.View; 
import android.view.WindowManager; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.EditText; 

/** 
* @author 
*/ 
public class TextEntryActivity extends Activity { 
    private EditText et; 

    /* 
    * (non-Javadoc) 
    * @see android.app.Activity#onCreate(android.os.Bundle) 
    */ 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.activity_text_entry); 
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND, 
       WindowManager.LayoutParams.FLAG_BLUR_BEHIND); 
     // title 
     try { 
      String s = getIntent().getExtras().getString("title"); 
      if (s.length() > 0) { 
       this.setTitle(s); 
      } 
     } catch (Exception e) { 
     } 
     // value 

     try { 
      et = ((EditText) findViewById(R.id.txtValue)); 
      et.setText(getIntent().getExtras().getString("value")); 
     } catch (Exception e) { 
     } 
     // button 
     ((Button) findViewById(R.id.btnDone)).setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       executeDone(); 
      } 
     }); 
    } 

    /* (non-Javadoc) 
    * @see android.app.Activity#onBackPressed() 
    */ 
    @Override 
    public void onBackPressed() { 
     executeDone(); 
     super.onBackPressed(); 
    } 

    /** 
    * 
    */ 
    private void executeDone() { 
     Intent resultIntent = new Intent(); 
     resultIntent.putExtra("value", TextEntryActivity.this.et.getText().toString()); 
     setResult(Activity.RESULT_OK, resultIntent); 
     finish(); 
    } 


} 

출시 할 것 같은

String m_Input; 

public synchronized String getInput() 
{ 
    runOnUiThread(new Runnable() 
    { 
     @Override 
     public void run() 
     { 
      AlertDialog.Builder alert = new AlertDialog.Builder(context); 
      //customize alert dialog to allow desired input 
      alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() { 
      public void onClick(DialogInterface dialog, int whichButton) 
      { 
          m_Input = alert.getCustomInput(); 
          notify(); 
      } 
     }); 
     alert.show(); 
     } 
    }); 

    try 
    { 
     wait(); 
    } 
    catch (InterruptedException e) 
    { 
    } 

    return m_Input; 
} 
+5

UI 스레드에서 호출되는 메소드에서 사용자를 기다릴 수 없습니다. 따라서 프로그램 흐름의 이벤트 중심 모델로 전환하거나 배경 메서드가 무엇을 기다리고 있는지 사용자 액션 업데이트에 대한 응답으로 UI 스레드에서 onWhatever() 메서드가 호출 될 때까지 기다릴 수있는 백그라운드 스레드에서이 메서드를 호출해야합니다. –

+0

나는 정말로 이해하지 못한다. 배경 스레드에서 이것을 어떻게 호출 할 것인가를 설명하고, onWhatever() 내 문자열을 반환 하겠는가? – ab11

+0

3 (?) 이상 UI 스레드를 차단하려는 경우 응용 프로그램을 닫을 것인지 묻는 ANR 대화 팝업이 나타나면 3 초가 걸렸을 것으로 생각됩니다. Android의 UI 스레드에서 차단 항목을 실행하지 마십시오. –

답변

11

피드백을 보내 주셔서 감사합니다. 백그라운드 스레드를 wait() 및 알림). 나는 이것이 주어진 패러다임에 대한 가장 좋은 아이디어는 아니지만, 내가 함께 일하는 도서관을 준수해야한다고 생각한다.

+1

일부 코드를 게시 할 수 있습니까? – Caner

+2

일부 코드 – ab11

+0

덕분에 내 대답을 업데이 트 많은 !!! – Caner

1

뭔가는 다음과 같습니다

public void launchPreferedNameEdit() { 
    Intent foo = new Intent(this, TextEntryActivity.class); 
    foo.putExtra("value", objItem.getPreferedNickname()); 
    this.startActivityForResult(foo, EDIT_PREFERED_NAME); 
} 

당신은 어떻게이게 가능

protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    switch (requestCode) { 
     case EDIT_PREFERED_NAME: 
      try { 
       String value = data.getStringExtra("value"); 
       if (value != null && value.length() > 0) { 

       } 
      } catch (Exception e) { 
      } 
      break; 
     default: 
      break; 
    } 
} 
+0

내가 틀릴 수도 있지만 설명하는 문제가 전혀 작동하지 않을 것이라고 생각합니다. ? 문제를 명확히하기 위해 제 질문을 수정했습니다. – ab11

+0

설명했듯이 불가능합니다. 그러나 내 게시물은 입력 텍스트가있는 활동으로이 작업을 수행하는 방법을 제공합니다. – Pentium10

27

를 사용하여 결과를 얻을?

아니요. Android에는 차단 UI 모델이 없습니다. 모든 것이 비동기식입니다.

질문 자체에 대한 귀하의 의견의 일부에 대응 UPDATE

, 당신은 백그라운드 스레드에서 UI를 표시 할 수 없습니다. 이 답변에서 쓴 것처럼 Android에는 차단 UI 모델이 없습니다. this sample project과 같이 대화 상자가 허용 될 때 실행하려는 대화 상자의 단추 핸들러에 코드를 입력하기 만하면됩니다.

+0

이 답변이 다운 투표 한 특별한 이유가 있습니까? –

+2

어쩌면 누군가가 듣고 싶지 않았던 대답일까요? 나는 그것이 두 번 일어났습니다. – blindstuff

+2

백그라운드 스레드에서 직접 UI를 표시 할 수는 없지만 백그라운드 스레드에서 UI 스레드가 표시되도록 요청할 수 있습니다. –

10

이 작업을 수행하는 올바른 방법은 이벤트 구동 프로그램 모델입니다. 즉 "전화하지 마시고 연락 드리겠습니다".

간단한 콘솔 모드 프로그래밍에서 코드는 사용자가 값을 얻기 전까지는 반환하지 않는 차단 입력 기능을 호출하는 경향이 있습니다.

많은 GUI 프로그래밍 환경이 다르게 작동합니다. 코드는 일반적으로 실행되지 않지만 잠재적 인 관심사가 발생할 때 운영 체제/창 관리자가 대신 호출합니다. 이에 대한 응답으로 무언가를하고 신속하게 반환합니다. 그렇지 않은 경우 운영 체제가 반환 할 때까지 연락 할 수있는 방법이 없기 때문에 다른 것에 대한 알림을받을 수 없습니다. (win32와 비교하면 메시지 루프가 Android에서 구현 된 것처럼 보이며 메시지 루프가 이벤트와 함께 호출하는 나머지 코드 만 작성합니다. 즉각적으로 반환하지 않으면 메시지 루프가 중단됩니다)

결과적으로 프로그램 흐름의 개념을 재고해야합니다. 할 일 목록을 간단한 일련의 명령문으로 작성하는 대신, 서로에 대해 그리고 입력에 의존하는 일련의 행동으로 생각하십시오. 상태 변수에서 현재 수행중인 작업을 기억하십시오.사용자 입력과 같은 이벤트가 발생하면 해당 이벤트로 다음 단계로 넘어갈 수 있는지 확인하고, 그렇다면 상태 변수를 업데이트 한 후 OS로 즉시 돌아가서 다음 단계를 수신 할 수있게하십시오. 행사. 이벤트가 당신이 필요로하지 않은 것이라면, 당신의 상태를 업데이트하지 않고 돌아 오십시오.

이 모델이 작동하지 않으면 차단 입력을 사용하여 콘솔 모드 응용 프로그램처럼 실행되는 프로그램 논리의 백그라운드 스레드를 작성하십시오. 그러나 입력 함수는 실제로 입력이 가능하다는 것을 알려주는 깃발이나 어떤 것을 기다릴 것입니다. 그런 다음 Android에서 이벤트를 전달하는 UI 스레드에서 플래그를 업데이트하고 즉시 반환합니다. 백그라운드 스레드는 데이터가 제공되었음을 나타 내기 위해 플래그가 변경된 것을보고 실행을 계속합니다. (안드로이드 터미널 에뮬레이터와 같은 것은 배경 구성 요소가 실제로는 다른 프로세스 인 콘솔 모드 리눅스이고, 파이프로부터 I/O를 차단하여 입력을 얻습니다. 자바 구성 요소는 안드로이드 UI 이벤트를 받아들입니다. 문자를 stdin 파이프에 넣고 표준 출력 파이프에서 꺼내서 화면에 표시합니다.)

0

사례 : 환경 변경 후 리스너 이벤트가 발생하여 데이터를 처리 할 준비가되었으며 사용자가 쿼리 한 문자열을 추가해야했습니다. 옵션 메뉴가 열려있는 동안 경고 대화 상자를 팝업하는 것은 가능하지 않습니다 ... 그래서 기다려야했습니다. 워크 플로우의 다음 액티비티로 반 객체를 던지고 onResume()을 설정하여 placeholder가 null인지 확인합니다.이 경우 대화 상자를 팝업하고 객체를 완료했습니다 * "대화 상자의 버튼 처리기에서 "*.

위의 정답에 투표 할 수 없지만 다른 사람을이 시간에 맞춰 저장하고 덜 정확한 해결책을 찾아 내고 싶습니다. 대화 상자가 있습니다.

0

처음 상태 사용자 입력이 필요한 경우 "사용자 입력 필요"또는 기타 항목을 표시하도록 플래그를 설정할 수있는 상태 시스템이라는 용어로 생각할 수 있습니다. 그런 다음 이벤트를 처리 할 때 해당 플래그를 확인하고 설정된 경우 이벤트에 대한 유일한 조치로 대화 상자를 시작하고 플래그를 설정 해제하십시오. 그런 다음 사용자 입력을 처리 한 후 대화 상자 이벤트 핸들러에서 대화 상자가 필요하지 않은 경우 대개 해당 코드를 호출 할 수 있습니다.

0

지금까지 제공 한 모든 솔루션을 이해하는 데 어려움을 겪었습니다.

그래서 같은 실행 가능한 상기 사용자 입력 OK'ed 후에 수행 될 예정 코드 그게 랩 :

Runnable rOpenFile = new Runnable() { 
     @Override 
     public void run() { 
      .... code to perform 
     } 
    } 

를이어서 바로 그 아래에 I가 사용자에게 실행 가능한 함수의 이름을 전달할 대화 상자 방법.

userInput("Open File", rOpenFile); 

userInput 메서드는 위에서 설명한 alertDialog 빌더를 기반으로합니다. 사용자 입력이 Ok'ed되면 의도 된 실행 파일이 시작됩니다.

private void userInput(String sTitle, final Runnable func) { 
    AlertDialog.Builder aBuilder = new AlertDialog.Builder(this); 

    aBuilder.setTitle(sTitle); 
    final EditText input = new EditText(this); 
    input.setInputType(InputType.TYPE_CLASS_TEXT); 
    aBuilder.setView(input); 

    bDialogDone = false; 

    aBuilder.setPositiveButton("Ok", new DialogInterface.OnClickListener() { 
     @Override 
     public void onClick(DialogInterface dialog, int which) { 
      final String sText = input.getText().toString(); 
      sEingabe = sText; 
      func.run(); 
     } 
    }); 
    aBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
     @Override 
     public void onClick(DialogInterface dialog, int which) { 
      dialog.cancel(); 
      sEingabe = ""; 
     } 
    }); 

    aBuilder.show(); 
} 
관련 문제