我有一個列表視圖,上面有一個搜索EditText。列表視圖中的每一行都由幾個文本和圖片組成。當用戶在搜索EditText中輸入關鍵字時,我希望用包含關鍵字的行更新列表視圖。我已經借用this的實現如下。使用自定義適配器在ListView中搜索關鍵字
我的自定義適配器:
public class CustomAdapter extends BaseAdapter implements Filterable {
private LayoutInflater inflater;
private ArrayList<CustomObject> objects;//mOriginalValues
private Activity activity;
private ArrayList<Bitmap> newsImageList;
private Context context;
private ArrayList<CustomObject> filteredObjects; // Values to be displayed after filtering
private class ViewHolder {
TextView titleTextView;
TextView dateTextView;
TextView bodyTextView;
ImageView logoView;
ImageView newsImageView;
ProgressBar progressBar;
}
public CustomAdapter(Context context, ArrayList<CustomObject> objects, Activity activity) {
// super(context, R.layout.news_item, objects);
inflater = LayoutInflater.from(context);
this.objects = objects;
this.filteredObjects=objects;
this.activity= activity;
this.newsImageList= new ArrayList<Bitmap>();
this.context= context;
for(int i=0; i<objects.size(); i++)
newsImageList.add(null);
}
@Override
public int getCount() {
return filteredObjects.size();
}
@Override
public CustomObject getItem(int position) {
return filteredObjects.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
System.out.println("IN GET VIEW");
ViewHolder holder = null;
if(convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.news_item, null);
holder.titleTextView = (TextView) convertView.findViewById(R.id.txtTitle);
holder.dateTextView = (TextView) convertView.findViewById(R.id.txtDate);
holder.bodyTextView = (TextView) convertView.findViewById(R.id.txtBody);
holder.logoView= (ImageView) convertView.findViewById(R.id.source_imageView);
holder.newsImageView= (ImageView) convertView.findViewById(R.id.news_imageView);
holder.progressBar= (ProgressBar) convertView.findViewById(R.id.img_progress_bar);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.titleTextView.setText(objects.get(position).getTitle());
holder.dateTextView.setText(objects.get(position).getDate());
holder.bodyTextView.setText(objects.get(position).getBody());
//for the source logo
String uri = "@drawable/"+objects.get(position).getSource_logo()+"_logo";
int imageResource = activity.getResources().getIdentifier(uri, null, activity.getPackageName());
Drawable res =activity.getResources().getDrawable(imageResource);
holder.logoView.setImageDrawable(res);
//the news image
String newsImageURL = objects.get(position).getNewsImageURL();
if(newsImageURL!=null) {
// show The Image in a ImageView
//pre-execute
holder.progressBar.setVisibility(View.VISIBLE);
holder.newsImageView.setVisibility(View.VISIBLE);
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) holder.bodyTextView.getLayoutParams();
params.addRule(RelativeLayout.BELOW, R.id.relative_container);
Picasso.with(context).load(newsImageURL).into(holder.newsImageView);//EXECUTE in background
holder.progressBar.setVisibility(View.INVISIBLE);//post-execute
}
else
{
System.out.println("NO IMAGE");
//adjusting the view
holder.progressBar.setVisibility(View.INVISIBLE);
holder.newsImageView.setVisibility(View.GONE);
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) holder.bodyTextView.getLayoutParams();
params.addRule(RelativeLayout.BELOW, R.id.txtDate);
}
return convertView;
}
@Override
public Filter getFilter() {
Filter filter = new Filter() {
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint,FilterResults results) {
filteredObjects = (ArrayList<CustomObject>) results.values; // has the filtered values
notifyDataSetChanged(); // notifies the data with new filtered values
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
System.out.println("FILTERING with the keyword:"+ constraint);
FilterResults results = new FilterResults(); // Holds the results of a filtering operation in values
ArrayList<Object> FilteredArrList = new ArrayList<Object>();
if (objects == null) {
objects = new ArrayList<CustomObject>(filteredObjects); // saves the original data in mOriginalValues
}
/********
*
* If constraint(CharSequence that is received) is null returns the mOriginalValues(Original) values
* else does the Filtering and returns FilteredArrList(Filtered)
*
********/
if (constraint == null || constraint.length() == 0) {
// set the Original result to return
results.count = objects.size();
results.values = objects;
} else {
constraint = constraint.toString().toLowerCase();
for (int i = 0; i < objects.size(); i++) {
System.out.println("loop "+i);
String title = objects.get(i).getTitle();
String date = objects.get(i).getDate();
String body = objects.get(i).getBody();
String source_logo = objects.get(i).getSource_logo();
String newsImageURL = objects.get(i).getNewsImageURL();
System.out.println("title of this item:"+title+", key word:"+constraint.toString());
if (title.contains(constraint.toString()) || date.contains(constraint.toString()) || body.contains(constraint.toString())) {
System.out.println("FOUND!");
FilteredArrList.add(new CustomObject(title,date, body, source_logo, newsImageURL));
}
}
// set the Filtered result to return
results.count = FilteredArrList.size();
results.values = FilteredArrList;
}
return results;
}
};
return filter;
}
}
class CustomObject {
private String title;
private String date;
private String body;
private String source_logo;
private String newsImageURL;
public CustomObject(String prop1, String prop2, String prop3, String prop4, String prop5) {
this.title = prop1;
this.date = prop2;
this.body=prop3;
this.source_logo=prop4;
this.newsImageURL=prop5;
}
public String getTitle() {
return title;
}
public String getDate() {
return date;
}
public String getBody(){
return body;
}
public String getSource_logo()
{
return source_logo;
}
public String getNewsImageURL(){ return newsImageURL; }
}
在我的活動:
我的動態XML文件:
<?xml version="1.0" encoding="utf-8"?>
<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"
>
<RelativeLayout
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
<EditText
android:id="@+id/news_search_editText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="البحث"
/>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/activity_main_swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/news_search_editText">
<ListView
android:id="@+id/activity_main_listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
</ListView>
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
<Button
android:text="تحديث ↑"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/refresh_button"
android:background="@drawable/button_refresh"
android:layout_alignParentTop="true"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:layout_marginTop="50dp"
/>
</RelativeLayout>
不幸的是,過濾的行爲是不正確的。雖然我可以在日誌中看到關鍵字與每行內容之間的比較是否正確完成,並且只有匹配關鍵字被添加到已過濾列表中,但更新列表並不正確。當我輸入列表中的關鍵字時,它會顯示列表中的前幾個項目(其中一些與關鍵字無關)並刪除其餘項目。當我輸入不在列表中的關鍵字時,它將清除列表視圖。因此,這種行爲是奇怪的和意外的。有人可以提出解決方案嗎?