0

listView 行に長いクリックを登録しようとしているので、非表示ボタンが表示されます。問題は、行を長押しすると、ボタンが正しく表示されますが、2 つの異なる行にしか表示されないことです。私

私のコードを見て、クリックしたボタンだけではなく 2 行で表示されるようになった理由を教えてください。

ここに私のアダプタークラス:

package android.GUI;

import android.content.Context;
import android.database.Cursor;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.CursorAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;

// This is a custom adapter that will use cursor to get data from SQLite DB as the source.

public class FastScrollAdapter extends CursorAdapter {

    private LayoutInflater mInflater;
    private Cursor cursor;

    public FastScrollAdapter(Context context, Cursor c) {
        super(context, c);
        this.mInflater = LayoutInflater.from(context);
        this.cursor = c;

    }

    public FastScrollAdapter(Context context, Cursor c, boolean autoRequery) {
        super(context, c, autoRequery);
        this.mInflater = LayoutInflater.from(context);
        this.cursor = c;
    }

    // Here we shall look to see if the View already exists and create a new one
    // if not.

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

        // If view doesn't exists = create a new one and also store it (all of
        // the views) in our ViewHolder class called "holder"
        if (convertView == null) {

            convertView = this.mInflater.inflate(R.layout.list_entry, null);

            holder = new ViewHolder();

            holder.LL = (LinearLayout) convertView.findViewById(R.id.layoutBG);
            holder.delete = (Button) convertView.findViewById(R.id.deleteItem);
            holder.LL.setOnLongClickListener(new OnLongClickListener() {

                @Override
                public boolean onLongClick(View v) {
                    // TODO Auto-generated method stub
                    holder.delete.setVisibility(View.VISIBLE);
                    return false;
                }
            });

            holder.rowID = (TextView) convertView.findViewById(R.id.rawId);
            holder.info = (TextView) convertView.findViewById(R.id.Info);
            holder.info.setTypeface(Entry.roboto);
            holder.info.setText("Info");
            holder.dateDisp = (TextView) convertView
                    .findViewById(R.id.dateDisp);
            holder.day = (TextView) convertView.findViewById(R.id.day);
            holder.finish = (TextView) convertView.findViewById(R.id.finish);
            holder.hourMin = (TextView) convertView.findViewById(R.id.hourMin);
            holder.shiftDisp = (TextView) convertView
                    .findViewById(R.id.shiftDisp);
            holder.start = (TextView) convertView.findViewById(R.id.start);
            holder.timestarted = (TextView) convertView
                    .findViewById(R.id.timestarted);

            convertView.setTag(holder);

            // If exists, just fetch this view and display it.
        } else {
            holder = (ViewHolder) convertView.getTag();

        }
        this.cursor.moveToPosition(position);

        // Set some values...
        /*************** Taken From DB ******************/
        holder.start.setText(this.cursor.getString(this.cursor
                .getColumnIndex(DBAdapter.KEY_START)));
        holder.start.setTypeface(Shifts.roboto);

        holder.shiftDisp.setText(this.cursor.getString(this.cursor
                .getColumnIndex(DBAdapter.KEY_HOURS)));
        holder.shiftDisp.setTypeface(Shifts.roboto);

        holder.rowID.setText(this.cursor.getString(this.cursor
                .getColumnIndex(DBAdapter.KEY_ROWID)));
        holder.rowID.setTypeface(Shifts.roboto);

        holder.dateDisp.setText(this.cursor.getString(this.cursor
                .getColumnIndex(DBAdapter.KEY_DATE)));
        holder.dateDisp.setTypeface(Shifts.roboto);

        holder.day.setText(this.cursor.getString(this.cursor
                .getColumnIndex(DBAdapter.KEY_DAY)));
        holder.day.setTypeface(Shifts.roboto);

        holder.finish.setText(this.cursor.getString(this.cursor
                .getColumnIndex(DBAdapter.KEY_END)));
        holder.finish.setTypeface(Shifts.roboto);

        /*************** Regular ones ******************/

        holder.info.setTypeface(Shifts.roboto);
        holder.info.setText("Info:");

        holder.hourMin.setTypeface(Shifts.roboto);
        holder.hourMin.setText("Shift:");

        holder.timestarted.setTypeface(Shifts.roboto);
        holder.timestarted.setText("Duration:");

        return convertView;
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {

        return null;
    }

    static class ViewHolder {

        TextView rowID;
        TextView info;
        TextView dateDisp;
        TextView day;
        TextView timestarted;
        TextView start;
        TextView finish;
        TextView hourMin;
        TextView shiftDisp;
        Button delete;
        LinearLayout LL;

    }

}
4

1 に答える 1

1

この問題は、ビューのリサイクルが原因です。ボタン ビューの状態を維持するには、状態の別の配列を維持する必要があります。私はこのようにします:

アダプターに配列を追加します。

public static int[] buttonState;

コンストラクターにメソッドを追加します。

populateButtonState();

メソッド (0 は表示されないことを意味し、1 は表示されることを意味します):

public static void populateButtonState() {
    buttonState = new int[c.getCount()];
    int i = 0;
    while (c.isAfterLast() == false) {
        buttonState[i] = 0;
        i++;
        c.moveToNext();
    }
}

次に、getView で、配列に基づいて可視性を設定します。

holder.delete = (Button) convertView.findViewById(R.id.deleteItem);           
if(buttonState[position] = 1) holder.delete.setVisibility(View.VISIBLE);                

また、(ステータスを切り替えonLongClickたいと仮定して) 以下を追加する必要があります。onLongClick

if(buttonState[position] = 1) {
    holder.delete.setVisibility(View.INVISIBLE);
    buttonState[position] = 0;
} else {
    holder.delete.setVisibility(View.VISIBLE);
    buttonState[position] = 1;
}                           
于 2012-05-20T23:00:14.447 に答える