Search code examples
androidlistbuttonandroid-gridview

dynamically add elements on list view


I need to implement a dynamic list view. I have already created it with arrays and in a static way, but I need to add a button which creates new elements in the grid and a click on listner. If I switch from arrays to lists, it will be a solution? Here is my code, can anyone give me a little help please?

GRID VIEW:

<GridView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:horizontalSpacing="-10dp"
tools:context="com.example.giovanni.mainapp_drawer.Activities.MainActivity"
android:orientation="vertical"
android:columnWidth="160dp"
android:fadeScrollbars="true"
android:gravity="center"
android:numColumns="2"
android:stretchMode="columnWidth"
android:id="@+id/gv"
</GridView>

BUTTON ADAPTER:

public class RoomsBtnAdapter extends BaseAdapter{


    private Context context;
    private final String[] strings;
    private final int[] colors;

    public RoomsBtnAdapter(Context context, String[] strings, int[] colors) {
        this.context = context;
        this.strings = strings;
        this.colors = colors;
    }

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

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View gridView;

        if (convertView == null) {

            gridView = new View(context);

            gridView = inflater.inflate(R.layout.room_btn, null);

            Button btn = (Button) gridView.findViewById(R.id.roomBtn);
            btn.setText(strings[position]);
            btn.setBackgroundResource(colors[position]);

        } else {
            gridView = (View) convertView;
        }

        return gridView;
    }

    @Override
    public int getCount() {
        return strings.length;
    }

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

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

}

Fragment of grid view:

public class RoomsFragment extends Fragment {

    public int[] colors = {R.color.colorRoom1, R.color.colorRoom2, R.color.colorRoom3, R.color.colorRoom4, R.color.colorRoom5, R.color.colorRoom6, R.color.colorRoom7};

    public String[] strings = {"Conversare", "Giocare (videogames)", "Break", "Business", "Compagni di viaggio", "Aperitivo", "Chiacchiere e caffè"};

    public RoomsFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_rooms, container, false);
    }


    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {

        final GridView gridView = (GridView) getActivity().findViewById(R.id.gv);
        gridView.setAdapter(new RoomsBtnAdapter(getContext(), strings, colors));

        gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                                    int position, long id) {

                switch (position) {
                    case 0:
                        Log.d("click", "click");

                    case 1:
                }

            }
        });
    }
}

Solution

  • You did it very well! And yes, there is a solution. The key method is adapter.notifyDataSetChanged(); if you call this notifyDataSetChanged the adapter will try to "redraw" the ListView, so if you make any change in the data source (In this case you will add an element to the list) you will see a different number of cells.

    So you need to follow these steps:

    1- Replace the String[] for a List

    2- Keep a reference to the adapter created

    3- Call notifyDataSetChanged() on this adapter every time you make a change (This method should be called in the UI thread)

    The final code should look something like this:

    final GridView gridView = (GridView) getActivity().findViewById(R.id.gv);
    final RoomsBtnAdapter adapter = new RoomsBtnAdapter(getContext(), strings, colors);
    gridView.setAdapter(adapter);
    
    gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                                int position, long id) {
    
            switch (position) {
                case 0:
                    strings.add("New String");
                    adapter.notifyDataSetChanged(); //This is the key ingredient
                case 1:
            }
    
        }
    });