-1

StackOverflow community, I need your help (again) ! I created a custom class to quickly create View object (basically it's just a question displayed). Exemple :

Title : Home

Message : Are you living with a cat ?

[BtnYes] ------------------------ [BtnNo]

So here is my custom class "QuestionHelper" to create question programmatically :

public List<LinearLayout> addQuestion(ViewGroup rootView, String title, String message, int id) {
        List<LinearLayout> mButtons = new ArrayList<>();

        // Inflate une question
        LayoutInflater questionInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        RelativeLayout myQuestion = (RelativeLayout) questionInflater.inflate(R.layout.activity_formulaire_question, rootView, false);

        // Assigne la vue au controlleur
        tvTitle = (TextView) myQuestion.findViewById(R.id.activity_formulaire_question_title);
        tvMessage = (TextView) myQuestion.findViewById(R.id.activity_formulaire_question_message);

        // Remplissage des champs textes
        tvTitle.setText(title);
        tvMessage.setText(message);

        // Boutton sous la forme de LinearLayout
        btnNo = (LinearLayout) myQuestion.findViewById(R.id.activity_formulaire_question_ll_btn_no);
        btnYes = (LinearLayout) myQuestion.findViewById(R.id.activity_formulaire_question_ll_btn_yes);

        // Ajout dans la liste
        mButtons.add(btnNo);
        mButtons.add(btnYes);

        return mButtons;
    }

And this is, I think, the bad way of programming (because I don't respect MVC pattern, the button state is managed by the view fragment and there are lots of lines).

final LinearLayout rootQuestion = (LinearLayout) rootView.findViewById(R.id.activity_formulaire_questions_preliminaires_ll_wrapper);
        final QuestionHelper questionHelper = new QuestionHelper(super.getActivity());

        List<LinearLayout> question1 = questionHelper.addQuestion(rootQuestion,
                getResources().getString(R.string.question_preliminaire_1_title),
                getResources().getString(R.string.question_preliminaire_1_message), 1);

        question1.get(0).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                List<LinearLayout> question2 = questionHelper.addQuestion(rootQuestion,
                        getResources().getString(R.string.question_preliminaire_2_title),
                        getResources().getString(R.string.question_preliminaire_2_message), 2);
            }
        });
        question1.get(1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                List<LinearLayout> question3 = questionHelper.addQuestion(rootQuestion,
                        getResources().getString(R.string.question_preliminaire_3_title),
                        getResources().getString(R.string.question_preliminaire_3_message), 3);

                question3.get(0).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        List<LinearLayout> question4 = questionHelper.addQuestion(rootQuestion,
                                getResources().getString(R.string.question_preliminaire_4_title),
                                getResources().getString(R.string.question_preliminaire_4_message), 4);

                        question4.get(0).setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                List<LinearLayout> question6 = questionHelper.addQuestion(rootQuestion,
                                        getResources().getString(R.string.question_preliminaire_6_title),
                                        getResources().getString(R.string.question_preliminaire_6_message), 6);
                            }
                        });
                    }
                });
                question3.get(1).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        List<LinearLayout> question5 = questionHelper.addQuestion(rootQuestion,
                                getResources().getString(R.string.question_preliminaire_5_title),
                                getResources().getString(R.string.question_preliminaire_5_message), 5);

                        question5.get(1).setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                List<LinearLayout> question6 = questionHelper.addQuestion(rootQuestion,
                                        getResources().getString(R.string.question_preliminaire_6_title),
                                        getResources().getString(R.string.question_preliminaire_6_message), 6);
                            }
                        });
                    }
                });
            }
        });

I can have up to 8 questions depending on the previous question.

UPDATE : To explain clearly what I mean, here is an image. Do you think we could optimise this process ?

UPDATE 2 : I looked for a QuestionHolder class who take the view, the differents variables, and hold it with a get/set tag. Am I in the right way ?

UPDATE 3 : QuestionHolder refer to the same view with getTag...

UPDATE 4 : The view displayed is like that : case 1 : when I press YES YES YES but when I scroll up and press No at the question 1 it looks like that. the questions 3&4|5&6 are removed and let appears question 2. [for the exemple, I manually kill the application and reloaded it... :(]

UPDATE 5 : I created a ListView with an adapter, but it's harder than I think... So I will probably give up and do it the "dirty way"

Nawako
  • 342
  • 3
  • 17
  • The image clearly explains what you want to achieve but im having problems understanding whats the problem that stops you from doing it. – Nanoc Nov 04 '15 at 14:24
  • It's for optimisation purpose. I can do it like this, but I find it inelegant, and not human readable when there is too much question. I'm thinking of creating a method `setButtonState (boolean choice)` with a `switch (button.getId)` to identify **which button** was selected or not, and then dynamically remove or add the next question but I didn't manage to achieve it yet :) **The objective is to write the clearest code with MVC pattern.** – Nawako Nov 04 '15 at 14:33
  • Well, you can create a view to show your questions and buttons and a model class to store each question, then i would use startActivityForResult() to show the question and get the clicked button as the return value, that way you have separated view from model (MVC) and can manage the logic of the next question in a separated activity – Nanoc Nov 04 '15 at 14:39
  • `startActivityForResult()` is listening the click for the current view (question) or the whole view (with multiple questions) ? Because in my case (image related), if a user is in question 6, then scroll up to question 1 and press "NO" then question 3&4|5&6 would be removed and let the question 2 appears. When the current last question as be filled, **I have a button that allow to validate the form**, then I check which button is activated or no. If you confirm that it can be done like that, I will dig this way :) – Nawako Nov 04 '15 at 14:52
  • In my mind you only show one question at a time so the main activity manages wich question and the second activity just show the question (only one at a time) and return the YES/NO to the mainActivity so it will be able to decide wich question goes next or whatever. To me it seems like a good way of doing it. – Nanoc Nov 04 '15 at 15:01
  • It doesn't work this way :/ I updated the main thread, have a look :) – Nawako Nov 04 '15 at 15:28

1 Answers1

1

Create class what represent question item:

public class Node{
    private long id;
    private String question;
    private String title;
    private long yesId;
    private long noId;

    //Constructor, getter here....
}

You need adapter with list of question.

ArrayList<Node> questions = new ArrayList<>();
NodeAdapter adapter = new NodeAdapter(questions, ...);

When you pressing button get next node id by answer (getYesId/getNoId). And if it last item create new by id or if not check is next id same as new next id.

//Create interface in your adapter or do what you want, but like this

public void onNodeClicked(long nextId, int currentPosition){
    Node next;
    if(currentPosition == questions.size() - 1){
        next = getNodeById(nextId);
        question.add(next);
    }else{
        next = questions.get(position + 1);
        if(nextId != next.getId()){
            ArrayList<Node> remove = new ArrayList<>();
            remove.addAll(position + 1, questions);
            questions.removeAll(remove);
            next = getNodeById(nextId);
            question.add(next);
        }
    }
    adapter.notifyDataSetChanged();
}

I hope it can help you)

sunnyday
  • 2,671
  • 1
  • 13
  • 16
  • If I have an adapter, I should have a **ListView**, right ? So the adapter is populated, at first, with all the questions ? I'm trying to do it this way. Thank for your kind help :) – Nawako Nov 05 '15 at 08:55