Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I have a fragment with a ScrollView and, inside of it, I need maybe 5 or 6 lists. To make things simpler, let's say there are three lists - list of names, list of places and list of events.

The problem is, I can't use lists inside of ScrollViews so I need to use LinearLayouts and do the adding to the list thing by myself. This causes me all sorts of problems.

I'm using index variables to keep track of where in my layout to put the new row when the user clicks "Add".

int currIndNames;
int currIndPlaces;
int currIndEvents;

Now this is my onCreate function:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (savedInstanceState != null){
        names = savedInstanceState.getStringArrayList("names");
        places = savedInstanceState.getStringArrayList("places");
        events = savedInstanceState.getStringArrayList("events");
    } else {
        if (names == null){
            names = new ArrayList<String>();
        };
        if (places == null){
            places = new ArrayList<String>();
        }
        if (events == null){
            events = new ArrayList<String>();
        }            
    }

    realNames = new LinkedHashSet<>(names);
    realPlaces = new LinkedHashSet<>(places);
    realEvents = new LinkedHashSet<>(events);
}

The "real" variables are there because I didn't find a way to put sets into savedInstanceState, so I keep each group of items both in a set and in a list.

Now, in my onViewCreated method, I'm calling prepareNames, preparePlaces and prepareEvents. The names are the first list in the layout, so the function looks something like this:

private void prepareNames(){

  edtAddName = (EditText)getActivity().findViewById(R.id.edtName);

  LinearLayout linearLayoutNames = (LinearLayout)getActivity().
            findViewById(R.id.linearLayoutNamesTitle);


    currIndNames = ((ViewGroup)linearLayout).indexOfChild(linearLayoutNames)+1;

    for (String name: names){
        addNamesRow(name, currIndNames++);
        currIndPlaces++;
        currIndEvents++;
    }

    prepareToggleButtonNames();
    prepareButtonAddName();
    prepareButtonNames();

} 

Now, as you see, after adding the names row, I also have to increase the indexes for places and events, because they're further down in the linear layout.

Furthermore, users can remove rows, and I have to do something similar when removing rows. This is my addNamesRow function:

private void addNamesRow(final String text, int position){
    final LinearLayout rowLayout = (LinearLayout)LinearLayout.inflate(
            getActivity().getBaseContext(), R.layout.item,null);

    rowLayout.setTag(NAMES_TAG);

    TextView tvItem = (TextView)rowLayout.findViewById(R.id.tv_item);
    tvItem.setText(text);

    Spinner spItem = (Spinner)rowLayout.findViewById(R.id.sp_item);
    spItem.setAdapter(ArrayAdapter.createFromResource(getActivity().getBaseContext(),
            R.array.ratings,android.R.layout.simple_spinner_item));
    spItem.setSelection(2);


    Button btnItem = (Button)rowLayout.findViewById(R.id.btn_item);
    btnItem.setText("X");
    btnItem.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            currIndNames--;
            currIndPlaces--;
            currIndEvents--;
            linearLayout.removeView(rowLayout);
            realNames.remove(text);
        }
    });

    linearLayout.addView(rowLayout, position);

    linearLayout.invalidate();
    edtAddName.setText("");
}

My code works but I have a lot of duplication and it's very messy. I have some ideas on how to avoid some of the repetition but I'm new to Android development and I feel like I have some deeper issues in my code, and I would like to do things the right way.

share|improve this question

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.