Android自定义自动完成textview图标和文本

时间:2014-11-28 03:32:46

标签: android autocomplete

我希望有AutoCompleteTextView可以同时显示文字和图标。我从这个示例中获得了帮助:http://wptrafficanalyzer.in/blog/customizing-autocompletetextview-to-display-images-and-text-in-the-suggestion-list-using-simpleadapter-in-android/

在此示例中,图像用于项目的可绘制文件夹中。但是,我想使用数据库中的图像。我不知道如何更改代码下面的第二个参数来放置数据库而不是可绘制文件夹的图像。

更新 事实证明,我需要使用自定义采用者。我尝试了下面的代码,但没有调用getView。为什么?

SearchItemArrayAdapter

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;

public class SearchItemArrayAdapter extends ArrayAdapter<CountryEntry>
{
    private static final String tag = "SearchItemArrayAdapter";
    private CountryEntry listEntry;
    private TextView autoItem;
    private ImageView categoryIcon;
    private List<CountryEntry> countryEntryList = new ArrayList<CountryEntry>();

    /**
     *
     * @param context
     * @param textViewResourceId
     * @param objects
     */
    public SearchItemArrayAdapter(Context context, int textViewResourceId, ArrayList<CountryEntry> objects)
    {
        super(context, textViewResourceId, objects);
        countryEntryList = objects;
        Log.d(tag, "Search List -> journalEntryList := " + countryEntryList.toString());
    }

    @Override
    public int getCount()
    {
        Log.w(tag, "Size:= " +  this.countryEntryList.size());
        return this.countryEntryList.size();
    }

    @Override
    public CountryEntry getItem(int position)
    {
        CountryEntry journalEntry = this.countryEntryList.get(position);
        Log.d(tag, "*-> Retrieving JournalEntry @ position: " + String.valueOf(position) + " : " + journalEntry.toString());
        //return journalEntry;
        return countryEntryList.get(position);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        Log.w(tag, "GetView");

        View row = convertView;
        LayoutInflater inflater = LayoutInflater.from(getContext());

        if (row == null)
        {
            row = inflater.inflate(R.layout.autocomplete_layout, parent, false);
        }

        listEntry = this.countryEntryList.get(position);
        String searchItem = listEntry.title;
        autoItem = (TextView) row.findViewById(R.id.txt);
        autoItem.setText(searchItem);

        // Get a reference to ImageView holder
        categoryIcon = (ImageView) row.findViewById(R.id.flag);
        categoryIcon.setImageBitmap(listEntry.image);



        return row;
    }
}

MainActivity

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.AutoCompleteTextView;
import java.util.ArrayList;

public class MainActivity extends ActionBarActivity {


    AutoCompleteTextView mAutoCompleteTextView;

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


        Bitmap theImage = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);

        // Add the country details

        AutoCompleteTextView autoComplete = (AutoCompleteTextView) findViewById(R.id.autocomplete);

        ArrayList<CountryEntry> list = new ArrayList<CountryEntry>();

        // Add it to array
        list.add(new CountryEntry("india", theImage));
        list.add(new CountryEntry("usa", theImage));

        SearchItemArrayAdapter adapter = new SearchItemArrayAdapter(this, R.layout.autocomplete_layout, list);

        autoComplete.setAdapter(adapter);

    }

}

CountryEntry

import android.graphics.Bitmap;
public class CountryEntry {
    public String title;
    public Bitmap image;

    public CountryEntry(String title, Bitmap image) {
        this.title = title;
        this.image = image;
    }
}

activity_main.xml中

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <AutoCompleteTextView
        android:id="@+id/autocomplete"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:textColor="@android:color/black"
        android:hint="autocomplete"
        android:completionThreshold="1"
        />

    <TextView
        android:id="@+id/tv_currency"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_below="@id/autocomplete"
        />

</RelativeLayout>

