Listview 中的 onClick 侦听器更改另一行

onClick listener in Listview changes another row

我有一个包含三个文本视图和一个图像视图的列表视图。其中一个文本视图的可见性在 xml 中设置为 'GONE'。

但是,当我单击图像视图时,我希望列表视图中的文本变得可见。这是有效的,但不是只显示该行的文本视图,而是显示另一行的文本视图。

当我点击该行时,如何只使该行的文本视图可见?

这是我的代码

public class CustomListAdapter2 extends ArrayAdapter<ObjectItem> {

//to reference the Activity
private final Activity context;

private ObjectItem[] data = null;


public CustomListAdapter2(Activity context, ObjectItem[] data) {

    super(context, R.layout.most_lodged_complaints, data);

    this.context = context;
    this.data = data;

}

public View getView(int position,  View view, ViewGroup parent) {


    if (view == null) {
        LayoutInflater inflater = context.getLayoutInflater();
        view = inflater.inflate(R.layout.most_lodged_complaints, parent, false);
    }


    final ObjectItem objectItem = data[position];

    TextView headerTextField = (TextView) view.findViewById(R.id.list_header);
    TextView detailTextField = (TextView) view.findViewById(R.id.list_detail);

    final TextView textView = (TextView) view.findViewById(R.id.list_detail2);

    ImageView imageView = (ImageView) view.findViewById(R.id.most_complaints_expand);

    headerTextField.setText(objectItem.header);
    detailTextField.setText(objectItem.detail);

    imageView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            textView.setVisibility(View.VISIBLE);
        }
    });

    return view;

};

}

注意:我已尝试使用 ViewHolder 模式,但问题仍然存在

ListView 重复使用 View。永远不要忘记这一点。

这样,如果您在任何位置设置任何 属性,这可能会在不同的位置产生类似的效果,因为最终将重新使用相同的视图。

在您的代码中您可以看到:

public View getView(int position,  View view, ViewGroup parent) {

    if (view == null) {
        // I just create a view if received view is null... 
        // In another words, just create a View with View.GONE if current is null
    } else {
        // Since some View are re-used.. they are not null
        // If you don't set visibility again, it will keep last state (in another workds, View.VISIBLE)
    }
};

因此,在使用 ListView 时,您必须在 getView(int position) 期间恢复 View 的所有属性。

如果您更改可见性,则必须跟踪哪个位置可见,哪个位置不可见。然后,在 getView() 期间您再次设置正确的状态。

您必须对每个 属性 执行此操作:setText()setVisibility()setClickable() 等...您必须恢复在另一个位置可能发生变化的所有内容。

因此,您可以保留一个单独的列表来跟踪哪些可见或不可见(这只是一个示例):

public class CustomListAdapter2 extends ArrayAdapter<ObjectItem> {

    private ObjectItem[] data = null;
    private boolean[] viewVisibility = null;


    public CustomListAdapter2(Activity context, ObjectItem[] data) {
        ...
        this.data = data;
        this.viewVisibility = new boolean[data.lenght];
    }

    public View getView(int position,  View view, ViewGroup parent) {
        ...
        final TextView textView = (TextView) view.findViewById(R.id.list_detail2);
        if(viewVisibility[position]) {
            textView.setVisibility(View.VISIBLE);
        } else {
            textView.setVisibility(View.GONE);
        }

        ...

        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                textView.setVisibility(View.VISIBLE);
                viewVisibility[position] = true;
            }
        });

        return view;

    };
}

您需要使用 OnItemClickListener,它会在回调方法中为您提供对点击的 View 的引用。

此处参考:https://developer.android.com/reference/android/widget/AdapterView.OnItemClickListener.html

这里的示例实现: