0

I have a list view containing three textviews and one imageview. The visibilty of one of the textview is sets to 'GONE' in the xml.

However, When i click on the imageview i expect the text in the listview to become visible. This is working but rather than make visible only the textview on that row, the text view of another row is showing also.

How do i make only the textview of a row to become visible when i click on that row?

Here are my codes

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;

};

}

Note: I've tried using the ViewHolder pattern and the problem persist

johnson
  • 111
  • 11

2 Answers2

1

ListView re-uses the View. Never forget that.

This way, if you set any property at any position, that can cause similar effect in a different position because same view will be eventually re-used.

In your code you can see that:

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)
    }
};

So, when using ListView you must restore all properties of a View during getView(int position).

If you change visibility, you must track which position is visible and which position isn't. Then, during getView() you set the proper state again.

You must do that to every property: setText(), setVisibility(), setClickable() etc... You must restore everything that may change in another position.

So, you can keep a separated list to track which one is visible or not (this is a just an example):

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;

    };
}
guipivoto
  • 18,327
  • 9
  • 60
  • 75
  • it gave this error java.lang.NullPointerException: Attempt to read from null array. I think it's because viewVisibility is set to null by default. What should I do? – johnson Apr 23 '18 at 20:08
  • Hi, forgot to add this line this.viewVisibility = new boolean[data.lenght]; working perfectly now, I'm so so grateful – johnson Apr 23 '18 at 20:23
  • @johnson Good to know... I was reading you comment when you posted this new one!! Glad it works! – guipivoto Apr 23 '18 at 20:24
0

You'll want to use an OnItemClickListener, which gives you a reference to the clicked View in the callback method.

Reference here: https://developer.android.com/reference/android/widget/AdapterView.OnItemClickListener.html

Example implementation here: https://stackoverflow.com/a/18405437/4321774

vdelricco
  • 749
  • 4
  • 15