我正在尝试在listView行上注册一个长按,然后它会显示一个Invisible按钮。 问题是,当我长按行时,按钮会正确显示,但只显示在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;
}
}
答案 0 :(得分: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;
}