1

我创建了一个 ListView,每行都有一个带有向上和向下箭头的按钮。按下这些按钮可使行向上或向下移动一个位置。

我通过在覆盖方法 getView 中为两个按钮实现 OnClickListener 来实现它。它可以正常工作,但是我对此感到不满,因为它似乎非常消耗内存并且大量代码加倍。

@Override
public View getView(final int position, View convertView, ViewGroup parent) {

    View rowView = inflater.inflate(R.layout.row_layout, parent, false);

    TextView textView = (TextView) rowView.findViewById(R.id.label);
    CheckBox checkBox = (CheckBox) rowView.findViewById(R.id.checkbox);
    checkBoxes.add(position, checkBox);

    String address = this.getItem(position).getAddress();
    String tokenizedAddress = tokenizeAddress(address);

    textView.setText(tokenizedAddress);

    ImageButton buttonUp = (ImageButton)rowView.findViewById(R.id.button_up);
    ImageButton buttonDown = (ImageButton)rowView.findViewById(R.id.button_down);

    buttonUp.setOnClickListener(new OnClickListener() {

        public void onClick(View v) {
            ListAdapter adapter = ListAdapter.this;

            if(position != 0 ){
                GameTask current = adapter.getItem(position);

                ArrayList<GameTask> list = new ArrayList<GameTask>();
                for( int i = 0; i < adapter.getCount(); i++ )
                    list.add(adapter.getItem(i));
                list.remove(position);
                list.add(position-1, current);
                adapter.clear();
                for( int i = 0; i < list.size(); i++ ){
                    adapter.add(list.get(i));
                }
                adapter.notifyDataSetChanged();
            }

        }
    });

    buttonDown.setOnClickListener(new OnClickListener() {

        public void onClick(View v) {
            ListAdapter adapter = ListAdapter.this;

            if(position != adapter.getCount()-1 ){
                GameTask current = adapter.getItem(position);

                ArrayList<GameTask> list = new ArrayList<GameTask>();
                for( int i = 0; i < adapter.getCount(); i++ )
                    list.add(adapter.getItem(i));
                list.remove(position);
                list.add(position+1, current);
                adapter.clear();
                for( int i = 0; i < list.size(); i++ ){
                    adapter.add(list.get(i));
                }
                adapter.notifyDataSetChanged();
            }

        }
    });


    return rowView;
}

两个侦听器的操作几乎相同,唯一的区别是移位 +1/-1 的条件和值。我想知道如何在扩展的 ArrayAdapter 类中创建实现 OnClickListener 的内部类,但是我不知道如何将单击的行的位置传递给这个内部类。

4

3 回答 3

2

无需从 ArrayList 中添加和删除元素,您可以更好地实现Collections.swap(List list, int firstElementIndex, int secondElementIndex)它,因为您不必遍历整个 Collection。可以找到一个简单的例子here

于 2012-08-03T10:51:33.330 回答
1

您可以创建一个可供buttonUp和使用的方法buttonDown。此方法可以将按下的操作类型 (UP/DOWN) 和项目在 ListView 中的位置作为参数,然后在传递适当操作的两个单击侦听器中调用此方法。

例子:

// 2 new constants
private static final int UP = 0;
private static final int DOWN = 1;

// Based on "type", increment or decrement the position.

private void changeRow(int type, int position){
        if(type==UP){
                position=position-1;
        }else if(type==DOWN){
                position=position+1;
        }

        // ........

        // Then in your "for" cicle you specify:
        list.add(position, current);

       // ........
}

然后在buttonUp您指定的 onClick() 方法中:

changeRow(UP, position);

buttonDown

changeRow(DOWN, position);
于 2012-08-03T10:44:43.237 回答
1

这很容易实现

这样做的方法是将要显示的数据存储在List

然后当用户单击向上或向下箭头时

使用移动位置交换数据项的引用Collections.swap(List, int, int)

然后调用notifyDataSetChanged适配器

于 2012-08-03T10:50:45.593 回答