Java customArrayAdapter搜索行-Android
我一直在试图解决这个问题,但在这里找不到任何答案。 我正在尝试使用ArrayAdapter为自定义arrayList创建EditText搜索 在我实际搜索一个对象(本项目中的命名产品)之前,一切都进展顺利。 当我搜索一个时,意味着我在编辑文本中输入字符,列表变为空白,我看不到任何项目 这是我的代码:Java customArrayAdapter搜索行-Android,java,android,android-arrayadapter,Java,Android,Android Arrayadapter,我一直在试图解决这个问题,但在这里找不到任何答案。 我正在尝试使用ArrayAdapter为自定义arrayList创建EditText搜索 在我实际搜索一个对象(本项目中的命名产品)之前,一切都进展顺利。 当我搜索一个时,意味着我在编辑文本中输入字符,列表变为空白,我看不到任何项目 这是我的代码: SearchActivity , receiving the ArrayList from the mainactivity : public class SearchActivity
SearchActivity , receiving the ArrayList from the mainactivity :
public class SearchActivity extends Activity {
EditText editSearch;
ProductArrayAdapter productsAdapter;
ListView products;
static ArrayList<Product> viewList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
viewList = new ArrayList<Product>(MainActivity.listToBeSent);
Toast.makeText(getBaseContext(), viewList.get(1).getName(), Toast.LENGTH_LONG).show();
productsAdapter = new ProductArrayAdapter(this,
R.layout.layout_product, viewList);
products = (ListView) findViewById(R.id.listProducts);
products.setAdapter(productsAdapter);
editSearch = (EditText)findViewById(R.id.searchLine);
editSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String charsToSearch = editSearch.getText().toString().toLowerCase(Locale.getDefault());
productsAdapter.filter(charsToSearch);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable s) {
String charsToSearch = editSearch.getText().toString().toLowerCase(Locale.getDefault());
productsAdapter.filter(charsToSearch);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.search, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
在ProductArrayAdapter上,我将getView()方法更改为:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewContainer viewContainer;
//View rowView = convertView;
// means that if it is the first time and we didn't yet inflate the
// view, so inflate it now. rowView gets the already built or non-exist
// convertView.
if (convertView == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
convertView = inflater.inflate(resource, parent, false);
viewContainer = new ViewContainer();
viewContainer.txtName = (TextView) convertView
.findViewById(R.id.txtName);
viewContainer.txtDescription = (TextView) convertView
.findViewById(R.id.txtDescription);
viewContainer.txtPrice = (TextView) convertView
.findViewById(R.id.txtPrice);
viewContainer.imgProduct = (ImageView) convertView
.findViewById(R.id.productPic);
viewContainer.imgOnSale = (ImageView) convertView
.findViewById(R.id.onSaleImage);
// adding tag to each rowView , tag can be Object therefore
// viewContainer = Object.
convertView.setTag(viewContainer);
} else {
viewContainer = (ViewContainer) (convertView.getTag());
}
viewContainer.txtName.setText(products.get(position).getName());
viewContainer.txtDescription.setText(products.get(position).getDescription());
viewContainer.txtPrice.setText("Price: " + (products.get(position).getPrice().toString()));
viewContainer.imgProduct.setImageResource(products.get(position).getImage());
viewContainer.imgOnSale.setImageResource(R.drawable.logo_icon);
return convertView;
}
有什么想法吗?删除您的
筛选方法。这不是处理适配器过滤的正确方法。ArrayAdapter
已经支持基本的过滤机制。简单地做:
productsAdapter.getFilter.filter(charsToSearch);
对于存储在适配器中的每个产品,它将执行以下操作:
singleProduct.toString().toLowerCase().startsWith(charsToSearch);
如果startsWith()
逻辑对您有效,一个快速有效的解决方案是重写Product
类的toString()
方法,并让它返回getName()
。否则,如果您想为过滤逻辑提供更自定义的解决方案,实际上只有两种解决方案可用:
使用BaseAdapter
从头开始编写您自己的适配器,并让它实现Filterable
接口。虽然一个非常基本的实现并不太糟糕,但如果您以前从未这样做过,它可能会让人望而生畏
利用一个允许您添加自己的过滤逻辑的现有数据库
还要注意的是,在使用ArrayAdapter
时,将自己的列表副本保留在使用super构建的列表之外是非常危险的。特别是当涉及到过滤时。无法保证用于构造适配器的列表与外部引用的列表相同。进一步阅读
对于getView()
方法,请确保使用getItem(position)
而不是直接引用产品。把祝酒
放在里面也不是个好主意。显示列表时,您将看到大量的祝酒词同时弹出。如果需要调试语句,请改用Log
。此外,还需要调整以下行:
rowView = inflater.inflate(resource, null);
viewContainer = new ViewContainer();
对此,请改为:
viewContainer = inflater.inflate(resouce, parent, false);
您根本不需要该rowView
变量。只需从方法中完全删除并替换为viewContainer
。否则,您的getView()
方法看起来不错。谢谢Jay,让我离解决方案更近了一步!我编辑了我的问题,在代码上做了一些修改,并加入了新的问题。不同的字母会产生不同的结果吗?您是否以任何方式修改适配器?Product
toString()方法返回什么?
rowView = inflater.inflate(resource, null);
viewContainer = new ViewContainer();
viewContainer = inflater.inflate(resouce, parent, false);