onItemClick给出可见页面上项目的索引/位置...不是列表中项目的实际索引..启用setTextFilterEnabled时的项目

时间:2010-03-26 08:00:41

标签: android sqlite listview indexing position

我正在创建一个列表..列表的元素是从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);

我有什么方法可以获得该项目的原始索引/位置,而不是过滤后的文本中显示的那个...过滤后。

7 个答案:

答案 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循环将单击列表项的内容与数组中的所有名称进行比较。 。这样可以在过滤后的搜索列表中检索单击项的正确位置,而不是在同一位置错误地打开原始列表项的详细信息。