1

各行に上矢印と下矢印のボタンがある ListView を作成しました。これらのボタンを押すと、行が 1 つ上または下にシフトされます。

オーバーライド メソッド getView で両方のボタンに OnClickListener を実装することで実現しました。それは正常に機能しますが、メモリを大量に消費し、多くのコードが2倍になるため、私はそれでうまくいきません。

@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

Collections.swap(List list, int firstElementIndex, int secondElementIndex)ArrayListに要素を追加したり削除したりする代わりに、コレクション全体を反復処理する必要がないため、実装がはるかに簡単になります。同じものの簡単な例を見つけることができますhere

于 2012-08-03T10:51:33.330 に答える
1

これは簡単に達成できます

これを行う方法は、に表示されるデータを保存することです。List

次に、ユーザーが上矢印または下矢印をクリックすると

を使用して位置をシフトしているデータ項目の参照を交換しますCollections.swap(List, int, int)

notifyDataSetChanged次に、アダプターを呼び出します

于 2012-08-03T10:50:45.593 に答える
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);

       // ........
}

次に、 onClick() メソッドでbuttonUp次を指定します。

changeRow(UP, position);

およびbuttonDown:

changeRow(DOWN, position);
于 2012-08-03T10:44:43.237 に答える