【问题标题】:ListAdapter. getView return bad link of item from View(convertView)列表适配器。 getView 从 View(convertView) 返回项目的错误链接
【发布时间】:2019-05-22 19:41:07
【问题描述】:

我在使用 ListAdapter(ArrayAdapter) 时遇到了一个奇怪的错误。我解决了这个问题,但我认为,任何人都可能有一些问题,我决定写下我的解决方案。

我的任务:ListView,每个项目都有 onclick 事件。最后选择的项目(其 _id val)保存到 SharedPreferences。重新打开 Activity 后需要加载最后选择的项目位置(使用 SharedPreferences 中保存的 _id)。

问题:加载组件后,我有更多次调用 getView 与其他视图的值(null 或非 null)和位置(位置值多次为 0)。但主要问题是从选定项目获取链接。

我的代码:

public class ListAdapter extends ArrayAdapter<String[]> {
private final LayoutInflater mInflater;
private final ViewBinderHelper binderHelper;
public ViewHolder beforeHolder = null;

public ListAdapter(Context context, List<String[]> objects) {
    super(context, R.layout.lv_item, objects);
    mInflater = LayoutInflater.from(context);
    binderHelper = new ViewBinderHelper();
}

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

    int i = Integer.valueOf(ProgramActivity.dirNames.get(position));
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.lv_item, parent, false);

        holder = new ViewHolder();
        holder.swipeLayout = (SwipeRevealLayout) convertView.findViewById(R.id.swipe_layout);
        holder.frontView = convertView.findViewById(R.id.front_layout);
        holder.textView = (TextView) convertView.findViewById(R.id.text);


        holder.frontView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (backStack.size() > 0) {
                    Toast.makeText(getContext(), "У вас уже выбрана последовательность программ", Toast.LENGTH_SHORT).show();
                    return;
                }

                if (beforeHolder != null) {
                    beforeHolder.frontView.setBackgroundResource(R.color.colorAccent);
                }
                else {
                    //ProgramActivity.adapter.notifyDataSetChanged();
                }

                view.setBackgroundResource(R.color.holo_green_light);

                SharedPreferences.Editor ed = MainActivity.sPref.edit();
                ed.putInt("idProgram",holder.idProgram);
                ed.commit();

                MainActivity.idProgram = holder.idProgram;

                beforeHolder = holder;
            }
        });


        convertView.setTag(holder);

    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    final String[] item = getItem(position);
    if (item != null) {
        holder.idProgram = i;
        if (i == MainActivity.idProgram) {
            holder.frontView.setBackgroundResource(R.color.holo_green_light);
            beforeHolder = holder;
        } else {
            holder.frontView.setBackgroundResource(R.color.colorAccent);
        }

        binderHelper.bind(holder.swipeLayout, item[1]);

        holder.textView.setText(item[1]);
    }

    return convertView;
}

/**
 * Only if you need to restore open/close state when the orientation is changed.
 * Call this method in {@link android.app.Activity#onSaveInstanceState(Bundle)}
 */
public void saveStates(Bundle outState) {
    binderHelper.saveStates(outState);
}

/**
 * Only if you need to restore open/close state when the orientation is changed.
 * Call this method in {@link android.app.Activity#onRestoreInstanceState(Bundle)}
 */
public void restoreStates(Bundle inState) {
    binderHelper.restoreStates(inState);
}

private class ViewHolder {
    SwipeRevealLayout swipeLayout;
    View frontView;
    TextView textView;
    int idProgram;
}
}

beforeHolder = 持有者;链接错误,尽管代码正确且条件 (i == MainActivity.idProgram) 仅适用于一个选项。但是在我单击其他项目并运行代码行 beforeHolder.frontView.setBackgroundResource(R.color.colorAccent); 之后项目颜色没有改变。

【问题讨论】:

    标签: android listview android-arrayadapter listadapter getview


    【解决方案1】:

    花了几天的时间后,我找到了摆脱这种情况的方法。 我知道错误出在 Activity 布局中。我将参数layout_height="wrap_content" 设置为ListView,因为这个getView 运行了更多次(我多次添加相同的组件,因为它在添加过程中改变了它的大小)。

    首先我添加了一行

    ProgramActivity.adapter.notifyDataSetChanged();

    (在代码中,它被注释掉了。)并将beforeHolder = holder;删除为条件(i == MainActivity.idProgram),但是第一次点击时这个解决方案有大约1秒的延迟。

    最喜欢的解决方案是将layout_height 更改为fill_parent。总之,我想说这是某种错误,即使使用wrap_content,beforeHolder 变量也应该有一个有效的引用。

    【讨论】:

    • ListView 不支持 wrap_content 高度。在某些情况下它可能会“工作”,但强烈建议您不要使用它(Google 的 Android 平台工程师)。如果您需要 wrap_content 高度,则可以使用 RecyclerView(尽管您将击败 RecyclerView 的 recycler 部分并可能导致性能问题)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多