Android SearchBox für Custom Listview

Laire

Mitglied
Hallo,

ich brauche für meine Custom Listview eine searchbox also sowas wie hier:

custom_listview_search2.png


Die Beispiele die ich im Netzt gefunden haben, waren meist für normale Fieldlists oder sehr speziell auf ein Beispiel beschränkt, so das ich die nich adaptieren konnte.

Die activity sieht so aus:
Java:
package de.bodprod.rettinfo;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;

public class AntidotList extends Activity{
    ArrayList<HashMap<String, String>> antidotList;

    String[] sqliteIds;

    public static String TAG_ID = "id";
    public static String TAG_TOX = "tox";
    public static String TAG_ANTIDOT = "antidot";

    ListView lv;
    int textlength=0;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.antidotlist_layout);

        antidotList = new ArrayList<HashMap<String, String>>();
        lv = (ListView) findViewById(R.id.antidotlistlayout);

        lv.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

            }
        });        
        new loadStoreAntidots().execute();
    }

    class loadStoreAntidots extends AsyncTask<String, String, String> {
        @Override
        protected String doInBackground(String... args) {
            // updating UI from Background Thread
            runOnUiThread(new Runnable() {
                public void run() {
                    DatabaseHandler db = new DatabaseHandler(getApplicationContext());
                    List<AntidotsClass> antidots = db.getAllAntidots();
                    sqliteIds = new String[antidots.size()];

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

                        AntidotsClass s = antidots.get(i);

                        // creating new HashMap
                        HashMap<String, String> map = new HashMap<String, String>();

                        // adding each child node to HashMap key => value
                        map.put(TAG_ID, s.getId().toString());
                        map.put(TAG_TOX, s.getTox());
                        map.put(TAG_ANTIDOT, s.getAntidot());

                        // adding HashList to ArrayList
                        antidotList.add(map);

                        // add sqlite id to array
                        // used when deleting a website from sqlite
                        sqliteIds[i] = s.getId().toString();
                    }
                    ListAdapter adapter = new SimpleAdapter(
                        AntidotList.this,
                        antidotList, R.layout.antidotlistitem_layout,
                        new String[] { TAG_ID, TAG_TOX, TAG_ANTIDOT },
                        new int[] { R.id.sqlite_id, R.id.tox_layout, R.id.antidot_layout }
                    );
                    lv.setAdapter(adapter);
                }
            });
            return null;
        }
    }
}

und die Layout Datei so:

Code:
<?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"
    style="@style/mainView" 
    android:orientation="vertical" >
    <EditText android:id="@+id/EditText01"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:hint="Suchen">                               
    </EditText>    
    <ListView
        android:id="@+id/antidotlistlayout"
        style="@style/mainView" 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >
    </ListView>           
</LinearLayout>

Wäre für jede Hilfe dankbar.
 
Woran genau scheitert es? Die Beispiele zeigen doch das Prinzip schön vor?

Du hast eine Menge von Objekten in denen du suchen kannst. Jedes Mal wenn sich der Text in deiner Search-Box ändert, stößt du einen Async-Task an. Dieser Async-Task filtert die Objektmenge nach dem eingegebenen Begriff, teilt dem Adapter mit wie seine neuen Daten aussehen und stößt dann ein notifyDataSetChanged an.

Daraufhin zeichnet die ListView neu. Das einzige was jetzt noch fehlt, ist Code der den Async-Task abbricht wenn er noch läuft und ein neuer gestartet werden soll.
 
Habe jetzt noch ein paar Beispiel durchgeguckt und bin etwas weiter gekommen. Aber irgendwie funktioniert die Suche nicht wirklich. Egal welchen Buchstabe ich in die Searchbox eingebe, er zeigt mir immer den ersten Eintrag in der Liste an und weiter nichts.

Wenn also die Liste zum BEispiel so aussieht:

Auto
Blume
Gabel
Hund
Wasser

und gebe in der Searchbox W ein, verschwinden alle Einträge ausser Auto. Vielleicht kann mir wer weiter helfen.

Hier der Quelltext:

