如何动态地向autocompletetextview添加建议,同时保留角色状态和图像

时间:2014-01-30 08:00:31

标签: android simplecursoradapter autocompletetextview android-cursoradapter

目前我正在使用代码提供文字建议。我想添加另一个文字和图片。我怎么做?目前,我正在使用下面的代码。我显示文字,但不显示图像。如何设置图像?

public class AutoCompleteTextViewActivity extends Activity{

ImageLoader imageLoader;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
        .cacheInMemory(true)
        .cacheOnDisc(true)
        .build();

ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
        .defaultDisplayImageOptions(defaultOptions)
        .build();
ImageLoader.getInstance().init(config);


        AutoCompleteTextView actv = new AutoCompleteTextView(this);
        actv.setThreshold(1);
        final String[] from = {BaseColumns._ID, "name", "artist", "title"};
        int[] to = {R.id.list_image, R.id.textView1, R.id.textView2, R.id.textView3};
        final SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.list_row, null, from, to);
        adapter.setStringConversionColumn(1);
        ViewBinder viewBinder = new ViewBinder() {
             public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
                 if (columnIndex == 0) {
                     ImageView iv = (ImageView) view;
                     Bitmap bitmap = cursor.getExtras().getParcelable("image");
                     if (bitmap != null) {
                         iv.setImageBitmap(bitmap);
                     }
                     return true;
                 }
                 return false;
             }
        };
        adapter.setViewBinder(viewBinder);
        FilterQueryProvider provider = new FilterQueryProvider() {
            ExecutorService mPool = Executors.newCachedThreadPool();
            Uri URI = Uri.parse("adapter://autocomplete");

            public Cursor runQuery(CharSequence constraint) {
                if (constraint == null) {
                    return null;
                }
                try {
                    return callWebService(constraint, from);
                } catch (JSONException e) {
                    e.printStackTrace();
                    return null;
                }
            }

            // here you make the web request
            private Cursor callWebService(CharSequence constraint, String[] columnNames) throws JSONException {
                Log.d("TAG", "callWebService for: " + constraint);
                MatrixCursor cursor = new MyMatrixCursor(columnNames);

                // TODO do real network request
                // call web service here and keep the result in "jsonStr" 

            //  String a=constraint;
                JSONObject json=JSONfunctions.getJSONfromURL("http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist="+ constraint +"&api_key=63692beaaf8ba794a541bca291234cd3&format=json");



                JSONObject js1=json.getJSONObject("artist");
                JSONObject js=js1.getJSONObject("similar");
                JSONArray resultArray = js.getJSONArray("artist");


                int length = resultArray.length();
                for (int i = 0; i < length; i++) {
                    String data = resultArray.getJSONObject(i).getString("name");

                    String dataimage = resultArray.getJSONObject(i).getJSONArray("image").getJSONObject(i).getString("#text");

                    cursor.newRow().add(i)
                        .add(data)
                        .add(data)
                        .add(data);

                    String link = dataimage;
                    // get cached Bundle based on "link" (use HashMap<String, Bundle>)
                    // or if new link initiate async request for getting the bitmap

                    // TODO implement HashMap caching

                    // new async request
                    Bundle extras = new Bundle();
                    try {
                        mPool.submit(new ImageRequest(link, extras));
                    } catch (MalformedURLException e) {
                        e.printStackTrace();
                    }
                    cursor.respond(extras);
                }
                cursor.setNotificationUri(getContentResolver(), URI);
                return cursor;
            }

            class ImageRequest implements Runnable {
                private URL mUrl;
                private Bundle mExtra;

                public ImageRequest(String link, Bundle extra) throws MalformedURLException {
                    mUrl = new URL(link);
                    mExtra = extra;
                }

                public void run() {
                            String TAG="log";
                            // TODO do real network request
                            // simulate network delay
//                          Log.d(TAG, "getting " + mUrl);
//                          try {
//                              Thread.sleep(2000 + (long) (4000 * Math.random()));
//                          } catch (InterruptedException e) {
//                              e.printStackTrace();
//                          }

                            Bitmap b = imageLoader.loadImageSync(mUrl.toString());
                         //   Bitmap b = BitmapFactory.decodeResource(getResources(), mUrl.toString());
                            mExtra.putParcelable("image", b);
                            getContentResolver().notifyChange(URI, null);
                            Log.d(TAG, "run got a bitmap " + b.getWidth() + "x" + b.getHeight());

                }


            }
        };
        adapter.setFilterQueryProvider(provider);
        actv.setAdapter(adapter);



        LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
        setContentView(actv, params);
    }

}

///////////////

MyMatrixCursor //////////

public class MyMatrixCursor extends MatrixCursor {
    List<Bundle> mBundles = new ArrayList<Bundle>();

    public MyMatrixCursor(String[] columnNames) {
        super(columnNames);
    }

    @Override
    public Bundle respond(Bundle extras) {
        mBundles.add(extras);
        return extras;
    }

    @Override
    public Bundle getExtras() {
        return mBundles.get(mPos);
    }
}

////////

JSONfunctions ///////

public class JSONfunctions {

    public static JSONObject getJSONfromURL(String url){
        InputStream is = null;
        String result = "";
        JSONObject jArray = null;

        //http post
        try{
                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost(url);
                HttpResponse response = httpclient.execute(httppost);
                HttpEntity entity = response.getEntity();
                is = entity.getContent();

        }catch(Exception e){
                Log.e("log_tag", "Error in http connection "+e.toString());
        }

      //convert response to string
        try{
                BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
                StringBuilder sb = new StringBuilder();
                String line = null;
                while ((line = reader.readLine()) != null) {
                        sb.append(line + "\n");
                }
                is.close();
                result=sb.toString();
        }catch(Exception e){
                Log.w("log_tag", "Error converting result "+e.toString());
        }

        try{

            jArray = new JSONObject(result);            
        }catch(JSONException e){
                Log.w("log_tag", "Error parsing data "+e.toString());
        }

        return jArray;
    }
}

////////

main.xml中 ///

<?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" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Pick Artist"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <AutoCompleteTextView
        android:id="@+id/actv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:completionThreshold="1"> <requestFocus />
    </AutoCompleteTextView>
    <TextView
        android:id="@+id/selection"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"

        android:textAppearance="?android:attr/textAppearanceLarge" />

</LinearLayout>

/////

list_row.xml ///

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/white"
    android:orientation="horizontal"
    android:padding="5dip" >

    <!--  ListRow Left sied Thumbnail image -->
    <LinearLayout android:id="@+id/thumbnail" 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="3dip"      
        android:layout_alignParentLeft="true"
        android:layout_marginRight="5dip">

        <ImageView     
            android:id="@+id/list_image"   
        android:layout_width="wrap_content"  
  android:layout_height="wrap_content"  
  android:adjustViewBounds="true"  
  android:maxWidth="42dp"  
  android:maxHeight="42dp"  
  android:src="@drawable/ic_launcher"
  android:scaleType="fitCenter"  
  android:layout_marginLeft="3dp"/>

    </LinearLayout>

    <!-- Title Of Song-->
    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/thumbnail"
        android:layout_toRightOf="@+id/thumbnail"
        android:text="test"
        android:textColor="#040404"
        android:typeface="sans" 
        android:textSize="15dip"
        android:textStyle="bold"/>

    <!-- Artist Name -->

    <!-- Rightend Duration -->

     <!-- Rightend Arrow -->



    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/textView1"
        android:layout_centerVertical="true"
        android:text="test"
        android:textColor="#040404"
        android:textSize="5dip"
        android:textStyle="bold"
        android:typeface="sans" />

    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/thumbnail"
        android:layout_toRightOf="@+id/thumbnail"
        android:text="test"
        android:textColor="#040404"
        android:textSize="15dip"
        android:textStyle="bold"
        android:typeface="sans" />

</RelativeLayout>

/// 清单

///

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.example"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".AutoCompleteTextViewActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

1 个答案:

答案 0 :(得分:1)

