使用自定义列表自动完成搜索

时间:2014-02-02 04:30:08

标签: android json autocomplete custom-controls

我正在创建一个自定义列表视图,其中包含一个自动完成文本视图,该列表正在从JSON填充。我想通过实现Filterable接口来过滤自定义列表。任何人都可以帮助我,如何实现{{1}自定义列表的方法

这是getFilter()方法

onCreate

这是 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.custom_list); CustomListView = this; setListData(); //to set the list data Resources res = getResources(); list = (ListView) findViewById(R.id.list); adapter = new CustomAdapter(CustomListView, CustomListViewValuesArr, res); list.setAdapter(adapter); list.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { i1 = new Intent(CustomListHospital.this, Details.class); i1.putExtra("Name", list.getItemAtPosition(position).toString()); startActivity(i1); } }); inputSearch.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) { // When user changed the Text // getfilter to filter the search while user types in the search // box CustomListHospital.this.adapter.getFilter().filter(cs); } 方法

setListData()

这是我创建的自定义适配器的代码

   public void setListData() {
    i1 = getIntent();
    s1 = i1.getStringExtra("Speciality");
    try {
        InputStream inputStream = getAssets().open("Hospital_Json.txt");
        BufferedReader bufferedReader = new BufferedReader(
                new InputStreamReader(inputStream));
        String tempString;
        StringBuilder builder = new StringBuilder();

        while ((tempString = bufferedReader.readLine()) != null) {
            builder.append(tempString);

            builder.append(System.getProperty("line.separator"));
        }

        jsonString = builder.toString();

        JSONObject jsonObject = new JSONObject(jsonString);
        JSONArray jsonArray = jsonObject.getJSONArray("data");

        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject countryObject = jsonArray.getJSONObject(i);
            String cellNo = countryObject.getString("Telephone");
            String name = countryObject.getString("Name");
            String special = countryObject.getString("Speciality");
            String category = countryObject.getString("Category");

            ListModel sched = new ListModel();

            if (category.equals("Doctor") && special.equals(s1)) {
                sched.setHospitalName(name);
                sched.setCellNo(cellNo);
                CustomListViewValuesArr.add(sched);
            } else if (category.equals("Hospital") && special.equals(s1)) {
                sched.setHospitalName(name);
                sched.setCellNo(cellNo);
                CustomListViewValuesArr.add(sched);
            }
        }

    } catch (IOException e) {
        e.printStackTrace();
    } catch (JSONException e) {
        e.printStackTrace();
    }

2 个答案:

答案 0 :(得分:0)

以下是如何在Base Adapter

中使用过滤器的示例

在您的活动中调用此过滤器

adapter.getFilter()过滤器( “textt”);

public class AutocompleteFilterAdapter extends BaseAdapter implements
    Filterable {

List<String> originalList, filterdList;
TestFilter filter = new TestFilter();
private Context mContext;
TextView txtName;

public AutocompleteFilterAdapter(List<String> data, Context context) {

    this.originalList = data;
    this.filterdList = data;
    mContext = context;

}

@Override
public Filter getFilter() {
    // TODO Auto-generated method stub
    return filter;
}

private class TestFilter extends Filter {

    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        // TODO Auto-generated method stub
        FilterResults results = new FilterResults();
        List<String> list = new ArrayList<String>();
        // String filterdString = null;

        for (int i = 0; i < originalList.size(); i++) {

            if (originalList.get(i).contains(
                    constraint.toString().substring(1)))
                list.add(originalList.get(i));
        }

        results.values = list;
        results.count = list.size();
        return results;
    }

    @Override
    protected void publishResults(CharSequence constraint,
            FilterResults results) {
        // TODO Auto-generated method stub
        filterdList = (List<String>) results.values;
        notifyDataSetChanged();
    }

}

@Override
public int getCount() {
    // TODO Auto-generated method stub
    if (filterdList != null)
        return filterdList.size();
    return 0;
}

@Override
public String getItem(int position) {
    // TODO Auto-generated method stub
    return filterdList.get(position);
}

@Override
public long getItemId(int position) {
    // TODO Auto-generated method stub
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub

    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) mContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(
                R.layout.autocompletetextview_search, parent, false);
    }

    txtName = (TextView) convertView
            .findViewById(R.id.autoCompleteTextviewSearch);
    txtName.setText(getItem(position));

    return convertView;
}

}

答案 1 :(得分:0)

Here is another example:


public class PlanetAdapter extends ArrayAdapter<Planet> implements Filterable {

        private List<Planet> planetList;
        private Context context;
        private Filter planetFilter;
        private List<Planet> origPlanetList;

        public PlanetAdapter(List<Planet> planetList, Context ctx) {
                super(ctx, R.layout.img_row_layout, planetList);
                this.planetList = planetList;
                this.context = ctx;
                this.origPlanetList = planetList;
        }

        public int getCount() {
                return planetList.size();
        }

        public Planet getItem(int position) {
                return planetList.get(position);
        }

        public long getItemId(int position) {
                return planetList.get(position).hashCode();
        }

        public View getView(int position, View convertView, ViewGroup parent) {
                View v = convertView;

                PlanetHolder holder = new PlanetHolder();

                // First let's verify the convertView is not null
                if (convertView == null) {
                        // This a new view we inflate the new layout
                        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                        v = inflater.inflate(R.layout.img_row_layout, null);
                        // Now we can fill the layout with the right values
                        TextView tv = (TextView) v.findViewById(R.id.name);
                        TextView distView = (TextView) v.findViewById(R.id.dist);


                        holder.planetNameView = tv;
                        holder.distView = distView;

                        v.setTag(holder);
                }
                else 
                        holder = (PlanetHolder) v.getTag();

                Planet p = planetList.get(position);
                holder.planetNameView.setText(p.getName());
                holder.distView.setText("" + p.getDistance());


                return v;
        }

