我正在创建一个列表..列表的元素是从sqlite数据库中提取的。我使用ArrayList和ArrayAdapter填充列表...单击列表中的项目我希望能够触发包含有关项目的信息点击...信息,如项目的索引号..
使用方法: onItemClick(AdapterView av,View v,int index,long arg)
我确实点击了该项目的索引。但它是当前显示的列表。问题出现在我做setFilterTextEnabled(true)时,并在应用程序中键入一些文本来搜索某个项目..然后单击它..而不是给我原始列表中项目的索引它给了我索引在筛选列表..
以下是代码片段:
myListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> av, View v, int index, long arg) {
Intent lyricsViewIntent = new Intent(iginga.this, LyricsPage.class);
lyricsViewIntent.putExtra("title", songList.get((int)arg).getTitle());
lyricsViewIntent.putExtra("id", songList.get((int)arg).getSongId());
startActivity(lyricsViewIntent);
}
});
myListView.setTextFilterEnabled(true);
我有什么方法可以获得该项目的原始索引/位置,而不是过滤后的文本中显示的那个...过滤后。
答案 0 :(得分:9)
我最近对这个问题进行了一些摔跤,解决方案结果相当简单。您可以使用getListAdapter()
上的ListActivity
检索“可见列表”,这会反映列表的当前过滤视图。
例如,在ListActivity
子类的onCreate()
:
final ListView listView = getListView();
final ListAdapter listAdapter = getListAdapter();
listView .setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
MyClass item = (MyClass) listAdapter .getItem(position);
// now do something with that item
}
});
因此,请忽略您放入列表适配器的“原始”列表,而是在每次事件发生时从适配器请求列表。
答案 1 :(得分:5)
阿比纳夫我完全理解你的问题,因为过去两天我一直在努力解决同样的问题。我没有意识到“int position”和“int id”的值会在您使用软键盘过滤数据时发生变化,直到我开始在调试器上使用断点。希望此代码可以让您更好地了解如何解决问题。我最后编写了一个for循环,以便我可以将过滤列表的toString()与未过滤列表的toString()进行匹配。这样我可以检索/更正“int position”值。
public class FacultyActivity extends ListActivity
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Retrieves the array stored in strings.xml
final String[] facultyList1 = getResources().getStringArray(R.array.professor_name);
final String[] facultyList2 = getResources().getStringArray(R.array.professor_email);
// Develop an array based on the list_view.xml template
setListAdapter(new ArrayAdapter<String>(this, R.layout.faculty, facultyList1));
final ListView lv = getListView();
// Allow the user to filter the array based on text input
lv.setTextFilterEnabled(true);
// Handle the user event where the user clicks on a professor's name
lv.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
/* Filtering text changes the size of the array[index]. By clicking on a filtered
* entry the int position and long id does not correlate to the original array list.
* This block of code will search the original array based on the toString() function
* and for loop the orignial array to find the matching string, retrieving the
* correct index/position.
*/
String name = lv.getItemAtPosition(position).toString();
for (int index = 0; index < facultyList1.length; index++)
{
if (name.equals(facultyList1[index]))
{
position = index;
break;
}
}
Bundle bundle = new Bundle();
bundle.putString("email", facultyList2[position]);
startActivity(new Intent(FacultyActivity.this, EmailActivity.class).putExtras(bundle));
}
});
}
}
答案 2 :(得分:1)
执行此操作的方法之一可能是在绘制视图时使用其索引标记视图View#setTag()
并在需要时使用View#getTag()
答案 3 :(得分:1)
我认为这是一个应该修复的错误:例如,如果您在条目号150上单击(使用鼠标),则会返回条目名称150和ID为150.但如果您输入字符这会让你输入150回来,它是你输入的相同字符的三个中的第一个,你得到0和条目0的名称(当然在原始列表中你不是你想要的)。这应该返回条目150的id和名称,如果过滤了,并且必须做abhinav上面所做的事情(尽管对我有用而且很有用),在我不太谦虚的意见中是克服的。
答案 4 :(得分:0)
在Adapter类中,使用以下代码覆盖以下方法。
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getPosition(StateFlower item) {
return allItemsArray.indexOf(item);
}
@Override
public StateFlower getItem(int arg0) {
return allItemsArray.get(arg0);
}
答案 5 :(得分:0)
我刚刚为同样的问题找到了一个简单的解决方案。
第一个问题,在您的适配器中,您使用的是ArrayList&lt;串GT;或String []?
尝试创建一个类来保存所需的信息
然后,使用ArrayList&lt; DataHoldingClass&gt;在适配器中。
例如:
public class DataHoldingClass {
private Integer id;
private String name;
public DataHoldingClass(Integer id,String name){
this.id=id;
this.name=name;
}
public Integer getDataId(){
return id;
}
@Override
public String toString() {
return name;
}
//implements getters and setters to name and other fields if you want
}
有必要覆盖toString()方法,以便适配器知道列表中显示的信息。 然后,代码中的某个地方:
ArrayList< DataHoldingClass> info = new ArrayList<DataHoldingClass>();
info.add( new DataHoldingClass(id,name) ) //here you populate the ArrayList with the desired informations to be showed at List
adapter = new ArrayAdapter< DataHoldingClass>(context,
android.R.layout.simple_dropdown_item_1line, info);`
并且芬兰:
`@Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
Log.d(" arg2 ="+arg2+" arg3="+arg3+" Real id ="+((DataHoldingClass)arg0.getAdapter().getItem(arg2)).getDataId(),"");
}
它对我有用。 希望我能帮到你。
答案 6 :(得分:0)
我花费了数小时试图找到解决此过滤器问题的方法,因此,如果其他任何人都在挣扎,这是对我有用的内容的快速总结。
使用Arthur的答案中的一些代码:
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String name = lv.getItemAtPosition(position).toString();
for (int index = 0; index < facultyList1.length; index++)
{
if (name.equals(facultyList1[index]))
{
position = index;
break;
}
}
}
并结合最佳答案here 在相同的onItemClick上创建此功能代码:
/* Filtering text changes the size of the array[index]. By clicking on a filtered
* entry the int position changes, taking you to the details of food in the original
* list's details. This block of code will take FoodsData, which contains all of the
* textviews within a list item, and compare the contents of the chosen filtered list item
* with every food name within foodsArray by using a loop, retrieving the correct index/position.
* But this was the most important answer that helped me get it working in my code:
* https://stackoverflow.com/questions/11164543/how-to-extract-objects-from-listview-getitematposition-wont-work
*/
FoodsData chosenFilteredListItem = (FoodsData) (lv.getItemAtPosition(position));
String chosenFilteredListItemFoodName = chosenFilteredListItem.getFoodName();
for (int index = 0; index < foodsArray.length; index++)
{
if (chosenFilteredListItemFoodName.equals(foodsArray[index]))
{
position = index;
}
}
正如我在代码中的注释所说,这采用了称为FoodsData的类,该类描述单个列表项中的各种textview,并通过使用for循环将单击列表项的内容与数组中的所有名称进行比较。 。这样可以在过滤后的搜索列表中检索单击项的正确位置,而不是在同一位置错误地打开原始列表项的详细信息。