好吧试试这个:

    LinearLayout ll = new LinearLayout(this);
    ll.setOrientation(LinearLayout.VERTICAL);

    AutoCompleteTextView actv = new AutoCompleteTextView(this);
    actv.setThreshold(1);
    String[] from = {"name"};
    int[] to = {android.R.id.text1};
    SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_dropdown_item_1line, null, from, to) {

        // required for Spanned data
        @Override
        public void bindView(View view, Context context, Cursor cursor) {
            MyCursor c = (MyCursor) cursor;
            TextView tv = (TextView) view;
            tv.setText(c.getSpanned());
        }

        // required for Spanned data
        @Override
        public CharSequence convertToString(Cursor cursor) {
            MyCursor c = (MyCursor) cursor;
            return c.getSpanned();
        }
    };
    FilterQueryProvider provider = new FilterQueryProvider() {
        @Override
        public Cursor runQuery(CharSequence constraint) {
            if (constraint == null) {
                return null;
            }
            MyCursor c = new MyCursor();
            // fake web service responses
            List<String> names = callFakeWebService(constraint);
            int i = 0;
            for (String name: names) {
                SpannableStringBuilder ssb = new SpannableStringBuilder(name);
                int start = name.indexOf(" ");
                ForegroundColorSpan what = new ForegroundColorSpan(0xffff0000);
                ssb.setSpan(what, start + 1, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                c.newRow().add(i++).add(name);
                c.addSpanned(ssb);
            }
            return c;
        }

        // fake web service request
        private List<String> callFakeWebService(CharSequence constraint) {
            Log.d(TAG, "callFakeWebService for: " + constraint);
            String[] namesArr = {
                    "Mark Smith",
                    "Monica Thompson",
                    "John White",
                    "Jane Brown"
            };
            String stringConstraint = constraint.toString().toLowerCase();
            List<String> names = new ArrayList<String>();
            for (int i = 0; i < namesArr.length; i++) {
                String name = namesArr[i];
                if (name.toLowerCase().startsWith(stringConstraint)) {
                    names.add(name);
                }
            }
            return names;
        }
    };
    adapter.setFilterQueryProvider(provider);
    actv.setAdapter(adapter);
    ll.addView(actv);
    TextView tv = new TextView(this);
    tv.setTextSize(32);
    tv.setTextColor(0xffff0000);
    tv.setText("type one of:\n  mark,\n  monica,\n  john\n  jane");
    ll.addView(tv);
    setContentView(ll);

自定义Cursor可能看起来像这样(它只是支持一行跨越的简约版本):

static class MyCursor extends MatrixCursor {
    private static final String[] NAMES = {BaseColumns._ID, "name"};
    private ArrayList<Spanned> mSpannedList;

    public MyCursor() {
        super(NAMES);
        mSpannedList = new ArrayList<Spanned>();
    }

    public void addSpanned(Spanned s) {
        mSpannedList.add(s);
    }

    public Spanned getSpanned() {
        return mSpannedList.get(mPos);
    }
}
没有跨文字的

编辑

    AutoCompleteTextView actv = new AutoCompleteTextView(this);
    actv.setThreshold(1);
    final String[] from = {BaseColumns._ID, "name", "artist", "title"};
    int[] to = {R.id.list_image, R.id.textView1, R.id.textView2, R.id.textView3};
    final SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.list_row, null, from, to);
    adapter.setStringConversionColumn(1);
    ViewBinder viewBinder = new ViewBinder() {
         public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
             if (columnIndex == 0) {
                 ImageView iv = (ImageView) view;
                 Bitmap bitmap = cursor.getExtras().getParcelable("image");
                 if (bitmap != null) {
                     iv.setImageBitmap(bitmap);
                 }
                 return true;
             }
             return false;
         }
    };
    adapter.setViewBinder(viewBinder);
    FilterQueryProvider provider = new FilterQueryProvider() {
        ExecutorService mPool = Executors.newCachedThreadPool();
        Uri URI = Uri.parse("adapter://autocomplete");

        public Cursor runQuery(CharSequence constraint) {
            if (constraint == null) {
                return null;
            }
            try {
                return callWebService(constraint, from);
            } catch (JSONException e) {
                e.printStackTrace();
                return null;
            }
        }

        // here you make the web request
        private Cursor callWebService(CharSequence constraint, String[] columnNames) throws JSONException {
            Log.d("TAG", "callWebService for: " + constraint);
            MatrixCursor cursor = new MyMatrixCursor(columnNames);

            // TODO do real network request
            // call web service here and keep the result in "jsonStr" 
            String jsonStr =  "{\"ResultArray\":[{\"data\":{ \"sno\":\"sno1\", \"date\":\"2011-08-21 14:27:09\", \"user\":\"1\", \"link\":\"http://scm-l3.technorati.com/11/11/17/56749/google-docs-revision.jpg?t=20111117074048\", \"name\":\"Aa\" }},{\"data\":{ \"sno\":\"sno2\", \"date\":\"2011-08-21 14:28:09\", \"user\":\"2\", \"link\":\"http://kcclaveria.com/wp-content/uploads/2013/02/google-panda-penguin.jpg\", \"name\":\"Bb\" }}]}";

            JSONObject json = new JSONObject(jsonStr);
            JSONArray resultArray = json.getJSONArray("ResultArray");

            int length = resultArray.length();
            for (int i = 0; i < length; i++) {
                JSONObject data = resultArray.getJSONObject(i).getJSONObject("data");

                cursor.newRow().add(i)
                    .add(data.getString("name"))
                    .add(data.getString("user"))
                    .add(data.getString("sno"));

                String link = data.getString("link");
                // get cached Bundle based on "link" (use HashMap<String, Bundle>)
                // or if new link initiate async request for getting the bitmap

                // TODO implement HashMap caching

                // new async request
                Bundle extras = new Bundle();
                try {
                    mPool.submit(new ImageRequest(link, extras));
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                }
                cursor.respond(extras);
            }
            cursor.setNotificationUri(getContentResolver(), URI);
            return cursor;
        }

        class ImageRequest implements Runnable {
            private URL mUrl;
            private Bundle mExtra;

            public ImageRequest(String link, Bundle extra) throws MalformedURLException {
                mUrl = new URL(link);
                mExtra = extra;
            }

            @Override
            public void run() {
                // TODO do real network request
                // simulate network delay
                Log.d(TAG, "getting " + mUrl);
                try {
                    Thread.sleep(2000 + (long) (4000 * Math.random()));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
                mExtra.putParcelable("image", b);
                getContentResolver().notifyChange(URI, null);
                Log.d(TAG, "run got a bitmap " + b.getWidth() + "x" + b.getHeight());
            }
        }
    };
    adapter.setFilterQueryProvider(provider);
    actv.setAdapter(adapter);

    LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    setContentView(actv, params);

和自定义MatrixCursor:

class MyMatrixCursor extends MatrixCursor {
    List<Bundle> mBundles = new ArrayList<Bundle>();

    public MyMatrixCursor(String[] columnNames) {
        super(columnNames);
    }

    @Override
    public Bundle respond(Bundle extras) {
        mBundles.add(extras);
        return extras;
    }

    @Override
    public Bundle getExtras() {
        return mBundles.get(mPos);
    }
}