使用带有文本和图像的自定义适配器在列表视图中搜索
Posted
技术标签:
【中文标题】使用带有文本和图像的自定义适配器在列表视图中搜索【英文标题】:Searching in a listview using a Custom Adapter with text and images 【发布时间】:2018-06-14 20:15:39 【问题描述】:我正在我的应用程序中配置资源以使用自定义适配器在列表视图中搜索。我在 addTextChangedListener 事件中使用 EditText 键入字符串并将文本传递给适配器,但它不起作用。
我使用“implements Filterable”配置适配器并使用“.setTextFilterEnabled(true)”启用Listview,但不起作用。
我看到我必须实现“public Filter getFilter()”,但我不知道该怎么做。
当我在 EditText 中键入一些单词时,例如“cel”或“12”,过滤器会起作用,但结果始终相同:Listview 中的前两项,无论 Listview 中的内容是什么(内容listview 是随机的)。
在我的 Fragment Activity 的 sn-p 下方:
public class VideosFragment extends Fragment
private ListView listView;
private ArrayList<String> idVideo = new ArrayList<>();
private ArrayList<String> titleVideo = new ArrayList<>();
private ArrayList<String> descVideo = new ArrayList<>();
private ArrayList<String> urlVideo = new ArrayList<>();
private ArrayList<String> channelTitle = new ArrayList<>();
private ArrayList<String> canalTitle = new ArrayList<>();
private ArrayList<String> canalId = new ArrayList<>();
private CustomFiltraCanaisAdapter customFiltraCanaisAdapter;
private EditText editText;
CustomVideoAdapter customVideoAdapter;
public VideosFragment()
// Required empty public constructor
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_videos, container, false);
// Configure Listview
listView = (ListView)view.findViewById(R.id.listView_videos);
//Create search parameters
editText = (EditText) view.findViewById(R.id.searchList);
listView.setTextFilterEnabled(true);
editText.addTextChangedListener(new TextWatcher()
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2)
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2)
String text = editText.getText().toString().toLowerCase(Locale.getDefault());
VideosFragment.this.customVideoAdapter.getFilter().filter(text);
@Override
public void afterTextChanged(Editable editable)
);
在我的 CustomAdapter 下方:
public class CustomVideoAdapter extends ArrayAdapter<String> implements Filterable
private final Activity context;
private final ArrayList<String> videoTitle;
private final ArrayList<String> videoDesc;
private final ArrayList<String> videoId;
private final ArrayList<String> channelTitle;
private final ArrayList<String> imgurl;
public CustomVideoAdapter(Activity context, ArrayList<String> videoTitle,
ArrayList<String> videoId,
ArrayList<String> channelTitle,
ArrayList<String> imgurl,
ArrayList<String> videoDesc)
super(context, R.layout.custom_lista_videos, videoTitle);
// TODO Auto-generated constructor stub
this.context = context;
this.videoTitle = videoTitle;
this.videoDesc = videoDesc;
this.videoId = videoId;
this.channelTitle = channelTitle;
this.imgurl = imgurl;
public View getView(int position,View view,ViewGroup parent)
LayoutInflater inflater=context.getLayoutInflater();
View rowView=inflater.inflate(R.layout.custom_lista_videos, null,true);
TextView txtTitle = (TextView) rowView.findViewById(R.id.txtVideoTitle);
ImageView imgPhoto = (ImageView) rowView.findViewById(R.id.imgPhoto);
TextView txtChannelTitle = (TextView) rowView.findViewById(R.id.txtChannelTitle);
TextView txtVideoId = (TextView) rowView.findViewById(R.id.txtVideoId);
TextView txtVideoDesc = (TextView) rowView.findViewById(R.id.txtVideoDesc);
txtTitle.setText(videoTitle.get(position));
Picasso.with(context).load(imgurl.get(position)).into(imgPhoto);
txtChannelTitle.setText(channelTitle.get(position));
txtVideoId.setText(videoId.get(position));
txtVideoDesc.setText(videoDesc.get(position));
return rowView;
;
缺少什么?
经过一些帮助后,我尝试创建(和使用)一个模型类,但我仍然没有任何进展,因为我不知道如何必须更改“CustomAdapter”上的代码才能正确使用此代码。
我的模型类如下:
公共类 FilteredVideoAdapter
private ArrayList<String> storedVideoTitle = null;
private ArrayList<String> storedVideoDesc = null;
private ArrayList<String> storedVideoId = null;
private ArrayList<String> storedChannelTitle = null;
private ArrayList<String> storedImgurl = null;
public FilteredVideoAdapter()
public ArrayList<String> getStoredVideoTitle()
return storedVideoTitle;
public void setStoredVideoTitle(ArrayList<String> storedVideoTitle)
this.storedVideoTitle = storedVideoTitle;
public ArrayList<String> getStoredVideoDesc()
return storedVideoDesc;
public void setStoredVideoDesc(ArrayList<String> storedVideoDesc)
this.storedVideoDesc = storedVideoDesc;
public ArrayList<String> getStoredVideoId()
return storedVideoId;
public void setStoredVideoId(ArrayList<String> storedVideoId)
this.storedVideoId = storedVideoId;
public ArrayList<String> getStoredChannelTitle()
return storedChannelTitle;
public void setStoredChannelTitle(ArrayList<String> storedChannelTitle)
this.storedChannelTitle = storedChannelTitle;
public ArrayList<String> getStoredImgurl()
return storedImgurl;
public void setStoredImgurl(ArrayList<String> storedImgurl)
this.storedImgurl = storedImgurl;
public FilteredVideoAdapter withFilteredVideoAdapter(
ArrayList<String> storedVideoTitle,
ArrayList<String> storedVideoDesc,
ArrayList<String> storedVideoId,
ArrayList<String> storedChannelTitle,
ArrayList<String> storedImgurl)
this.storedVideoTitle = storedVideoTitle;
this.storedVideoDesc = storedVideoDesc;
this.storedVideoId = storedVideoId;
this.storedChannelTitle = storedChannelTitle;
this.storedImgurl = storedImgurl;
return this;
【问题讨论】:
您到底想在 listView 中搜索什么?是视频标题吗 @RahulChandrabhan,是的!但我需要在 VideoTitle 上进行过滤,但有关过滤视频的其他信息必须与之相关联。 lib4 发布的解决方案适用于 VideoTitle,但缺少 Listview 上的信息,如 VideoID、VideoDesc 等。 您必须为您的视频信息创建一个pojo,以便所有数据相互绑定并且易于使用,不要为每个信息创建单独的arraylist 【参考方案1】:这是您必须在适配器内部执行的操作,您可能需要进行一些调整:-
@Override
public Filter getFilter()
return new Filter()
@Override
protected FilterResults performFiltering(CharSequence constraint)
FilterResults results = new FilterResults();
// If the constraint (search string/pattern) is null
// or its length is 0, i.e., its empty then
// we just set the `values` property to the
// original contacts list which contains all of them
if (constraint == null || constraint.length() == 0)
results.values = videoTitle;;
results.count = videoTitle.size();
else
// Some search copnstraint has been passed
// so let's filter accordingly
ArrayList<String> filteredTitle = new ArrayList<String>();
// We'll go through all the title and see
// if they contain the supplied string
for (String c : string)
if (string.toUpperCase().contains( constraint.toString().toUpperCase() ))
// if `contains` == true then add it
// to our filtered list
filteredTitle.add(c);
// Finally set the filtered values and size/count
results.values = filteredTitle;
results.count = filteredTitle.size();
// Return our FilterResults object
return results;
@Override
protected void publishResults(CharSequence constraint, FilterResults results)
mList = (ArrayList<String>) results.values;
notifyDataSetChanged();
;
希望这会对你有所帮助。
【讨论】:
虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review @zapping 编辑了我的答案,添加了如何做的示例。欢迎投票。 @lib4,我做了一些调整:: " for (String c : videoTitle) if (c.toLowerCase().contains( constraint.toString().toLowerCase() ))" 并添加“ArrayList你可以在不使用过滤器的情况下做到这一点,试试这个代码
您的活动代码
vendorSearchEt.addTextChangedListener(new TextWatcher()
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after)
@Override
public void onTextChanged(CharSequence s, int start, int before, int count)
@Override
public void afterTextChanged(Editable s)
if (vendorSearchEt.getText().toString().length() == 0)
if (vendorsListAdapter != null)
vendorsListAdapter.filter("");
else
String text = vendorSearchEt.getText().toString().toLowerCase(Locale.getDefault());
if (vendorsListAdapter != null)
vendorsListAdapter.filter(text);
);
适配器类
public class VendorsListAdapter extends BaseAdapter
// Declare Variables \\
Context mContext;
LayoutInflater inflater;
private List<VendorsList> vendorsLists = null;
private ArrayList<VendorsList> arrayListVendorsList = null;
AppCompatActivity act;
public VendorsListAdapter(Context context,
List<VendorsList> vendorsLists)
mContext = context;
this.vendorsLists = vendorsLists;
arrayListVendorsList = new ArrayList<>(vendorsLists);
inflater = LayoutInflater.from(mContext);
act = (AppCompatActivity) context;
public class ViewHolder
TextView vendorNameTv;
@Override
public int getCount()
return vendorsLists.size();
@Override
public VendorsList getItem(int position)
return vendorsLists.get(position);
@Override
public long getItemId(int position)
return position;
public View getView(final int position, View view, ViewGroup parent)
final ViewHolder holder;
if (view == null)
holder = new ViewHolder();
view = inflater.inflate(R.layout.lv_items_vendors_list, null);
holder.vendorNameTv = view.findViewById(R.id.lv_items_vendors_name_tv);
holder.vendorNameTv.setTypeface(StaticMethods.customFont(act, "Quicksand-Regular.otf"));
view.setTag(holder);
else
holder = (ViewHolder) view.getTag();
holder.vendorNameTv.setText(vendorsLists.get(position).getVendorName());
return view;
/**
* Filter Class for item searching
*
* @param charText Text to be searched
*/
public void filter(String charText)
charText = charText.toLowerCase(Locale.getDefault());
vendorsLists.clear();
if (charText.length() == 0)
vendorsLists.addAll(arrayListVendorsList);
else
for (VendorsList vendorsList : arrayListVendorsList)
if (vendorsList.getVendorName().toLowerCase(Locale.getDefault())
.contains(charText))
vendorsLists.add(vendorsList);
notifyDataSetChanged();
【讨论】:
以上是关于使用带有文本和图像的自定义适配器在列表视图中搜索的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 glide* 使用数组列表中的自定义适配器将图像设置为列表视图