问题
i´m newbie in android programming and try to implement getFilter() into my custom ArrayAdapter an filter the List by Name. I have not found any example that matches with my adapter.
Can someone help me with an example please (with my code), thx!!!
Maybe there is another possibility to filter the List?
java code:
public class c_DTArtikel_allforsearch extends Activity implements AdapterView.OnItemClickListener {
private ListView ListViewLayout;
private EditText search;
private String[] Name;
private String[] Number;
private int[] ImagesID;
private ArrayList<Article> articleList = new ArrayList<Article>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_lv_search);
Resources res = getResources();
String[] saugname = res.getStringArray(R.array.SauglanzeName);
String[] pumpmname = res.getStringArray(R.array.PumpMName);
String[] saugnummer = res.getStringArray(R.array.SauglanzeNumber);
String[] pumpmnummer = res.getStringArray(R.array.PumpMNummer);
TypedArray saugimg = res.obtainTypedArray(R.array.SauglanzeImg);
TypedArray pumpmimg = res.obtainTypedArray(R.array.PumpeMImg);
ArrayList<String> name = new ArrayList<String>();
name.addAll(Arrays.asList(saugname));
name.addAll(Arrays.asList(pumpmname));
Name = name.toArray(new String[saugname.length+pumpmname.length]);
ArrayList<String> number = new ArrayList<String>();
number.addAll(Arrays.asList(saugnummer));
number.addAll(Arrays.asList(pumpmnummer));
Number = number.toArray(new String[saugnummer.length+pumpmnummer.length]);
ArrayList<Integer> imgInts = new ArrayList<Integer>();
int nr = -1;
while ( ++nr < saugimg.length() )
imgInts.add (saugimg.getResourceId(nr, 0));
nr = -1;
while ( ++nr < pumpmimg.length() )
imgInts.add (pumpmimg.getResourceId(nr, 0));
ImagesID = new int[imgInts.size()];
for (int i=0; i < imgInts.size(); i++)
{
ImagesID[i] = ((Integer) imgInts.get(i)).intValue();
}
Search = (EditText) findViewById(R.id.EditTextSearch);
ListViewLayout = (ListView) findViewById(R.id.listViewLayoutSearch);
final TIAdapter adapter = new TIAdapter(articleList, this);
ListViewLayout.setAdapter(adapter);
ListViewLayout.setOnItemClickListener(this);
//has been missing
for (int i = 0; i < Name.length; i++)
{
Article a = new Article(Name[i], Number[i], ImagesID[i]);
// Binds all strings into an array
articleList.add(a);
}
// Add Text Change Listener to EditText
search.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
adapter.resetData();
}
adapter.getFilter().filter(s.toString());
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
Class Article
public class Article {
public String Name;
public String Number;
public int ImagesID;
public Article(String Name, String Number, int ImagesID) {
this.Name = Name;
this.Number = Number;
this.ImagesID = ImagesID;
}
public String getName() {
return Name;
}
public void setName(String name) {
this.Name = Name;
}
public String getNumber() {
return Number;
}
public void setNumber(String number) {
this.Name = Number;
}
public int getImgID() {
return ImagesID;
}
public void setImgID(int imgID) {
this.ImagesID = ImagesID;
}
}
Class custom adapter:
class TIAdapter extends ArrayAdapter<Article> implements Filterable {
private List<Article> articleList;
private Context context;
private Filter articleFilter;
private List<Article> origArticleList;
TIAdapter(List<Article> articleList, Context ctx) {
super (ctx, R.layout.layout_text_image, articleList);
this.articleList = articleList;
this.context = ctx;
this.origArticleList = articleList;
}
public int getCount() {
return articleList.size();
}
public Article getItem(int position) {
return articleList.get(position);
}
public long getItemId(int position) {
return articleList.get(position).hashCode();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
ArticleHolder holder = new ArticleHolder();
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.layout_text_image, null);
// Now we can fill the layout with the right values
holder.textViewArtikel = (TextView) v.findViewById(R.id.textViewArtikel);
holder.textViewArtikelNummer = (TextView) v.findViewById(R.id.textViewArtikelNummer);
holder.imageViewArtikel = (ImageView) v.findViewById(R.id.imageViewArtikel);
v.setTag(holder);
}
else {
holder = (ArticleHolder) v.getTag();
holder.imageViewArtikel = (ImageView) v.findViewById(R.id.imageViewArtikel);
DecodeTask dt1 = (DecodeTask)holder.imageViewArtikel.getTag(R.id.imageViewArtikel);
if(dt1 != null)
dt1.cancel(true);
}
final Article n = articleList.get(position);
holder.imageViewArtikel.setImageBitmap(null);
DecodeTask dt2 = new DecodeTask(getContext(), holder.imageViewArtikel, n.getImgID());
dt2.execute();
holder.textViewArtikel.setText(n.getName());
holder.textViewArtikelNummer.setText(n.getNumber());
holder.imageViewArtikel.setTag(n.getImgID(), dt2);
return v;
}
public void resetData() {
articleList = origArticleList;
}
private class ArticleHolder {
TextView textViewArtikel;
TextView textViewArtikelNummer;
ImageView imageViewArtikel;
}
@Override
public Filter getFilter() {
if (articleFilter == null)
articleFilter = new ArticleFilter();
return articleFilter;
}
private class ArticleFilter 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 = origArticleList;
results.count = origArticleList.size();
}
else {
// We perform filtering operation
List<Article> nArticleList = new ArrayList<Article>();
for (Article a : articleList) {
if (a.getName().toLowerCase().contains(constraint.toString().toLowerCase()))
nArticleList.add(a);
}
results.values = nArticleList;
results.count = nArticleList.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 {
articleList = (List<Article>) results.values;
notifyDataSetChanged();
}
}
}
}
}
}
here is the code from old getView();
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ImageView imageView = null;
if(row == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.layout_text_image, parent, false);
imageView = (ImageView)row.findViewById(R.id.imageViewArtikel);
}
else {
imageView = (ImageView)row.findViewById(R.id.imageViewArtikel);
DecodeTask dt1 = (DecodeTask)imageView.getTag(R.id.imageViewArtikel);
if(dt1 != null)
dt1.cancel(true);
}
imageView.setImageBitmap(null);
DecodeTask dt2 = new DecodeTask(getContext(), imageView, ImagesID[position]);
dt2.execute();
TextView textViewArtikel = (TextView) row.findViewById(R.id.textViewArtikel);
TextView textViewArtikelNummer = (TextView) row.findViewById(R.id.textViewArtikelNummer);
imageView.setTag(R.id.imageViewArtikel, dt2);
textViewArtikel.setText(Name[position]);
textViewArtikelNummer.setText(Number[position]);
return row;
}
decode Task
public class DecodeTask extends AsyncTask<String, Void, Bitmap> {
Context mContext;
ImageView v;
int resId;
public DecodeTask(Context context, ImageView iv, int res_id) {
mContext = context;
v = iv;
resId = res_id;
}
protected Bitmap doInBackground(String... params) {
return decodeBitmapFromResource(resId, 300, 300);
}
protected void onPostExecute(Bitmap result) {
v.setImageBitmap(result);
}
private Bitmap decodeBitmapFromResource(int resId, int reqWidth, int reqHeight) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(mContext.getResources(), resId, options);
options.inJustDecodeBounds = false;
Bitmap bmp = BitmapFactory.decodeResource(mContext.getResources(), resId, options);
return bmp;
}
}
Error logcat:
05-03 10:56:43.922 28792-28792/com.kreussler.krapp E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
at com.kreussler.krapp.c_DTArtikel_allforsearch$TIAdapter.getView(c_DTArtikel_allforsearch.java:286)
at android.widget.AbsListView.obtainView(AbsListView.java)
at android.widget.ListView.measureHeightOfChildren(ListView.java)
at android.widget.ListView.onMeasure(ListView.java)
at android.view.View.measure(View.java)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java)
at android.view.View.measure(View.java)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java)
at android.widget.FrameLayout.onMeasure(FrameLayout.java)
at android.view.View.measure(View.java)
at android.widget.LinearLayout.measureVertical(LinearLayout.java)
at android.widget.LinearLayout.onMeasure(LinearLayout.java)
at android.view.View.measure(View.java)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java)
at android.widget.FrameLayout.onMeasure(FrameLayout.java)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java)
at android.view.View.measure(View.java)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java)
at android.view.Choreographer.doCallbacks(Choreographer.java)
at android.view.Choreographer.doFrame(Choreographer.java)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java)
at android.os.Handler.handleCallback(Handler.java)
at android.os.Handler.dispatchMessage(Handler.java)
at android.os.Looper.loop(Looper.java)
at android.app.ActivityThread.main(ActivityThread.java)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java)
at dalvik.system.NativeStart.main(Native Method)
回答1:
As I found your problem interesting I made an activity with your code. The biggest problem I faced was where to get about 250 images. I first wanted to ask you but than managed to resize 306 pictures to 100x100 and put them in the drawable folder. Here is the changed getView().
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
ArticleHolder holder = new ArticleHolder();
final Article n = articleList.get(position);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.activity_sergej_lazy_res_listitem, null);
holder.textViewArtikel = (TextView) v.findViewById(R.id.textViewArtikel);
holder.textViewArtikelNummer = (TextView) v.findViewById(R.id.textViewArtikelNummer);
holder.imageViewArtikel = (ImageView) v.findViewById(R.id.imageViewArtikel);
v.setTag(holder);
}
else {
holder = (ArticleHolder) v.getTag();
DecodeTask dt1 = (DecodeTask)holder.imageViewArtikel.getTag( );
if(dt1 != null)
dt1.cancel(true);
}
holder.textViewArtikel.setText(n.getName());
holder.textViewArtikelNummer.setText(n.getNumber());
holder.imageViewArtikel.setImageBitmap(null);
DecodeTask dt2 = new DecodeTask(getContext(), holder.imageViewArtikel, n.getImgID(), position );
holder.imageViewArtikel.setTag(dt2);
dt2.execute();
return v;
}
As images of 100x100 were used there is no need to resize them. Here the changed AsyncTask:
public class DecodeTask extends AsyncTask<String, Void, Bitmap> {
Context mContext;
ImageView v;
int resId;
Bitmap bitmap = null;
int position;
public DecodeTask(Context context, ImageView iv, int res_id, int _position ) {
mContext = context;
v = iv;
resId = res_id;
position = _position;
v.setTag( this);
}
protected Bitmap doInBackground(String... params) {
bitmap = BitmapFactory.decodeResource(mContext.getResources(), resId);
return null;
}
protected void onPostExecute(Bitmap result) {
if( position < ListViewLayout.getFirstVisiblePosition() || position > ListViewLayout.getLastVisiblePosition())
return;
if ( v.getTag() == this )
v.setImageBitmap(bitmap);
}
}
来源:https://stackoverflow.com/questions/23341241/implementing-getfilter-into-custom-arrayadapter-with-asynctask