listData的选定项目在notifyDataSetChanged之后保持在同一位置

时间:2016-04-12 15:12:59

标签: android listview selector

我实现了一个简单的列表视图,其中包含一个选项,每次只选择一个项目,此功能正常工作。 我还有一个用于按Asc或Desc顺序对记录进行排序的按钮,当我选择一个记录时,在我对记录进行排序之后,旧记录的选择器保持在相同的旧位置,即使所选位置更新不同位置。

MainActivity:

    public class MainActivity extends Activity
{

    private ListView        _listView;
    private PersonAdapter   _adapter;
    private Button          _sortBtn;
    private List<Person>    _data;
    private int             _sort;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        _listView = (ListView) findViewById(R.id.list);
        _sortBtn = (Button) findViewById(R.id.sort_list_btn);

        _sort = 1;
        _data = new ArrayList<Person>();
        _data.add(new Person("abc", "defg", 1));
        _data.add(new Person("aaa", "defg", 12));
        _data.add(new Person("ccc", "defg", 13));
        _data.add(new Person("bb", "defg", 14));
        _data.add(new Person("aa", "defg", 144));
        _data.add(new Person("fff", "defg", 199));

        _adapter = new PersonAdapter(this, _data);
        _listView.setAdapter(_adapter);

        _sortBtn.setOnClickListener(new OnClickListener()
        {

            @Override
            public void onClick(View v)
            {
                Comparator<Person> sortById = Person.getComperatorByFirstName(_sort);
                Collections.sort(_data, sortById);

                _adapter.setData(_data);
                _sort = -_sort;
            }
        });

    }

    public static class Person
    {
        public String   _fName;
        public String   _lName;
        public int      _age;
        public boolean  _selected;

        public Person(String fName, String lName, int age)
        {
            _fName = fName;
            _lName = lName;
            _age = age;
        }

        public static Comparator<Person> getComperatorByFirstName(final int ascendingFlag)
        {
            return new Comparator<Person>()
            {
                @Override
                public int compare(Person patient1, Person patient2)
                {
                    return patient1._fName.compareTo(patient2._fName) * ascendingFlag;
                }
            };
        }

    }

}

listView适配器

public class PersonAdapter extends BaseAdapter
{

    private Context         _con;
    private List<Person>    _data;

    public PersonAdapter(Context context, List<Person> data)
    {
        _con = context;
        _data = data;
    }

    @Override
    public int getCount()
    {
        // TODO Auto-generated method stub
        return _data.size();
    }

    @Override
    public Person getItem(int position)
    {
        return _data.get(position);
    }

    @Override
    public long getItemId(int position)
    {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        Holder h = null;
        if (convertView == null)
        {
            h = new Holder();
            convertView = LayoutInflater.from(_con).inflate(R.layout.item_layout, parent, false);

            h._backgroundItem = (LinearLayout) convertView.findViewById(R.id.item_layout);
            h._fName = (TextView) convertView.findViewById(R.id.f_name);
            h._lName = (TextView) convertView.findViewById(R.id.l_name);
            h._age = (TextView) convertView.findViewById(R.id.age);
            convertView.setTag(h);
        }
        else
        {
            h = (Holder) convertView.getTag();
        }

        Person p = getItem(position);
        h._fName.setText(p._fName);
        h._lName.setText(p._lName);
        h._age.setText(String.valueOf(p._age));
        h._backgroundItem.setActivated(p._selected);



        return convertView;

    }


    public void setData(List<Person> data)
    {
        _data = data;
        notifyDataSetChanged();

    }

    private static class Holder
    {
        public LinearLayout _backgroundItem;
        public TextView     _fName;
        public TextView     _lName;
        public TextView     _age;
    }



}

项目布局:

  <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item_layout"
    android:layout_width="match_parent"
    android:layout_height="48dp"
    android:orientation="horizontal"
    android:background="@drawable/list_selector"
    android:weightSum="3" >

    <TextView
        android:id="@+id/f_name"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />

    <TextView
        android:id="@+id/l_name"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />

    <TextView
        android:id="@+id/age"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />

</LinearLayout>

我已经尝试过使用clearChoices但是在排序之后我根本看不到选择器,我也尝试将选择模式从单一模式更改为无,然后再单一但没有任何成功。

2 个答案:

答案 0 :(得分:1)

这是因为您正在切换列表项中的项目内容,但是单击被绑定到具有ListView的位置,因此它不会“更新”到项目的新位置。 我建议您在完成排序后以编程方式单击新项目。 获取所点击项目的ID

public int getItemPosition(long id)
{
    for (int position=0; position<mList.size(); position++)
        if (mList.get(position).getId() == id)
            return position;
    return 0;
}

然后在排序后点击

mList.performItemClick(
    mList.getAdapter().getView(mActivePosition, null, null),
    mActivePosition,
    mList.getAdapter().getItemId(mActivePosition));
希望它有所帮助!

答案 1 :(得分:0)

我建议在选择项目时存储所选项目的ID,并在订购数据集后,搜索该ID并重新选择它。