在getView()中返回错误的位置

时间:2014-07-17 11:02:50

标签: android

我的问题是在我的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

感谢任何想法。

1 个答案:

答案 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/

通过我的修改,我相信代码将正确保存列表视图中每个列表项的位置。