2010-07-12 4 views
3

Я делаю логин Activity, который в основном имеет EditText и два Buttons. Это выглядит следующим образом:Редактор TextWatcher EditText

http://img249.imageshack.us/img249/9108/loginm.png http://img249.imageshack.us/img249/9108/loginm.png

EditText имеет TextWatcher, которая проверяет пользователя с AsyncTask, который попадает в WebService.

Код:

public class Login extends Activity { 

    private EditText mUserNameET; 
    private Drawable mCorrect; 
    private Drawable mIncorrect; 
    private ProgressBar mProgressBar; 
    private MyApp mApp; 

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

     mApp = (MyApp) getApplication(); 
     mUserNameET = (EditText) findViewById(R.id.user_name_et); 
     mUserNameET.addTextChangedListener(new LoginValidator()); 

     mCorrect = getResources().getDrawable(R.drawable.correct); 
     mIncorrect = getResources().getDrawable(R.drawable.incorrect); 
     mProgressBar = new ProgressBar(this); 
    } 

    private class LoginValidator implements TextWatcher { 

     private ValidateUserAsyncTask validator = new ValidateUserAsyncTask(); 

     @Override 
     public void afterTextChanged(Editable s) { 

      String value = s.toString(); 

      if (value.length() == 0) 
       return; 

      /* If it's running, cancel it. */ 
      /* Issue #2 */ 
      if (AsyncTask.Status.RUNNING == validator.getStatus()) { 
       validator.cancel(true); 
       validator = new ValidateUserAsyncTask(); 
      } else if (AsyncTask.Status.FINISHED == validator.getStatus()) { 
       validator = new ValidateUserAsyncTask(); 
      } 

      validator.execute(value); 
      /* Issue #1 */ 
      mUserNameET.setCompoundDrawables(null, null, mProgressBar.getProgressDrawable(), null); 
     } 

     @Override 
     public void beforeTextChanged(CharSequence s, int start, int count, 
       int after) { 
     } 

     @Override 
     public void onTextChanged(CharSequence s, int start, int before, 
       int count) { 
     } 
    } 

    class ValidateUserAsyncTask extends AsyncTask<String, Void, Boolean> { 

     @Override 
     protected void onPostExecute(Boolean result) { 
      super.onPostExecute(result); 

      if (result) { 
       mUserNameET.setCompoundDrawablesWithIntrinsicBounds(null, null, mCorrect, null); 
      } else { 
       mUserNameET.setCompoundDrawablesWithIntrinsicBounds(null, null, mIncorrect, null); 
      } 
     } 

     @Override 
     protected Boolean doInBackground(String... params) { 
      return mApp.validateUser(params[0]); 
     } 
    } 
} 

Мои вопросы:

Хотя AsyncTask работает Я хочу, чтобы показать ProgressBar внутри EditText. Я пытался сделать это с помощью:

mUserNameET.setCompoundDrawables(null, null, mProgressBar.getProgressDrawable(), null); 

, но он не работает.

И я также немного обеспокоен созданием новых экземпляров AsyncTask. Я утечка памяти?

+0

Как вы получаете 'EditText 'с кнопкой' x', чтобы стереть текст? – JuiCe

ответ

1

Хотя AsyncTask работает я хочу , чтобы показать ProgressBar внутри EditText

Попробуйте создать AnimationDrawable отображающая индикатор прогресса, и использовать его с setCompoundDrawables().

И я тоже немного беспокоит создания новых экземпляров AsyncTask. Я утечка памяти?

Ну, вы не можете повторно использовать AsyncTask экземпляров - они одноразовые. Имейте в виду, что AsyncTask использует пул потоков, и поэтому вы можете одновременно выполнять несколько AsyncTasks, что может быть или не быть тем, что вы имеете в виду. Я бы предпочел ждать, пока не будет набирать, скажем, 1 секунду, прежде чем делать материал веб-сервиса.

+0

Вы имеете в виду, что я должен заменить 'ProgressBar' на' AnimationDrawable'? Что бы вы использовали для реализации одной секунды ожидания, прежде чем попасть в WebService? – Macarse

+0

@Macarse: Я не знаю, как вы можете получить 'ProgressBar' * внутри *' EditText', и, конечно, не через 'setCompoundDrawables()', так как 'ProgressBar' - это виджет с' LevelListDrawable' на своем ядре , Для задержки я бы, вероятно, использовал 'postDelayed()' в довольно жестком цикле (например, 200 мс). При каждом изменении нажатия клавиши значение lastKeyTime с 'SystemClock.elapsedTime()'. «Runnable» для 'postDelayed()' видит, если 'lastKeyTime' было более 1 секунды - если да, то выполняйте веб-сервис; если нет, перепланировать «Runnable». Это не будет идеально, но это будет означать, что вы вызываете веб-службу 5 раз параллельно или что-то в этом роде. – CommonsWare

Смежные вопросы