首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OnItemSelectedListener、ListView和物品回收

OnItemSelectedListener、ListView和物品回收
EN

Stack Overflow用户
提问于 2013-07-31 19:37:05
回答 2查看 5.2K关注 0票数 1

我在一个ListView中有一堆东西。每个项目包含几个可编辑的视图。我想保存用户对这些所做的更改。保存发生的事件是项目失去焦点时发生的。

我目前认为有两种方式:

代码语言:javascript
复制
    View.OnFocusChangeListener() with  onFocusChange(View v, boolean hasFocus)

这是可行的,但是混乱的,因为每个项目包含几个可编辑的视图。当整个项目失去焦点时,我宁愿节省下来。到目前为止,我试图简化的只是一些复杂的事情。

如果有一个OnItemDeSelectedListener,它将是完美的,但只有相反的情况:

代码语言:javascript
复制
    AdapterView.OnItemSelectedListener() with onItemSelected(AdapterView<?> adapterView, View view, int i, long l)

从表面上看,这看起来不错。我只是创建变量lastSelectedView,以便知道最后选择的(取消选择的)项是什么。问题在于ListView如何回收视图。我认为不能保证适配器没有回收lastSelectedView,因此改变了它所包含的数据。这是否合理的假设呢?

是否有合理的方法来解决OnItemSelectedListener?的回收视图问题?

EN

回答 2

Stack Overflow用户

发布于 2013-08-02 21:47:40

如果使用单个选择,则选择另一项将“取消选择”当前项。此时,您可以将更改应用到适配器中的项目的本地存储副本。我不认为您应该使用onItemSelected()或onItemDeselected()中传递的视图作为已编辑数据的模型。正如我所说的,最好创建当前正在编辑的适配器数据类型的项,并且在onSelectedListener()中,您可以将从编辑的项更改应用到适配器中的相应项。就像这样:

代码语言:javascript
复制
    ListView myListView;
    Object objectCurrentlyEditing;
    int positionCurrentlyEditing;
    myListView.setOnItemSelectedListener(new OnItemSelectedListener(){

        @Override
        public void onItemSelected(AdapterView<?> arg0, View arg1,
                int position, long arg3) 
        {
            myListView.getAdapter().getItem(positionCurrentlyEditing).update(objectCurrentlyEditing);

            positionCurrentlyEditing = position;
            objectCurrentlyEditing = myListView.getAdapter().getItem(position);
        }

        @Override
        public void onNothingSelected(AdapterView<?> arg0) {
            // TODO Auto-generated method stub

        }
    });

update函数是列表项在不再被选中后如何保存的。但是,此方法假设您使用的是单一选择模式。

票数 0
EN

Stack Overflow用户

发布于 2013-10-08 13:58:35

我的答案与这里的其他答案相似,试图以不同的方式解决回收问题--这将是一个有点循环的问题,所以请读两遍:在onItemSelected中,首先使用您在上一次调用onItemSelected时保存的数据。而不是将数据从当前视图(作为参数发送到onItemSelected )保存到要在下一次调用onItemSelected时使用的最终变量或字段。

例如,下面是一个模型对象:公共类YourModelObject{ public YourModelObject(String dataString,int dataInt){ this.dataString = dataString;this.dataInt = dataInt;}私有字符串dataString;私有int dataInt;//这里是一些getter、setter和方法.}

下面是显示它的列表视图:

代码语言:javascript
复制
ListView myListView;

ArrayList<YourModelObject> listOfModelObjects;
//somewhere before onItemSelected listOfModelObjects is initialized with data

final YourModelObject lastItemData; //this can either be final, or an instance variable.

myListView.setOnItemSelectedListener(new OnItemSelectedListener(){

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int i, long l)
    {
        //use last saved data:
        if (lastItemData != null){
            //do some stuff with lastItemData
        }
        //save current data for next call:
        TextView tv = (TextView) view.findViewById(someId);
        NumberPicker np = (NumberPicker) view.findViewById(anotherId);
        String dataString = tv.getText().toString();
        int dataInt = np.getValue();
        lastItemData = new YourModelObject(dataString , dataInt);
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {
    }
});

通过这种方式,您只能在项目丢失焦点(并选择了新的焦点)之后才操作数据,并且您对数据的一致性很乐观,因为您并不真正持有正在回收的视图,而只持有它曾经包含的数据。希望你发现它有用

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17979360

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档