AutoCompleteTextView with dynamic data

Put problem concerning Views, Layouts and other XML-Resources (like AndroidManifest) here.

AutoCompleteTextView with dynamic data

Postby timothyjc » Fri Oct 23, 2009 9:45 pm

My first post :)

My problem is that I have an AutoCompleteTextView which I want to change dynamically. The String[] is based on a call to a webservice which is triggered every time the user presses a key. I dont want the user to wait for the webservice call, so I use an AsyncTask.

Unfortunately this solution doenst work, because the adapter data being displayed is from the previous web call, not the latest.

Surely there is an easier way?!?

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. public class SearchByArtistAct extends Activity implements OnClickListener {
  2.  
  3.  
  4.  
  5.         ImageManager mImageManager;
  6.  
  7.         ArrayAdapter<String> adapter;
  8.  
  9.         private static final String TAG = SearchByArtistAct.class.getSimpleName();
  10.  
  11.  
  12.  
  13.         @Override
  14.  
  15.         public void onCreate(Bundle savedInstanceState) {
  16.  
  17.                 super.onCreate(savedInstanceState);
  18.  
  19.                 setContentView(R.layout.search_by_artist);
  20.  
  21.                 Button searchButton = (Button) findViewById(R.id.artist_search_button);
  22.  
  23.                 searchButton.setOnClickListener(this);
  24.  
  25.                 mImageManager = ImageManager.getInstance(this);
  26.  
  27.  
  28.  
  29.                 AutoCompleteTextView actv = (AutoCompleteTextView) findViewById(R.id.artist_search_text_edit);
  30.  
  31.                 actv.addTextChangedListener(textWatcher);
  32.  
  33.                 adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, new String[] {});
  34.  
  35.                 actv.setAdapter(adapter);
  36.  
  37.  
  38.  
  39.                 State.events = new ArrayList<Event>();
  40.  
  41.                 State.latitude = 0;
  42.  
  43.                 State.longitude = 0;
  44.  
  45.         }
  46.  
  47.  
  48.  
  49.         private void updateTextAdapter(String[] data) {
  50.  
  51.                 adapter.clear();
  52.  
  53.                 for (int i = 0; i < data.length; i++) {
  54.  
  55.                         String artistName = data[i];
  56.  
  57.                         adapter.add(artistName);
  58.  
  59.                         adapter.notifyDataSetChanged();
  60.  
  61.                 }
  62.  
  63.         }
  64.  
  65.  
  66.  
  67.         private String[] getArtistStrings(String searchName) {
  68.  
  69.                 try {
  70.  
  71.                         List<String> artistNames = ArtistNamesSearch.execute(searchName);
  72.  
  73.                         for (String artistName : artistNames) {
  74.  
  75.                                 Log.i(TAG, artistName);
  76.  
  77.                         }
  78.  
  79.                         return artistNames.toArray(new String[artistNames.size()]);
  80.  
  81.                 } catch (ClientException e) {
  82.  
  83.                         Log.e(TAG, "Unable to get artist names", e);
  84.  
  85.                         return new String[] {};
  86.  
  87.                 }
  88.  
  89.         }
  90.  
  91.  
  92.  
  93.         private String getInput() {
  94.  
  95.                 EditText artistInput = (EditText) findViewById(R.id.artist_search_text_edit);
  96.  
  97.                 String artistSearchString = artistInput.getText().toString();
  98.  
  99.                 artistSearchString = Helper.modifyString(artistSearchString);
  100.  
  101.                 return artistSearchString;
  102.  
  103.         }
  104.  
  105.  
  106.  
  107.         @Override
  108.  
  109.         public void onClick(View v) {
  110.  
  111.                 Intent i = new Intent(this, ArtistsAct.class);
  112.  
  113.                 mImageManager.clear();
  114.  
  115.  
  116.  
  117.                 // Start downloading
  118.  
  119.                 mImageManager.load(getInput());
  120.  
  121.  
  122.  
  123.                 // Show results
  124.  
  125.                 startActivity(i);
  126.  
  127.         }
  128.  
  129.  
  130.  
  131.         TextWatcher textWatcher = new TextWatcher() {
  132.  
  133.  
  134.  
  135.                 @Override
  136.  
  137.                 public void onTextChanged(CharSequence s, int start, int before, int count) {
  138.  
  139.                         new GetNamesTask().execute(getInput());
  140.  
  141.                 }
  142.  
  143.  
  144.  
  145.                 @Override
  146.  
  147.                 public void beforeTextChanged(CharSequence s, int start, int count, int after) {
  148.  
  149.                 }
  150.  
  151.  
  152.  
  153.                 @Override
  154.  
  155.                 public void afterTextChanged(Editable s) {
  156.  
  157.                        
  158.  
  159.                 }
  160.  
  161.         };
  162.  
  163.  
  164.  
  165.         private class GetNamesTask extends AsyncTask<String, Integer, String[]> {
  166.  
  167.  
  168.  
  169.                 @Override
  170.  
  171.                 protected String[] doInBackground(String... params) {
  172.  
  173.                         String searchString = params[0];
  174.  
  175.                         if (searchString.endsWith("+") || searchString.length() < 2) {
  176.  
  177.                                 return null;
  178.  
  179.                         }
  180.  
  181.                         return getArtistStrings(params[0]);
  182.  
  183.                 }
  184.  
  185.  
  186.  
  187.                 @Override
  188.  
  189.                 protected void onPostExecute(String[] result) {
  190.  
  191.                         if (result != null) {
  192.  
  193.                                 updateTextAdapter(result);
  194.  
  195.                         }
  196.  
  197.                 }
  198.  
  199.  
  200.  
  201.         }
  202.  
  203.  
  204.  
  205. }
