Android Listview.getChildAt()指向两个项目

时间:2014-02-26 20:13:55

标签: android

我有一个活动,其中包含一个列表视图,并且有足够的项目来扩展页面。

我想将位置i的某个listView项设置为不同的drawable。

要这样做,我使用代码行..

listView.getChildAt(selector).setBackgroundResource(R.drawable.main_button_shape_pressed);

有一个非常令人困惑的问题。这行代码是将两个listView项设置为指定的drawable。

当i = 0时,项目0和项目11设置为可绘制。事实证明,当我用i调用这行代码时,项目i和项目i + 11都设置为可绘制的。这是令人费解的。然后,当我在横向中启动活动时混合一切,它是一个不同的第二个列表视图,它被设置为可绘制的。在某些情况下,当我从纵向更改为横向时,屏幕上的当前突出显示列表视图项目将更改为其他项目。

WTF正在继续使用listview类吗?儿童的索引是否经常指向不同的东西?

这是我的整个活动。

public class SelectorActivity extends Activity {

private ListView listView;
private int selector;
private boolean set;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.selector_layout);
    set=false;
    Bundle extras = getIntent().getExtras();

    if(extras!=null)
    {
        selector=extras.getInt("selector");
    }

    listView=(ListView)findViewById(R.id.selector_layout);

    //set the string array for the listview
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
            R.array.sounds_array, android.R.layout.simple_list_item_1);
    adapter.setDropDownViewResource(android.R.layout.simple_list_item_1);

    listView.setBackgroundResource(R.drawable.listview_background);
    listView.setAdapter(adapter);



    highlightSelected();



}

//this method will highlight a selected listview once that listview is drawn
private void highlightSelected()
{
    if(!set)
    {
        new Thread(
                new Runnable()
                {

                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        boolean trigger=true;
                        while(trigger)
                        {
                            if(listView.getChildAt(selector)!=null)
                            {
                                set=true;
                                trigger=false;
                                listView.getChildAt(selector).setBackgroundResource(R.drawable.main_button_shape_pressed);
                            }

                        }
                    }

                }
            ).start();

    }
}

}

1 个答案:

答案 0 :(得分:2)

ListViews回收他们的孩子。在绘制时,ListView将为每个可见子项创建一个新视图。滚动时,它将重新使用不可见的最后一个视图(滚动离开屏幕)作为列表中的下一个视图。这就是为什么它在横向上是一个不同的视图索引,这就是为什么它可能是具有不同屏幕尺寸的设备上的不同视图索引。

解决方案应该是在适配器的getView()方法中重置视图背景。

此外,触摸UI(主)线程以外的任何其他视图是一种不好的做法。检查getView()方法中的选定项索引,并在那里设置背景。您还需要通过迭代列表视图中的可见视图并将其背景设置为适当的值来处理所选索引更改的情况(除非它在创建此活动后永远不会更改)。

        // Must be final to use inside the ArrayAdapter
        final int selector = extras == null ? -1 : extras.getInt("selector");
        ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(
                this,
                R.array.sounds_array,
                android.R.layout.simple_list_item_1) {
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                View newView = super.getView(position, convertView, parent);
                // set the background according to whether this is the selected item
                if (position == selector) {
                    // this is the selected item
                    newView.setBackgroundResource(R.drawable.main_button_shape_pressed);
                } else {
                    // default background for simple_list_item_1 is nothing
                    newView.setBackground(null);
                }
                return newView;
            }
        };