2010-11-17 15 views
5

Sto tentando di sostituire MultiAutoCompleteTextView Elenco a discesa con ListView, che dovrebbe avere la stessa funzionalità dell'elenco a discesa, ciò significa che quando faccio clic su uno degli elementi deve essere aggiunto a MultiAutoCompleteTextView box, o così via, ma filtrando il ListView durante la digitazione.Come sostituire MultiAutoCompleteTextView elenco a discesa

Così mi si avvicinò con questo codice grezzo senza successo:

filterable_listview.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="fill_parent" android:layout_height="fill_parent" 
android:orientation="vertical"> 

<MultiAutoCompleteTextView 
    android:layout_height="wrap_content" android:layout_width="fill_parent" 
    android:hint="@string/To" android:id="@+id/search_box"></MultiAutoCompleteTextView> 

<ListView android:id="@android:id/list" android:layout_width="fill_parent" 
    android:layout_height="fill_parent" android:layout_weight="1"/> 

</LinearLayout> 

AutoCompleteActivity.java

protected void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
setContentView(R.layout.filterable_listview); 
manager = new ContactManager(); 
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, manager.getContacts()); 

searchEdit = (MultiAutoCompleteTextView) findViewById(R.id.search_box); 

searchEdit.addTextChangedListener(filterTextWatcher); 

searchEdit.setTokenizer(new SpaceTokenizer()); 

setListAdapter(adapter); 

getListView().setOnItemClickListener(
    new ListView.OnItemClickListener() { 
    public void onItemClick(AdapterView<?> parent, View view, 
          int position, long id) { 
        //Here is one issues 
    searchEdit.append(adapter.getItem(position)); 
    } 
}); 
} 

private TextWatcher filterTextWatcher = new TextWatcher() { 
     public void afterTextChanged(Editable s) { 
     } 

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

     public void onTextChanged(CharSequence s, int start, int before, int count) { 
      adapter.getFilter().filter(s); 
     } 

}; 

devo problemi principali:

1 Quando faccio clic su un elemento, viene aggiunto l'intero testo selezionato, So che il problema si basa su:

searchEdit.append (adapter.getItem (posizione));

ma, come posso fare spanning testo come il completamento automatico regolare lo fa?

2) Una volta che un elemento è stato selezionato, il prossimo ingresso non mostrano il suggerimento più (nonostante SpaceTonekizer)

Spero che la mia spiegazione era chiara.

Grazie in anticipo

risposta

6

Se qualcuno ha bisogno di fare qualcosa di simile avevo bisogno, ho fatto questo

private MultiAutoCompleteTextView searchEdit; 

private ArrayAdapter<String> adapter = null; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    adapter = new ArrayAdapter<String>(this, 
      android.R.layout.simple_dropdown_item_1line, manager 
        .getContacts()); 

    setListAdapter(adapter); 

    searchEdit = (MultiAutoCompleteTextView) findViewById(R.id.search_box); 

    searchEdit.addTextChangedListener(filterTextWatcher); 

    searchEdit.setTokenizer(new SpaceTokenizer()); 

    searchEdit.setAdapter(adapter); 

    searchEdit.setOnClickListener(new OnClickListener() { 

     public void onClick(View v) { 
      String t = ((TextView) v).getText().toString(); 
      String f = searchEdit.getText().toString(); 

      int s = searchEdit.getSelectionStart(); 
      int i = s; 

      while (i > 0 && f.charAt(i - 1) != ' ') { 
       i--; 
      } 

      adapter.getFilter().filter(t.substring(i, s)); 
     } 
    }); 

    okButton = (Button) findViewById(R.id.ok); 
    okButton.setOnClickListener(new OnClickListener() { 

     public void onClick(View v) { 
      Bundle stats = new Bundle(); 
      stats.putString("ConversationName", searchEdit.getText() 
        .toString()); 

      Intent i = new Intent(); 
      i.putExtras(stats); 
      setResult(RESULT_OK, i); 
      finish(); 
     } 
    }); 

    searchEdit.setOnKeyListener(new OnKeyListener() { 

     public boolean onKey(View v, int keyCode, KeyEvent event) { 
      if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT 
        || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT 
        || keyCode == KeyEvent.KEYCODE_DPAD_UP 
        || keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { 

       String t = ((TextView) v).getText().toString(); 
       String f = searchEdit.getText().toString(); 

       int s = searchEdit.getSelectionStart(); 
       int i = s; 

       while (i > 0 && f.charAt(i - 1) != ' ') { 
        i--; 
       } 

       adapter.getFilter().filter(t.substring(i, s)); 

       return false; 
      } 

      return false; 
     } 
    }); 

    getListView().setOnItemClickListener(
      new ListView.OnItemClickListener() { 
       public void onItemClick(AdapterView<?> parent, View view, 
         int position, long id) { 

        String t = adapter.getItem(position); 
        String f = searchEdit.getText().toString(); 

        int s = searchEdit.getSelectionStart(); 
        int i = s; 

        while (i > 0 && f.charAt(i - 1) != ' ') { 
         i--; 
        } 

        searchEdit.getText().insert(s, t.substring(s - i)); 
       } 
      }); 
} 


    @Override 