Parsed in 0.042 seconds, using GeSHi 1.0.8.4


Syntax: [ Download ] [ Hide ]
Using xml Syntax Highlighting
  1. <?xml version="1.0" encoding="utf-8"?>
  2.  
  3. <LinearLayout
  4.  
  5.         xmlns:android="http://schemas.android.com/apk/res/android"
  6.  
  7.         android:orientation="vertical"
  8.  
  9.         android:layout_width="fill_parent"
  10.  
  11.         android:layout_height="fill_parent"
  12.  
  13.         android:background="#ffffff"
  14.  
  15. >
  16.  
  17.  
  18.  
  19.         <TextView
  20.  
  21.                 android:id="@+id/artist_search_text"
  22.  
  23.                 android:layout_width="fill_parent"
  24.  
  25.                 android:layout_height="wrap_content"
  26.  
  27.                 android:text="ARTIST"
  28.  
  29.                 android:paddingTop="10dip" />
  30.  
  31.  
  32.  
  33.         <AutoCompleteTextView
  34.  
  35.                 android:id="@+id/artist_search_text_edit"
  36.  
  37.                 android:layout_width="fill_parent"
  38.  
  39.                 android:layout_height="wrap_content"
  40.  
  41.                 android:singleLine="true" />
  42.  
  43.  
  44.  
  45.         <Button
  46.  
  47.                 android:id="@+id/artist_search_button"
  48.  
  49.                 android:text="Search"
  50.  
  51.                 android:layout_width="fill_parent"
  52.  
  53.                 android:layout_height="wrap_content" />
  54.  
  55.  
  56.  
  57. </LinearLayout>
Parsed in 0.003 seconds, using GeSHi 1.0.8.4
:)
timothyjc
Freshman
Freshman
 
Posts: 3
Joined: Fri Oct 23, 2009 9:36 pm

Top

Can anyone help?

Postby timothyjc » Wed Nov 04, 2009 5:03 pm

This really has me stumped
timothyjc
Freshman
Freshman
 
Posts: 3
Joined: Fri Oct 23, 2009 9:36 pm

Postby hallikpapa » Mon Dec 28, 2009 12:13 am

I am trying to accomplish the same thing. Any luck?