Activity:
Java:
package de.bodprod.rettinfo;
 
import java.util.ArrayList;
import java.util.HashMap;
import android.app.ListActivity;
import android.content.Context;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;

public class AntidotList extends ListActivity{
	ArrayList<HashMap<String, Object>> antidots;
	ArrayList<HashMap<String, Object>> antidotsResult;
	LayoutInflater inflater;
	
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        setContentView(R.layout.antidotlist_layout);
        final EditText searchBox=(EditText) findViewById(R.id.EditText01);
        ListView antidotListView=(ListView) findViewById(android.R.id.list);
        
        inflater=(LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        
        antidots = new ArrayList<HashMap<String,Object>>();        
    	DatabaseHandler db = new DatabaseHandler(getApplicationContext());
    	antidots = db.getAllAntidots();
    	
    	antidotsResult = new ArrayList<HashMap<String,Object>>(antidots);
    	
    	final CustomAdapter adapter = new CustomAdapter(this, R.layout.antidotlist_layout, antidotsResult);
    	antidotListView.setAdapter(adapter);
    	
    	searchBox.addTextChangedListener(new TextWatcher() {
    		public void onTextChanged(CharSequence s, int start, int before, int count) {
    			//get the text in the EditText
    			String searchString=searchBox.getText().toString();
    			int textLength=searchString.length();
 
    			antidotsResult.clear();
 
    			for(int i=0;i<antidots.size();i++){
    				String toxinname=antidots.get(i).get("toxin").toString();
    				if(textLength<=toxinname.length()){
    					if(searchString.equalsIgnoreCase(toxinname.substring(0,textLength)))
    						antidotsResult.add(antidots.get(i));
    				}
    			} 
    			adapter.notifyDataSetChanged();
    		}
    		public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
    		public void afterTextChanged(Editable s) {}
    	});
	}
    	
	private class CustomAdapter extends ArrayAdapter<HashMap<String, Object>>{
		public CustomAdapter(Context context, int textViewResourceId, ArrayList<HashMap<String, Object>> Strings) {
			super(context, textViewResourceId, Strings);
		}
		private class ViewHolder{
			TextView sqlite_id, tox_layout, antidot_layout;
		}

		ViewHolder viewHolder;

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			if(convertView==null){        
				convertView=inflater.inflate(R.layout.antidotlistitem_layout, null);
				viewHolder=new ViewHolder();
	    
				viewHolder.sqlite_id=(TextView) convertView.findViewById(R.id.sqlite_id);
				viewHolder.tox_layout=(TextView) convertView.findViewById(R.id.tox_layout);
				viewHolder.antidot_layout=(TextView) convertView.findViewById(R.id.antidot_layout);
				
				convertView.setTag(viewHolder);
				
			}else{
				viewHolder=(ViewHolder) convertView.getTag();
			}
	   
			viewHolder.sqlite_id.setText(antidots.get(position).get("sql_id").toString());
			viewHolder.tox_layout.setText(antidots.get(position).get("toxin").toString());
			viewHolder.antidot_layout.setText(antidots.get(position).get("antidot").toString());
	  
			return convertView;
		}
	}
}

Datenbank Handler:

Java:
package de.bodprod.rettinfo;
 
import java.util.ArrayList;
import java.util.HashMap;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
 
public class DatabaseHandler extends SQLiteOpenHelper {
    // All Static variables
    // Database Version
    private static final int DATABASE_VERSION = 7;
 
    // Database Name
    private static final String DATABASE_NAME = "rettinfo";
 
    // Antidot table name
    private static final String TABLE_ANTIDOT = "antidotlist";
 
    // Antidot Table Columns names
    private static final String KEY_ID = "id";
    private static final String KEY_TOX = "tox";
    private static final String KEY_ANTIDOT = "antidot";
    private static final String KEY_DOS = "dos";
    private static final String KEY_KAT = "kat";
 