        public void resetData() {
                planetList = origPlanetList;
        }


        /* *********************************
         * We use the holder pattern        
         * It makes the view faster and avoid finding the component
         * **********************************/

        private static class PlanetHolder {
                public TextView planetNameView;
                public TextView distView;
        }



        /*
         * We create our filter        
         */

        @Override
        public Filter getFilter() {
                if (planetFilter == null)
                        planetFilter = new PlanetFilter();

                return planetFilter;
        }



        private class PlanetFilter extends Filter {



                @Override
                protected FilterResults performFiltering(CharSequence constraint) {
                        FilterResults results = new FilterResults();
                        // We implement here the filter logic
                        if (constraint == null || constraint.length() == 0) {
                                // No filter implemented we return all the list
                                results.values = origPlanetList;
                                results.count = origPlanetList.size();
                        }
                        else {
                                // We perform filtering operation
                                List<Planet> nPlanetList = new ArrayList<Planet>();

                                for (Planet p : planetList) {
                                        if (p.getName().toUpperCase().startsWith(constraint.toString().toUpperCase()))
                                                nPlanetList.add(p);
                                }

                                results.values = nPlanetList;
                                results.count = nPlanetList.size();

                        }
                        return results;
                }

                @Override
                protected void publishResults(CharSequence constraint,
                                FilterResults results) {

                        // Now we have to inform the adapter about the new list filtered
                        if (results.count == 0)
                                notifyDataSetInvalidated();
                        else {
                                planetList = (List<Planet>) results.values;
                                notifyDataSetChanged();
                        }

                }

        }
}


and use it at MainActivity:




public class MainActivity extends Activity {

        // The data to show
        List<Planet> planetsList = new ArrayList<Planet>();
        PlanetAdapter aAdpt;

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

        initList();

        // We get the ListView component from the layout
        ListView lv = (ListView) findViewById(R.id.listView);


        // This is a simple adapter that accepts as parameter
        // Context
        // Data list
        // The row layout that is used during the row creation
        // The keys used to retrieve the data
        // The View id used to show the data. The key number and the view id must match
        //aAdpt = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, planetsList);
        aAdpt = new PlanetAdapter(planetsList, this);
        lv.setAdapter(aAdpt);

        // React to user clicks on item
        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {

                        public void onItemClick(AdapterView<?> parentAdapter, View view, int position,
                                        long id) {


                                // We know the View is a <extView so we can cast it
                                TextView clickedView = (TextView) view;

                                Toast.makeText(MainActivity.this, "Item with id ["+id+"] - Position ["+position+"] - Planet ["+clickedView.getText()+"]", Toast.LENGTH_SHORT).show();

                        }
                   });

          // we register for the contextmneu        
          registerForContextMenu(lv);

          // TextFilter
          lv.setTextFilterEnabled(true);
          EditText editTxt = (EditText) findViewById(R.id.editTxt);          

          editTxt.addTextChangedListener(new TextWatcher() {

                                @Override
                                public void onTextChanged(CharSequence s, int start, int before, int count) {
                                        System.out.println("Text ["+s+"] - Start ["+start+"] - Before ["+before+"] - Count ["+count+"]");
                                        if (count < before) {
                                                // We're deleting char so we need to reset the adapter data
                                                aAdpt.resetData();
                                        }

                                        aAdpt.getFilter().filter(s.toString());

                                }

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

                                }

                                @Override
                                public void afterTextChanged(Editable s) {
                                }
                        });
        }


     // We want to create a context Menu when the user long click on an item
    @Override
        public void onCreateContextMenu(ContextMenu menu, View v,
                        ContextMenuInfo menuInfo) {

                super.onCreateContextMenu(menu, v, menuInfo);
                AdapterContextMenuInfo aInfo = (AdapterContextMenuInfo) menuInfo;

                // We know that each row in the adapter is a Map
                Planet planet =  aAdpt.getItem(aInfo.position);

                menu.setHeaderTitle("Options for " + planet.getName());
                menu.add(1, 1, 1, "Details");
                menu.add(1, 2, 2, "Delete");

        }




    // This method is called when user selects an Item in the Context menu
        @Override
        public boolean onContextItemSelected(MenuItem item) {
                int itemId = item.getItemId();
                AdapterContextMenuInfo aInfo = (AdapterContextMenuInfo) item.getMenuInfo();
                planetsList.remove(aInfo.position);
                aAdpt.notifyDataSetChanged();
                return true;
        }


        private void initList() {
        // We populate the planets

        planetsList.add(new Planet("Mercury", 10));
        planetsList.add(new Planet("Venus", 20));
        planetsList.add(new Planet("Mars", 30));
        planetsList.add(new Planet("Jupiter", 40));
        planetsList.add(new Planet("Saturn", 50));
        planetsList.add(new Planet("Uranus", 60));
        planetsList.add(new Planet("Neptune", 70));


    }


    // Handle user click
    public void addPlanet(View view) {
            final Dialog d = new Dialog(this);
            d.setContentView(R.layout.dialog);
            d.setTitle("Add planet");
            d.setCancelable(true);

            final EditText edit = (EditText) d.findViewById(R.id.editTextPlanet);
            Button b = (Button) d.findViewById(R.id.button1);
            b.setOnClickListener(new View.OnClickListener() {

                        public void onClick(View v) {
                                String planetName = edit.getText().toString();
                                MainActivity.this.planetsList.add(new Planet(planetName, 0));
                                MainActivity.this.aAdpt.notifyDataSetChanged(); // We notify the data model is changed
                                d.dismiss();
                        }
                });

            d.show();
    }


}