我的问题是在我的listview中有六个或更多的entrys后,getView方法开始给我错误的项目位置,因为我滚动后的listview被回收。我的问题是如何在滚动后获得正确的位置。我在类似的问题中研究了这个问题,但我仍然无法解决它。你能帮助我吗?
public class LayoutPreference extends DialogPreference {
private String mValue = "1";//default
private int mClickedDialogEntryIndex;
GridView gridView;
ArrayList<LayoutConfiguration> gridArray = new ArrayList<LayoutConfiguration>();
LayoutPreferenceViewAdapter customGridAdapter;
private boolean mValueSet;
private String[] mEntryValues;
private String[] mEntries;
Button btnConfirm;
public LayoutPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setDialogLayoutResource(R.layout.imglayout_grid);
setWidgetLayoutResource(R.layout.imglayout_grid_widget);
}
@Override
protected void onBindView(View view) {
super.onBindView(view);
final ImageView box = (ImageView) view.findViewById(R.id.pref_widget_box);
gridArray.clear();
for ( LayoutConfiguration layoutConfiguration : LayoutConfiguration.getLayoutConfigurations()) {
gridArray.add(layoutConfiguration);
}
for ( LayoutConfiguration layoutConfiguration : gridArray) {
if ( mValue != null && mValue.equals(layoutConfiguration.getId())) {
box.setImageBitmap(layoutConfiguration.genImage(105, 75));
if(layoutConfiguration.getId()=="conf_2.1"||layoutConfiguration.getId()=="conf_2"){
box.setRotation(0);
}else{
box.setRotation(180);
}
}
}
box.invalidate();
}
@Override
protected void onBindDialogView(View view) {
setEntryValues();
int index = findIndexOfValue(getSharedPreferences().getString(getKey(), "1"));
ViewGroup rootLayout = (ViewGroup) view;
gridView = (GridView) rootLayout.findViewById(R.id.gridView);
customGridAdapter = new LayoutPreferenceViewAdapter(getContext(), R.layout.imglayout_row_grid, gridArray, index, new ItemSelectedListener());
gridView.setAdapter(customGridAdapter);
btnConfirm = (Button) rootLayout.findViewById(R.id.confirmBtn);
btnConfirm.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
save();
}
});
super.onBindDialogView(view);
}
private void setEntryValues() {
mEntryValues = new String[gridArray.size()];
for ( int i = 0; i < gridArray.size(); i++)
mEntryValues[i] = gridArray.get(i).getId();
mEntries = new String[gridArray.size()];
for ( int i = 0; i < gridArray.size(); i++)
mEntries[i] = gridArray.get(i).getId();
}
public void setValue(String value) {
// Always persist/notify the first time.
final boolean changed = !TextUtils.equals(mValue, value);
if (changed || !mValueSet) {
mValue = value;
mValueSet = true;
persistString(value);
if (changed) {
notifyChanged();
}
}
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
setValue(restoreValue ? getPersistedString(mValue) : (String) defaultValue);
}
public String getValue() {
return mValue;
}
private int getValueIndex() {
return findIndexOfValue(mValue);
}
@Override
protected void onPrepareDialogBuilder(Builder builder) {
super.onPrepareDialogBuilder(builder);
mClickedDialogEntryIndex = getValueIndex();
builder.setPositiveButton(null, null);
}
public int findIndexOfValue(String value) {
for (int i = 0; i < gridArray.size(); i++) {
if (gridArray.get(i).getId().equals(value)) {
return i;
}
}
return -1;
}
public class ItemSelectedListener {
public void itemSelected( int index) {
if ( mClickedDialogEntryIndex >= 0) {
CheckedTextView chk = (CheckedTextView) ((RelativeLayout) gridView.getChildAt(mClickedDialogEntryIndex)).findViewById(R.id.item_chk);
if ( chk != null)
chk.setChecked(false);
}
mClickedDialogEntryIndex = index;
mValue = mEntryValues[index];
CheckedTextView chk = (CheckedTextView) ((RelativeLayout) gridView.getChildAt(mClickedDialogEntryIndex)).findViewById(R.id.item_chk);
if ( chk != null)
chk.setChecked(true);
}
}
private void save() {
SharedPreferences.Editor editor = getEditor();
editor.putString( Preferences.SETTINGS_LAYOUT, mValue);
editor.commit();
callChangeListener( mValue);
LayoutPreference.this.onClick(getDialog(), DialogInterface.BUTTON_POSITIVE);
getDialog().dismiss();
}
}
public class LayoutPreferenceViewAdapter extends ArrayAdapter<LayoutConfiguration> {
Context context;
int layoutResourceId;
int index;
ArrayList<LayoutConfiguration> data ;
ItemSelectedListener listener;
public LayoutPreferenceViewAdapter(Context context, int layoutResourceId, ArrayList<LayoutConfiguration> data, int index, ItemSelectedListener listener) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
this.index = index;
this.listener = listener;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
View row = convertView;
RecordHolder holder;
if (row == null) {
row = inflater.inflate(layoutResourceId, null);
holder = new RecordHolder();
holder.imageItem = (ImageView) row.findViewById(R.id.item_image);
holder.chk = (CheckedTextView) row.findViewById(R.id.item_chk);
row.setTag(holder);
} else {
holder = (RecordHolder) row.getTag();
}
holder.imageItem.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
listener.itemSelected(position);
}
});
holder.chk.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
listener.itemSelected(position);
}
});
LayoutConfiguration item = data.get(position);
holder.imageItem.setImageBitmap(item.genImage( 140, 100));
return row;
}
static class RecordHolder {
CheckedTextView chk;
ImageView imageItem;
}
http://www.imagehosting.cz/?v=2014071811.png
和
http://www.imagehosting.cz/?v=201407nin.png
调用Log in GetView方法。
Log.i("getView ","Position " + position + " View " + row);
07-18 11:59:43.694: I/getView(2954): Position 0 View null
07-18 11:59:43.704: I/getView(2954): Position 0 View android.widget.RelativeLayout@410f00e8
07-18 11:59:43.704: I/getView(2954): Position 0 View android.widget.RelativeLayout@410f00e8
07-18 11:59:43.714: I/getView(2954): Position 0 View android.widget.RelativeLayout@410f00e8
07-18 11:59:43.714: I/getView(2954): Position 0 View android.widget.RelativeLayout@410f00e8
07-18 11:59:43.714: I/getView(2954): Position 0 View android.widget.RelativeLayout@410f00e8
07-18 11:59:43.734: I/getView(2954): Position 0 View android.widget.RelativeLayout@410f00e8
07-18 11:59:43.744: I/getView(2954): Position 1 View null
07-18 11:59:43.755: I/getView(2954): Position 2 View null
07-18 11:59:43.785: I/getView(2954): Position 3 View null
07-18 11:59:43.805: I/getView(2954): Position 4 View null
07-18 11:59:43.815: I/getView(2954): Position 5 View null
07-18 11:59:43.875: I/getView(2954): Position 0 View null
07-18 11:59:43.905: I/getView(2954): Position 0 View android.widget.RelativeLayout@4100b838
07-18 11:59:43.905: I/getView(2954): Position 0 View android.widget.RelativeLayout@4100b838
07-18 11:59:43.905: I/getView(2954): Position 0 View android.widget.RelativeLayout@4100b838
07-18 11:59:43.915: I/getView(2954): Position 0 View android.widget.RelativeLayout@4100b838
07-18 11:59:43.915: I/getView(2954): Position 0 View android.widget.RelativeLayout@4100b838
感谢任何想法。
答案 0 :(得分:0)
我认为你可以这样做:
@Override
public View getView(int position, View row, ViewGroup parent) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
RecordHolder holder;
if (row == null) {
row = inflater.inflate(layoutResourceId, parent, false);
holder = new RecordHolder();
holder.imageItem = (ImageView) row.findViewById(R.id.item_image);
holder.chk = (CheckedTextView) row.findViewById(R.id.item_chk);
holder.imageItem.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
listener.itemSelected((int) v.getTag());
}
});
holder.chk.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
listener.itemSelected((int) v.getTag());
}
});
row.setTag(holder);
} else {
holder = (RecordHolder) row.getTag();
}
holder.imageItem.setTag(position);
holder.chk.setTag(position);
LayoutConfiguration item = data.get(position);
holder.imageItem.setImageBitmap(item.genImage( 140, 100));
return row;
}
我认为没有必要为位置变量添加最终修饰符。
此外,您可以更改方法接收的视图的名称,并避免创建另一个视图&#34; View row = convertView;&#34;。
使用&#34; .inflate(layoutId,null)&#34;这是一个不好的做法,因为你没有告诉系统哪个是视图的父级和&#34; layout _...&#34; xml中的属性不起作用。更多信息请访问:http://www.doubleencore.com/2013/05/layout-inflation-as-intended/
通过我的修改,我相信代码将正确保存列表视图中每个列表项的位置。