protected void onDestroy() { 
    super.onDestroy(); 
    searchEdit.removeTextChangedListener(filterTextWatcher); 
} 


private TextWatcher filterTextWatcher = new TextWatcher() { 

    public void afterTextChanged(Editable s) { 
     okButton.setEnabled(searchEdit.getText().toString().trim() 
       .length() > 0); 
    } 

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

    public void onTextChanged(CharSequence s, int start, int before, 
      int count) { 
     adapter.getFilter().filter(s); 
    } 

}; 



public class SpaceTokenizer implements Tokenizer { 

public int findTokenStart(CharSequence text, int cursor) { 
    int i = cursor; 

    while (i > 0 && text.charAt(i - 1) != ' ') { 
     i--; 
    } 
    while (i < cursor && text.charAt(i) == ' ') { 
     i++; 
    } 

    return i; 
} 

public int findTokenEnd(CharSequence text, int cursor) { 
    int i = cursor; 
    int len = text.length(); 

    while (i < len) { 
     if (text.charAt(i) == ' ') { 
      return i; 
     } else { 
      i++; 
     } 
    } 

    return len; 
} 

public CharSequence terminateToken(CharSequence text) { 
    int i = text.length(); 

    while (i > 0 && text.charAt(i - 1) == ' ') { 
     i--; 
    } 

    if (i > 0 && text.charAt(i - 1) == ' ') { 
     return text; 
    } else { 
     if (text instanceof Spanned) { 
      SpannableString sp = new SpannableString(text + " "); 
      TextUtils.copySpansFrom((Spanned) text, 0, text.length(), 
        Object.class, sp, 0); 
      return sp; 
     } else { 
      return text + " "; 
     } 
    } 
} 
} 

L'XML è simile al seguente:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="fill_parent" android:layout_height="fill_parent" 
android:orientation="vertical" 
android:drawingCacheQuality="high"> 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="fill_parent" android:layout_height="wrap_content" 
android:orientation="horizontal"> 


    <MultiAutoCompleteTextView 
     android:layout_marginLeft="1dip" 
     android:layout_marginTop="1dip" 
     android:layout_height="wrap_content" 
     android:layout_weight="1" 
     android:layout_width="fill_parent" 
     android:dropDownHeight="0px" 
     android:hint="@string/To" 
     android:id="@+id/search_box" 
     ></MultiAutoCompleteTextView> 



    <Button android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Ok" 
     android:id="@+id/ok" 
     android:enabled="false" 
     /> 


</LinearLayout>  
<ListView android:id="@android:id/list" android:layout_width="fill_parent" 
    android:layout_height="fill_parent" android:layout_weight="1" /> 

</LinearLayout> 

Spero che questo aiuto

+0

puoi dirmi okButton, dove lo metti? – pengwang

+1

scusate non ho aggiornato xml, controllo xml aggiunto. – vsm

+0

estendo ListActivity e invece manager.getContacts() ho usato una stringa [], ma ottengo 12-07 14: 29: 56.459: ERRORE/AndroidRuntime (423): java.lang.RuntimeException: impossibile avviare l'attività ComponentInfo { com.test.testMultiAutoCompleteTextView/com.test.testMultiAutoCompleteTextView.testMultiAutoCompleteTextView}: java.lang.NullPointerException – pengwang

Problemi correlati