0

I have a listView which shows a TextView and a Button. On clicking the button, I want to change the layout to a totally different layout. Here is my attempt at the same, but it doesn't show any changes (adapter class) :

public class ListViewAdapter extends ArrayAdapter<String> {

    ArrayList<String> list;

    public ListViewAdapter(@NonNull Context context, @LayoutRes int resource, @NonNull ArrayList<String> objects) {
        super(context, resource, objects);
        this.list = objects;
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull final ViewGroup parent) {
        final View[] listItemView = {convertView};
        if(listItemView[0] == null) {
            listItemView[0] = 
LayoutInflater.from(getContext()).inflate(R.layout.list_element_main, parent, false);
    }

        TextView textView = (TextView) listItemView[0].findViewById(R.id.main_text_view);
        textView.setText(list.get(position));

        Button button = (Button) listItemView[0].findViewById(R.id.switch_layout_button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //switch layout:
                //replace R.layout.list_element_main with
                //R.layout_list_element_switch)
                listItemView[0] = LayoutInflater.from(getContext()).inflate(R.layout.list_element_switch, parent, false);
                ListViewAdapter.this.notifyDataSetChanged();
            }
        });

        return listItemView[0];
    }
}

The new Layout has multiple elements in it and I'm using it elsewhere too, so I wanted to re-use that layout instead of adding the same thing again in this layout (list_element_main) playing around with its visibility (gone and visible). Is there some way to achieve this?

M J Learner
  • 171
  • 2
  • 11

3 Answers3

1

In order to do this you can override getItemViewType() and getViewTypeCount(). Your another view layout will be represented as another view type. When your click happens you should change your adapter data in order to make it return another value for your cell's view type. Then call notifyDataSetChanged() to reload the ListView.

Here's very basic sample code to illustrate the principle:

public class SampleAdapter extends BaseAdapter {

    int[] viewTypes = new int[20];

    @Override
    public int getCount() {
        return 10;
    }

    @Override
    public Object getItem(int i) {
        return null;
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public int getViewTypeCount() {
        return 2;
    }

    @Override
    public int getItemViewType(int position) {
        return viewTypes[position];
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup viewGroup) {
        int viewType = getItemViewType(position);
        if (convertView == null) {
            int layoutResId = viewType == 0 ? R.layout.item_layout1 : R.layout.item_layout2;
            convertView = LayoutInflater.from(viewGroup.getContext()).inflate(layoutResId, viewGroup, false);
        }
        if (viewType == 0) {
            // Just a sample, use a view holder in production code
            convertView.findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    viewTypes[position] = 1;
                    notifyDataSetChanged();
                }
            });
        }

        return convertView;
    }
}
algrid
  • 5,600
  • 3
  • 34
  • 37
  • There is probably a typo in your answer - you surely weren't suggesting me to override the same method twice. Could you probably add a few lines of code to explain? – M J Learner Sep 02 '17 at 17:53
0

I think the only way to do what you want would be to (do what you don't want to do, pun intended) replicate the layout block and toggle the visibility.

Fragments here would play no part since the first view which is hidden would be of no use once the button is clicked, therefore not needing to be a concurrent sub-activity.

SagunKho
  • 985
  • 10
  • 26
0

Maybe you can set a new adapter with the new layout

Tsur Yohananov
  • 533
  • 1
  • 7
  • 17