2012-02-04 48 views
14

Tôi đã googling ass của tôi cố gắng tìm một ai đó có cùng một vấn đề như tôi, mà không có may mắn. Vì vậy, đây là vấn đề của tôi:Geocoder tự động hoàn thành trong android

Tôi đang cố triển khai đề xuất địa chỉ tự động hoàn tất khi người dùng nhập tên địa điểm bằng cách sử dụng trình mã hóa địa lý trong Android. Tôi muốn điều này hoạt động giống như phiên bản javascript bằng cách sử dụng một hộp đựng.

Tôi đang sử dụng bố cục với AutoCompleteTextView và một mảng để tự động cập nhật danh sách đề xuất khi người dùng nhập. Tôi đã thêm một sự chậm trễ 500ms từ khi sự kiện onTextChanged() nhận được trước khi một cuộc gọi đến geocoder.getFromLocationName được gọi bằng cách sử dụng một Handler. Nếu người dùng nhập thêm thư trong vòng 500 mili giây, sự kiện cuối cùng sẽ bị hủy. Vấn đề tôi gặp phải là các đề xuất hầu như không bao giờ hiển thị trong giao diện người dùng dưới dạng các lựa chọn trong menu thả xuống. Tôi nhận được gợi ý địa chỉ, nhưng khi tôi thêm chúng vào bộ điều hợp gắn liền với autocomplatetextview chúng đơn giản sẽ không hiển thị.

Tôi đang chạy tính năng này trên trình mô phỏng sử dụng API cấp 7, kèm theo bao gồm google apis.

Bây giờ một số mã nguồn để hỗ trợ bạn: Cách bố trí:

<LinearLayout android:id="@+id/searchInputLayout" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:padding="6dip" 
    android:orientation="vertical"> 
    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="@string/searchMessage" /> 
    <EditText android:id="@+id/freetextInput" 
     android:hint="@string/searchFreetextLabel" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:background="@android:drawable/editbox_background" /> 
    <CheckBox android:id="@+id/includeVincinityCheckbox" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="@string/includeVincinityLabel" 
     android:checked="true" 
     android:onClick="includeVincinityClick" /> 
    <AutoCompleteTextView android:id="@+id/locationInput" 
     android:hint="@string/locationInputHint" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" /> 
    <Button android:id="@+id/searchButton" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="@string/searchBtnLabel" 
     android:onClick="searchBtnClicked" /> 
    </LinearLayout> 

Mã nguồn của hoạt động của tôi (mã tôi đã bỏ qua không liên quan):

public class SearchLocationTabActivity extends Activity implements TextWatcher, OnItemSelectedListener { 

private static final int MESSAGE_TEXT_CHANGED = 0; 
private static final int AUTOCOMPLETE_DELAY = 500; 
private static final int THRESHOLD = 3; 
private String latitude, longitude; 
private List<Address> autoCompleteSuggestionAddresses; 
private ArrayAdapter<String> autoCompleteAdapter; 
private Handler messageHandler; 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle icicle) { 
    super.onCreate(icicle); 
    setContentView(R.layout.search); 
    setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL); 

    messageHandler = new MyMessageHandler(this, this); 
    autoCompleteAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, new ArrayList<String>()); 
    autoCompleteAdapter.setNotifyOnChange(false); 
    AutoCompleteTextView locationinput = (AutoCompleteTextView) findViewById(R.id.locationInput); 
    locationinput.addTextChangedListener(this); 
    locationinput.setOnItemSelectedListener(this); 
    locationinput.setThreshold(THRESHOLD); 
    locationinput.setAdapter(autoCompleteAdapter); 
} 

@Override 
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { 
    messageHandler.removeMessages(MESSAGE_TEXT_CHANGED); 
} 

@Override 
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { 
String value = arg0.toString(); 
if (!"".equals(value) && value.length() >= THRESHOLD) { 
    Message msg = Message.obtain(messageHandler, MESSAGE_TEXT_CHANGED, arg0.toString()); 
    messageHandler.sendMessageDelayed(msg, AUTOCOMPLETE_DELAY); 
} else { 
    autoCompleteAdapter.clear(); 
} 
} 

@Override 
public void afterTextChanged(Editable arg0) { 
} 

@Override 
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) { 
    if (arg2 < autoCompleteSuggestionAddresses.size()) { 
     Address selected = autoCompleteSuggestionAddresses.get(arg2); 
     latitude = Double.toString(selected.getLatitude()); 
     longitude = Double.toString(selected.getLongitude()); 
    } 
} 

private void notifyResult(List<Address> suggestions) { 
    latitude = longitude = null; 
    autoCompleteAdapter.clear(); 
    for (Address a : autoCompleteSuggestionAddresses) { 
     autoCompleteAdapter.add(a.toString());//TODO: figure out a nice way to display this address in list 
    } 
    autoCompleteAdapter.notifyDataSetChanged(); 
} 