For me, schools is a variable tied to my autoCompleteAdapter.

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. //ON CREATE SNIPPET
  3.  
  4.  autoCompleteAdapter = new ArrayAdapter(this, android.R.layout.simple_dropdown_item_1line, schools);
  5.  
  6.         autoComplete = (AutoCompleteTextView)  findViewById(R.id.edit);
  7.  
  8.         autoComplete.addTextChangedListener(textChecker);
  9.  
  10.         autoComplete.setAdapter(autoCompleteAdapter);
  11.  
  12. ...
  13.  
  14. ...
  15.  
  16. ...
  17.  
  18.  
  19.  
  20. public void onTextChanged(CharSequence s, int start, int before, int count)
  21.  
  22. {
  23.  
  24.                 schools = SchoolProxy.search(s.toString());
  25.  
  26.                 autoCompleteAdapter.notifyDataSetChanged();
  27.  
  28. }
  29.  
  30.  
Parsed in 0.033 seconds, using GeSHi 1.0.8.4
hallikpapa
Freshman
Freshman
 
Posts: 3
Joined: Wed Dec 09, 2009 8:43 pm

Postby timothyjc » Mon Dec 28, 2009 1:18 am

I gave up - couldn't figure it out.
timothyjc
Freshman
Freshman
 
Posts: 3
Joined: Fri Oct 23, 2009 9:36 pm

Postby hallikpapa » Mon Dec 28, 2009 3:58 am

I read that part of the problem may be because notifyDataSetChanged() will only work on the UI thread. In order to do this, I should create a simple Runnable. This, of course, is still not working (It does hit the run() statement though). Anyone else have any input please?

Basically I populate the ArrayAdapter on create with the schools variable and it works fine. But now I am trying to repopulate it with a whole new String[] schools whenever a key is pressed. I am getting the data back exactly as expected, but the list is not updating with new data in the UI

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2.  
  3.  
  4. final TextWatcher textChecker = new TextWatcher() {
  5.  
  6.         public void afterTextChanged(Editable s) {}
  7.  
  8.  
  9.  
  10.         public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
  11.  
  12.  
  13.  
  14.         public void onTextChanged(CharSequence s, int start, int before, int count)
  15.  
  16.         {
  17.  
  18.                 schools = SchoolProxy.search(s.toString());
  19.  
  20.                 runOnUiThread(updateAdapter);
  21.  
  22.         }
  23.  
  24.     };
  25.  
  26.    
  27.  
  28.     private Runnable updateAdapter = new Runnable() {
  29.  
  30.                 public void run()
  31.  
  32.                {
  33.  
  34.                 autoCompleteAdapter.notifyDataSetChanged();
  35.  
  36.             }
  37.  
  38.  
  39.  
  40.     };
  41.  
  42.  
Parsed in 0.036 seconds, using GeSHi 1.0.8.4
hallikpapa
Freshman
Freshman
 
Posts: 3
Joined: Wed Dec 09, 2009 8:43 pm

Postby hallikpapa » Thu Dec 31, 2009 1:27 am

I was trying to avoid the arrayAdapter.add(T) method, cause I didn't want to loop through everything. But it looks like it's my only option. Here is how I got this working. While there are still bugs, (I typed something, hit backspace to the very beginning to clear it, then hit backspace again, it crashed). It works.

I hope this helps you, or helps someone else trying to do something similar.

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2.  
  3.  
  4. private AutoCompleteTextView autoComplete;
  5.  
  6. private String[] schools;
  7.  
  8. private ArrayAdapter<String> autoCompleteAdapter;
  9.  
  10.  
  11.  
  12. autoCompleteAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line);
  13.  
  14. autoCompleteAdapter.setNotifyOnChange(true); // This is so I don't have to manually sync whenever changed
  15.  
  16. autoComplete = (AutoCompleteTextView)  findViewById(R.id.edit);
  17.  
  18. autoComplete.addTextChangedListener(textChecker);
  19.  
  20.  
  21.  
  22. final TextWatcher textChecker = new TextWatcher() {
  23.  
  24.         public void afterTextChanged(Editable s) {}
  25.  
  26.  
  27.  
  28.         public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
  29.  
  30.  
  31.  
  32.         public void onTextChanged(CharSequence s, int start, int before, int count)
  33.  
  34.         {
  35.  
  36.                 schools = SchoolProxy.search(s.toString());
  37.  
  38.                 autoCompleteAdapter.clear();
  39.  
  40.                 for (int i = 0; i < schools.length; i++)
  41.  
  42.                 {
  43.  
  44.                         autoCompleteAdapter.add(schools[i]);
  45.  
  46.                 }
  47.  
  48.         }
  49.  
  50.     };
  51.  
  52.  
  53.  
  54.  