    public DatabaseHandler(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
 
    // Creating Tables
    @Override
    public void onCreate(SQLiteDatabase db) {
    	Log.d("Create: ", "Creating ..");
        String CREATE_ANTIDOT_TABLE = "CREATE TABLE " + TABLE_ANTIDOT + "("
                + KEY_ID + " INTEGER PRIMARY KEY," + KEY_TOX + " TEXT,"
                + KEY_ANTIDOT + " TEXT," + KEY_DOS + " TEXT," + KEY_KAT + " INTEGER" + ")";
        Log.d("Create: ", CREATE_ANTIDOT_TABLE);
        db.execSQL(CREATE_ANTIDOT_TABLE);

        ContentValues values = new ContentValues();
        values.put(KEY_TOX, "Alkylphosphat");
        values.put(KEY_ANTIDOT, "Atropinsulfat");
        values.put(KEY_DOS, "Initial: 2 - 5 mg i.V. alle 10 bis 15 Min 
 Kinder - Initial: 0,5 - 2 mg i.V. 
 bis zum Rückgang der Bronchialsekretion");
        values.put(KEY_KAT, "1");
        db.insert(TABLE_ANTIDOT, null, values);
        
        values.put(KEY_TOX, "E605 (Alkylphosphat)");
        values.put(KEY_ANTIDOT, "Atropinsulfat");
        values.put(KEY_DOS, "Initial: 2 - 5 mg i.V. alle 10 bis 15 Min 
 Kinder - Initial: 0,5 - 2 mg i.V. 
 bis zum Rückgang der Bronchialsekretion");
        values.put(KEY_KAT, "1");
        db.insert(TABLE_ANTIDOT, null, values);
        
        values.put(KEY_TOX, "DDVP (Alkylphosphat)");
        values.put(KEY_ANTIDOT, "Atropinsulfat");
        values.put(KEY_DOS, "Initial: 2 - 5 mg i.V. alle 10 bis 15 Min 
 Kinder - Initial: 0,5 - 2 mg i.V. 
 bis zum Rückgang der Bronchialsekretion");
        values.put(KEY_KAT, "1");
        db.insert(TABLE_ANTIDOT, null, values);       
        
        values.put(KEY_TOX, "Sarin (Alkylphosphat)");
        values.put(KEY_ANTIDOT, "Atropinsulfat");
        values.put(KEY_DOS, "Initial: 2 - 5 mg i.V. alle 10 bis 15 Min 
 Kinder - Initial: 0,5 - 2 mg i.V. 
 bis zum Rückgang der Bronchialsekretion");
        values.put(KEY_KAT, "1");
        db.insert(TABLE_ANTIDOT, null, values);         
        
        values.put(KEY_TOX, "Nervengas (Alkylphosphat)");
        values.put(KEY_ANTIDOT, "Atropinsulfat");
        values.put(KEY_DOS, "Initial: 2 - 5 mg i.V. alle 10 bis 15 Min 
 Kinder - Initial: 0,5 - 2 mg i.V. 
 bis zum Rückgang der Bronchialsekretion");
        values.put(KEY_KAT, "1");
        db.insert(TABLE_ANTIDOT, null, values);         
    }
 
    // Upgrading database
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Drop older table if existed
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_ANTIDOT);
        // Create tables again
        onCreate(db);
    }	
    

    public ArrayList<HashMap<String,Object>> getAllAntidots() {
    	ArrayList<HashMap<String,Object>> antidotList = new ArrayList<HashMap<String,Object>>();
        String selectQuery = "SELECT  * FROM " + TABLE_ANTIDOT + " ORDER BY " + KEY_TOX;
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);
        HashMap<String , Object> antidot;
        if (cursor.moveToFirst()) {
            do {
            	antidot = new HashMap<String, Object>();
            	antidot.put("sql_id", Integer.parseInt(cursor.getString(0)));
            	antidot.put("toxin", cursor.getString(1));
            	antidot.put("antidot", cursor.getString(2));
                antidotList.add(antidot);
            } while (cursor.moveToNext());
        }
        return antidotList;
    }    
}

Ich habe mit diesem Beispiel gearbeitet: Android..🙂: Search a Custom ListView in Android
 

Zurück
Oben