@Override 
public void onNothingSelected(AdapterView<?> arg0) { 
    latitude = longitude = null; 
} 

private class MyMessageHandler extends Handler { 

    private Context context; 
    private AsyncTaskSubscriber subscriber; 

    public MyMessageHandler(Context context, AsyncTaskSubscriber subscriber) { 
     this.context = context; 
     this.subscriber = subscriber; 
    } 

    @Override 
    public void handleMessage(Message msg) { 
     if (msg.what == MESSAGE_TEXT_CHANGED) { 
      String enteredText = (String) msg.obj; 

      try { 
       autoCompleteSuggestionAddresses = new Geocoder(context).getFromLocationName(enteredText, 10); 

       notifyResult(response); 
      } catch (IOException ex) { 
       Log.e(GeoCoderAsyncTask.class.getName(), "Failed to get autocomplete suggestions", ex); 
      } 
     } 
    } 
} 
} 

Bất kỳ sự giúp đỡ nhiều đánh giá cao!

+0

Tôi đang gặp sự cố tương tự. Điều gì thực sự là giải pháp của bạn? – jayearn

+0

tôi đã xóa bộ lọc trên chế độ xem tự động hoàn thành. xem giải pháp giải thích dưới đây;) –

Trả lời

3

Đối với những người không quản lý để xóa bộ lọc, dưới đây là những gì tôi đã thực hiện (trong số các sửa đổi nhỏ khác nhưng tôi không nghĩ rằng chúng có tác động đến phần lọc). Cũng lưu ý rằng đối với một nhấp chuột vào một trong các mục được phát hiện, you need to add an OnItemClickListener.

autoCompleteAdapter = new ArrayAdapterNoFilter(this, android.R.layout.simple_dropdown_item_1line); 

đâu ArrayAdapterNoFilter được lấy cảm hứng từ this other answer:

public class ArrayAdapterNoFilter extends ArrayAdapter<String> { 

    public ArrayAdapterNoFilter(Context context, int textViewResourceId) { 
     super(context, textViewResourceId); 
    } 

    private static final NoFilter NO_FILTER = new NoFilter(); 

    /** 
    * Override ArrayAdapter.getFilter() to return our own filtering. 
    */ 
    @Override 
    public Filter getFilter() { 
     return NO_FILTER; 
    } 

    /** 
    * Class which does not perform any filtering. Filtering is already done by 
    * the web service when asking for the list, so there is no need to do any 
    * more as well. This way, ArrayAdapter.mOriginalValues is not used when 
    * calling e.g. ArrayAdapter.add(), but instead ArrayAdapter.mObjects is 
    * updated directly and methods like getCount() return the expected result. 
    */ 
    private static class NoFilter extends Filter { 
     protected FilterResults performFiltering(CharSequence prefix) { 
      return new FilterResults(); 
     } 

     protected void publishResults(CharSequence constraint, FilterResults results) { 
      // Do nothing 
     } 
    } 
} 
+0

thanx cho hỗ trợ !! nó đã cứu rất nhiều thời gian của tôi !! – Pankaj

1

ok, ứng dụng này có giải pháp thực sự đơn giản. Các kết quả không hiển thị mọi lúc vì cơ chế lọc trong thành phần AutoCompleteTExtView. Bởi vì tất cả các kết quả từ trình mã hóa địa lý không nhất thiết phải chứa chuỗi được nhập, nó không hiển thị các kết quả đó.

+2

@ Runar: Bạn có thể vui lòng chia sẻ như thế nào bạn loại bỏ các lọc trong autocompletetextview như không có phương pháp tiếp xúc của nó để làm như vậy. Ngoài ra nếu bạn có thể là loại, đủ để chia sẻ AsyncTaskSubscriber, nó là lớp tùy chỉnh của bạn? – Nohsib

+0

@Nohsib Nếu bạn vẫn cần nó, tôi đã thêm một câu trả lời để cho biết cách xóa bộ lọc. – assylias

0

này thực sự hoạt động cho mã mã hóa địa lý của tôi. Tôi có thể thêm trình soạn thảo văn bản vào chế độ xem văn bản tự động hoàn tất, sau đó nhận văn bản và chạy tác vụ không đồng bộ sẽ nhận danh sách địa chỉ từ lớp googles GeoCode. Sử dụng bộ lọc mảng không có bộ lọc ở trên làm cho nó hiển thị các địa chỉ khi tôi nhập các chữ cái chính xác.

Cảm ơn!

+0

Im đề cập đến bộ lọc mảng không có bộ lọc – Danuofr

Các vấn đề liên quan