Parsed in 0.039 seconds, using GeSHi 1.0.8.4
hallikpapa
Freshman
Freshman
 
Posts: 3
Joined: Wed Dec 09, 2009 8:43 pm

Top

Postby Pipen » Fri Apr 02, 2010 12:05 pm

Thanks for that example, works like a charm.

But is it possible to always at the top have two options/sugestions that are always there. I add them in my textchecker, but then the adapter doesnt include them in the result, which is the way its suppose to, but i always want to options at the top, even if the chars doesnt match, is that possible?
Pipen
Once Poster
Once Poster
 
Posts: 1
Joined: Fri Apr 02, 2010 11:57 am

Re: AutoCompleteTextView with dynamic data

Postby extremeambient » Thu Jul 15, 2010 8:24 pm

Hi everyone,

This is my first post here and my first contribution to droid community, as I start developing an app two weeks ago. My knowledge about Java / Droid is near 0, and perhaps the next code is completely wrong, but here is the solution I found to this situation:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. package android.extremeambient.net.activities;
  2.  
  3. import java.util.ArrayList;
  4.  
  5. import android.app.Activity;
  6. import android.extremeambient.net.R;
  7. import android.os.Bundle;
  8. import android.text.Editable;
  9. import android.text.TextWatcher;
  10. import android.widget.ArrayAdapter;
  11. import android.widget.AutoCompleteTextView;
  12.  
  13. public class MyActivity extends Activity {
  14.         private ArrayAdapter<String> aCA;
  15.         private AutoCompleteTextView aCT;
  16.         private ArrayList<String> arrayList = new ArrayList<String>();
  17.         private String[] mString;
  18.        
  19.         @Override
  20.         public void onCreate(Bundle savedInstanceState) {
  21.         super.onCreate(savedInstanceState);
  22.        
  23.         aCT= (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView);
  24.         aCT.addTextChangedListener(textWacther);
  25.         }
  26.        
  27.         final TextWatcher textWacther = new TextWatcher() {
  28.                 @Override
  29.                 public void afterTextChanged(Editable s) {}
  30.                
  31.                 @Override
  32.                 public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
  33.            
  34.                 @Override
  35.                 public void onTextChanged(CharSequence s, int start, int before, int count) {
  36.                         updateAdapter(s, aCA, aCT);
  37.             }
  38.         };
  39.        
  40.         private void updateAdapter(CharSequence s, ArrayAdapter<String> adapter, AutoCompleteTextView aCT) {
  41.                 arrayList = doSearch(s.toString());
  42.                 mString = (String []) arrayList.toArray(new String [arrayList.size()]);//ArrayList to String[]
  43.                 adapter = new ArrayAdapter<String>(this, R.layout.stations, mString);
  44.                 adapter.setNotifyOnChange(true);
  45.                 aCT.setAdapter(adapter);
  46.         }
  47. }
  48.  
Parsed in 0.043 seconds, using GeSHi 1.0.8.4


As you see, I only set the text change listener on onCreate and update the adapter every time the text is changed, creating a new arrayadapter with the search data and then setting the adapter.


I get data from SQLite DB but in your case, getting data from a webservice, must be the same.
User avatar
extremeambient
Once Poster
Once Poster
 
Posts: 1
Joined: Thu Jul 15, 2010 8:07 pm

Top

Return to View, Layout & Resource Problems

Who is online

Users browsing this forum: Majestic-12 [Bot] and 7 guests