autocomplete_layout.xml

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

    <ImageView 
            android:id="@+id/flag"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:contentDescription="@string/hello_world"
            android:padding="10dp"
    />

    <TextView 
            android:id="@+id/txt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="15dp" 
            android:padding="10dp"          
    />  

</LinearLayout>

3 个答案:

答案 0 :(得分:3)

This link很棒,但它缺少一个关键的东西 - 为了让适配器成功显示输入文本的正确自动完成, 你的&#34; JournalEntry&#34; (如示例链接中所示)必须实现自己的toString()以进行过滤:

public class JournalEntry {
    public String title;
    public Bitmap image;

    public String toString() {
        return this.title.toString();
    }
}

答案 1 :(得分:2)

您可以使用this link来满足您的要求:

你的班级:

public class ConutryEntry {
    public String title;
    public Bitmap image;

}

适配器:

 public class SearchItemArrayAdapter extends ArrayAdapter<CountryEntry>
    {
        private static final String tag = "SearchItemArrayAdapter";
        private CountryEntry listEntry;
        private TextView autoItem;
        private ImageView categoryIcon;
        private List<CountryEntry> countryEntryList = new ArrayList<CountryEntry>();

        /**
         * 
         * @param context
         * @param textViewResourceId
         * @param objects
         */
        public SearchItemArrayAdapter(Context context, int textViewResourceId, List<CountryEntry> objects)
            {
                super(context, textViewResourceId, objects);
                countryEntryList = objects;
                Log.d(tag, "Search List -> journalEntryList := " + countryEntryList.toString());
            }

        @Override
        public int getCount()
            {
                return this.countryEntryList.size();
            }

        @Override
        public CountryEntry getItem(int position)
            {
                CountryEntry journalEntry = this.countryEntryList.get(position);
                Log.d(tag, "*-> Retrieving JournalEntry @ position: " + String.valueOf(position) + " : " + journalEntry.toString());
                return journalEntry;
            }

        @Override
        public View getView(int position, View convertView, ViewGroup parent)
            {
                View row = convertView;
                LayoutInflater inflater = LayoutInflater.from(getContext());

                if (row == null)
                    {
                        row = inflater.inflate(R.layout.search_listitem_icon, parent, false);
                    }

                listEntry = this.countryEntryList.get(position);
                String searchItem = listEntry.title;
                autoItem = (TextView) row.findViewById(R.id.search_auto_item);
                autoItem.setText(searchItem);

                // Get a reference to ImageView holder
                categoryIcon = (ImageView) row.findViewById(R.id.category_icon);
                categoryIcon.setImageBitmap(listEntry.image);

                return row;
            }
    }

像以下一样填充数组:

        byte Pic[];
        Pic = yourImageByte; //get the image in the form of byte[] from db
        ByteArrayInputStream imageStream = new ByteArrayInputStream(Pic);
        Bitmap theImage = BitmapFactory.decodeStream(imageStream);

        // Add the country details

        CountryEntry entry= new CountryEntry();
        entry.title = "India";
        entry.image = theImage;

        // Add it to array
        list.add(entry);
        SearchItemArrayAdapter adapter = new SearchItemArrayAdapter(this, R.layout.search_bar_fragment, list);

答案 2 :(得分:0)

这是UI线程代码

ArrayList<HashMap<String, String>> detailsFromDB = GET THIS FROM DB;

....

String[] from = {"item_picture","item_name"};
    // Ids of views in listview_layout
int[] to = {R.id.image, R.id.nametext};
if(names != null){
    AutoCompleteSimpleAdapter autoSimpleAdapter = new AutoCompleteSimpleAdapter(getActivity(), detailsFromDB , R.layout.auto_complete_select_item, from, to);
    [AUTO_COMPLETE_VIEW].setAdapter(autoSimpleAdapter );
}

适配器代码:

public class AutoCompleteSimpleAdapter extends BaseAdapter implements Filterable {

    private int[] mTo;
    private String[] mFrom;
    private ViewBinder mViewBinder;

    private List<? extends Map<String, ?>> mData;

    private int mResource;
    private int mDropDownResource;
    private LayoutInflater mInflater;

    private SimpleFilter mFilter;
    private ArrayList<Map<String, ?>> mUnfilteredData;

    public AutoCompleteSimpleAdapter(Context context, List<? extends Map<String, ?>> data,
            int resource, String[] from, int[] to) {
        mData = data;
        mResource = mDropDownResource = resource;
        mFrom = from;
        mTo = to;
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public Object getItem(int position) {
         return mData.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        return createViewFromResource(position, convertView, parent, mResource);
    }

    private View createViewFromResource(int position, View convertView,
            ViewGroup parent, int resource) {
        View v;
        if (convertView == null) {
            v = mInflater.inflate(resource, parent, false);
        } else {
            v = convertView;
        }

        bindView(position, v);

        return v;
    }

    public void setDropDownViewResource(int resource) {
        this.mDropDownResource = resource;
    }

    @Override
    public View getDropDownView(int position, View convertView, ViewGroup parent) {
        return createViewFromResource(position, convertView, parent, mDropDownResource);
    }

    private void bindView(int position, View view) {
        final Map<String, ?> dataSet = mData.get(position);
        if (dataSet == null) {
            return;
        }

        final ViewBinder binder = mViewBinder;
        final String[] from = mFrom;
        final int[] to = mTo;
        final int count = to.length;

        for (int i = 0; i < count; i++) {
            final View v = view.findViewById(to[i]);
            if (v != null) {
                final Object data = dataSet.get(from[i]);
                String text = data == null ? "" : data.toString();
                if (text == null) {
                    text = "";
                }

                boolean bound = false;
                if (binder != null) {
                    bound = binder.setViewValue(v, data, text);
                }

                if (!bound) {
                    if (v instanceof Checkable) {
                        if (data instanceof Boolean) {
                            ((Checkable) v).setChecked((Boolean) data);
                        } else if (v instanceof TextView) {
                            // Note: keep the instanceof TextView check at the bottom of these
                            // ifs since a lot of views are TextViews (e.g. CheckBoxes).
                            setViewText((TextView) v, text);
                        } else {
                            throw new IllegalStateException(v.getClass().getName() +
                                    " should be bound to a Boolean, not a " +
                                    (data == null ? "<unknown type>" : data.getClass()));
                        }
                    } else if (v instanceof TextView) {
                        // Note: keep the instanceof TextView check at the bottom of these
                        // ifs since a lot of views are TextViews (e.g. CheckBoxes).
                        setViewText((TextView) v, text);
                    } else if (v instanceof ImageView) {

                        byte[] decodedString = Base64.decode(((String) data).getBytes(), Base64.NO_WRAP);
                        Bitmap bitmap = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
                        setViewImage((ImageView)v, bitmap);
                       /* if (data instanceof Integer) {
                            setViewImage((ImageView) v, (Integer) data);                            
                        } else {
                            setViewImage((ImageView) v, text);
                        }*/
                    } else {
                        throw new IllegalStateException(v.getClass().getName() + " is not a " +
                                " view that can be bounds by this SimpleAdapter");
                    }
                }
            }
        }
    }

    public ViewBinder getViewBinder() {
        return mViewBinder;
    }

    public void setViewBinder(ViewBinder viewBinder) {
        mViewBinder = viewBinder;
    }

    public void setViewImage(ImageView v, int value) {
        v.setImageResource(value);
    }

    public void setViewImage(ImageView v, Bitmap bitmap) {
        v.setImageBitmap(bitmap);
    }

    public void setViewImage(ImageView v, String value) {
        try {
            v.setImageResource(Integer.parseInt(value));
        } catch (NumberFormatException nfe) {
            v.setImageURI(Uri.parse(value));
        }
    }

    public void setViewText(TextView v, String text) {
        v.setText(text);
    }

    public static interface ViewBinder {
        boolean setViewValue(View view, Object data, String textRepresentation);
    }



}