From fa3157159a87475515ce96deaf6833286cb5d527 Mon Sep 17 00:00:00 2001 From: fpeterfalvi <fpeterfalvi@gmail.com> Date: Mon, 30 Apr 2018 13:15:22 +0200 Subject: [PATCH] Generate new question list function implemented Server user can restrict the list of questions from the full database to a limited number of random questions with selecting which topics to include and providing the maximum number of questions per topic. --- KvizServer/app/build.gradle | 1 + KvizServer/app/src/main/AndroidManifest.xml | 7 +- .../java/onlab/kvizserver/GameActivity.java | 68 ++++++++- .../onlab/kvizserver/GameControlFragment.java | 2 +- .../java/onlab/kvizserver/LobbyActivity.java | 19 +-- .../java/onlab/kvizserver/MainActivity.java | 3 + .../main/java/onlab/kvizserver/Operation.java | 5 + .../onlab/kvizserver/QuestionListAdapter.java | 11 +- .../kvizserver/QuestionListFragment.java | 24 +++- .../QuestionListGeneratorDialogFragment.java | 130 ++++++++++++++++++ .../java/onlab/kvizserver/model/Question.java | 16 +++ .../res/layout/fragment_question_list.xml | 1 - ...ragment_question_list_generator_dialog.xml | 75 ++++++++++ 13 files changed, 338 insertions(+), 24 deletions(-) create mode 100644 KvizServer/app/src/main/java/onlab/kvizserver/Operation.java create mode 100644 KvizServer/app/src/main/java/onlab/kvizserver/QuestionListGeneratorDialogFragment.java create mode 100644 KvizServer/app/src/main/res/layout/fragment_question_list_generator_dialog.xml diff --git a/KvizServer/app/build.gradle b/KvizServer/app/build.gradle index f51e8f8..32792f3 100644 --- a/KvizServer/app/build.gradle +++ b/KvizServer/app/build.gradle @@ -30,4 +30,5 @@ dependencies { implementation 'com.github.rustamg:file-dialogs:1.0' implementation 'com.google.code.gson:gson:2.8.2' implementation 'com.github.satyan:sugar:1.4' + implementation 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.5@aar' } diff --git a/KvizServer/app/src/main/AndroidManifest.xml b/KvizServer/app/src/main/AndroidManifest.xml index 6dc8422..d7c6659 100644 --- a/KvizServer/app/src/main/AndroidManifest.xml +++ b/KvizServer/app/src/main/AndroidManifest.xml @@ -11,7 +11,12 @@ <uses-permission android:name="android.permission.INTERNET" android:required="true" /> - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <uses-permission + android:name="android.permission.WRITE_EXTERNAL_STORAGE" + android:required="true" /> + <uses-permission + android:name="android.permission.READ_EXTERNAL_STORAGE" + android:required="true" /> <application android:allowBackup="true" diff --git a/KvizServer/app/src/main/java/onlab/kvizserver/GameActivity.java b/KvizServer/app/src/main/java/onlab/kvizserver/GameActivity.java index 031c38e..8f864f0 100644 --- a/KvizServer/app/src/main/java/onlab/kvizserver/GameActivity.java +++ b/KvizServer/app/src/main/java/onlab/kvizserver/GameActivity.java @@ -22,13 +22,18 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; import onlab.kvizserver.model.PlayerAnswer; import onlab.kvizserver.model.Question; public class GameActivity extends AppCompatActivity implements GameControlFragment.OnFragmentInteractionListener, - QuestionListFragment.OnFragmentInteractionListener, FileDialog.OnFileSelectedListener { + QuestionListFragment.OnFragmentInteractionListener, FileDialog.OnFileSelectedListener, + QuestionListGeneratorDialogFragment.OnFragmentInteractionListener { private Question question = null; private int numberOfPlayers; @@ -68,9 +73,7 @@ public class GameActivity extends AppCompatActivity implements GameControlFragme inputs.add(new BufferedReader(new InputStreamReader(ClientHolder.get(i).getClientsocket().getInputStream()))); PrintWriter output = new PrintWriter(new BufferedWriter( new OutputStreamWriter(ClientHolder.get(i).getClientsocket().getOutputStream())), true); - output.println("$$$$"); outputs.add(output); - output.println("GameStarted##normal"); } } catch (IOException e) { e.printStackTrace(); @@ -103,6 +106,8 @@ public class GameActivity extends AppCompatActivity implements GameControlFragme } public void run() { + output.println("$$$$"); + output.println("GameStarted##normal"); while (!Thread.currentThread().isInterrupted()) { try { String read = input.readLine(); @@ -162,7 +167,7 @@ public class GameActivity extends AppCompatActivity implements GameControlFragme @Override public void nextQuestionButtonClicked(int timeLimit) { gameControlFragment.setCorrectAnswerButtonEnabled(true); - questionListFragment.selecetedQuestionDisplayed(); + questionListFragment.selectedQuestionDisplayed(); gameControlFragment.setNextQuestionButtonEnabled(false); questionString = question.getQuestionText(); @@ -258,4 +263,59 @@ public class GameActivity extends AppCompatActivity implements GameControlFragme } } + @Override + public void generateQuestionList(List<String> topics, int numberOfMultipleChoice, int numberOfGuess, boolean onlyEnabled) { + Log.d("questionList", "Megvan a kérdéslista"); + List<Question> questions = Question.listAll(Question.class); + + // disabled kérdések eltávolítása, ha csak enabled kérdésekből kell válogatni + if (onlyEnabled) { + Iterator<Question> it = questions.iterator(); + while( it.hasNext() ) { + Question q = it.next(); + if(!q.isEnabled()) + it.remove(); + } + } + + // megfelelő számú kérdés kiválogatása + Collections.shuffle(questions); + Map<String, Integer> selectedMultiple = new HashMap<>(); + Map<String, Integer> selectedGuess = new HashMap<>(); + for (String topic : topics) { + selectedMultiple.put(topic, 0); + selectedGuess.put(topic, 0); + } + Iterator<Question> it = questions.iterator(); + while( it.hasNext() ) { + Question q = it.next(); + boolean selected = false; + String topic = q.getTopic(); + if(q.getType() == Question.MULTIPLE_CHOICE && + selectedMultiple.get(topic) != null && selectedMultiple.get(topic) < numberOfMultipleChoice) { + selected = true; + selectedMultiple.put(topic, selectedMultiple.get(topic) + 1); + } else if (q.getType() == Question.GUESS && + selectedGuess.get(topic) != null && selectedGuess.get(topic) < numberOfGuess) { + selected = true; + selectedGuess.put(topic, selectedGuess.get(topic) + 1); + } else { + q.setCurrentIndex(0); + q.save(); + it.remove(); + } + } + + // kérdések véletleszerű sorrendbe rakása és indexek hozzárendelése + Collections.shuffle(questions); + for (int i=0;i<questions.size();i++) { + Question question = questions.get(i); + question.setCurrentIndex(i + 1); + question.save(); + } + + // QuestionListFragment frissítése + questionListFragment.refreshQuestionList(); + } + } diff --git a/KvizServer/app/src/main/java/onlab/kvizserver/GameControlFragment.java b/KvizServer/app/src/main/java/onlab/kvizserver/GameControlFragment.java index e99026a..ad3b874 100644 --- a/KvizServer/app/src/main/java/onlab/kvizserver/GameControlFragment.java +++ b/KvizServer/app/src/main/java/onlab/kvizserver/GameControlFragment.java @@ -121,7 +121,7 @@ public class GameControlFragment extends Fragment { public void displayMultipleChoiceQuestion(String questionTextString, List<String> answers, String correctAnswerString) { questionText.setText(questionTextString); - correctAnswerTextView.setText(correctAnswerString); + correctAnswerTextView.setText("Correct answer: " + correctAnswerString); for (int i=0;i<4;i++) { answerTextViews.get(i).setVisibility(View.VISIBLE); answerTextViews.get(i).setText(answers.get(i)); diff --git a/KvizServer/app/src/main/java/onlab/kvizserver/LobbyActivity.java b/KvizServer/app/src/main/java/onlab/kvizserver/LobbyActivity.java index ccf5699..fd099fb 100644 --- a/KvizServer/app/src/main/java/onlab/kvizserver/LobbyActivity.java +++ b/KvizServer/app/src/main/java/onlab/kvizserver/LobbyActivity.java @@ -1,38 +1,29 @@ package onlab.kvizserver; -import android.app.Application; import android.content.Context; import android.content.Intent; import android.net.nsd.NsdManager; import android.net.nsd.NsdServiceInfo; import android.os.Bundle; import android.os.Handler; -import android.support.design.widget.FloatingActionButton; -import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; -import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.View; import android.widget.Button; -import android.widget.TextView; import android.widget.Toast; import java.io.BufferedReader; import java.io.BufferedWriter; -import java.io.DataInputStream; -import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; -import java.net.SocketException; import java.util.ArrayList; -import java.util.List; import onlab.kvizserver.model.ClientModel; @@ -106,10 +97,14 @@ public class LobbyActivity extends AppCompatActivity { public void onClick(View view) { if (gameMode.equals("quizup") && (clients.size() != 2)) { Toast.makeText(getApplicationContext(), "QuizUp mode requires exactly 2 players!", Toast.LENGTH_LONG).show(); + } else if (gameMode.equals("normal") && (clients.size() == 0)) { + Toast.makeText(getApplicationContext(), "Game requires at least one player!", Toast.LENGTH_LONG).show(); } else { exit = false; serverThread.interrupt(); - commThread.interrupt(); + if (commThread != null) { + commThread.interrupt(); + } ClientHolder.addAll(clients); Intent intent; if (gameMode.equals("normal")) { @@ -401,10 +396,6 @@ public class LobbyActivity extends AppCompatActivity { } -enum Operation { - ADD_CLIENT, REMOVE_CLIENT; -} - diff --git a/KvizServer/app/src/main/java/onlab/kvizserver/MainActivity.java b/KvizServer/app/src/main/java/onlab/kvizserver/MainActivity.java index ce3fc88..374ca5f 100644 --- a/KvizServer/app/src/main/java/onlab/kvizserver/MainActivity.java +++ b/KvizServer/app/src/main/java/onlab/kvizserver/MainActivity.java @@ -7,6 +7,7 @@ import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; +import android.view.WindowManager; import android.widget.Button; import android.widget.EditText; import android.widget.RadioButton; @@ -35,6 +36,8 @@ public class MainActivity extends AppCompatActivity implements FileDialog.OnFile super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); + this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); + Button StartLobbyBtn = (Button) findViewById(R.id.StartLobby); final EditText txtName = (EditText) findViewById(R.id.txtName); Button ChooseQuestionFileBtn = (Button) findViewById(R.id.ChooseQuestionFile); diff --git a/KvizServer/app/src/main/java/onlab/kvizserver/Operation.java b/KvizServer/app/src/main/java/onlab/kvizserver/Operation.java new file mode 100644 index 0000000..8165c2a --- /dev/null +++ b/KvizServer/app/src/main/java/onlab/kvizserver/Operation.java @@ -0,0 +1,5 @@ +package onlab.kvizserver; + +public enum Operation { + ADD_CLIENT, REMOVE_CLIENT; +} diff --git a/KvizServer/app/src/main/java/onlab/kvizserver/QuestionListAdapter.java b/KvizServer/app/src/main/java/onlab/kvizserver/QuestionListAdapter.java index 2e86e76..dff741e 100644 --- a/KvizServer/app/src/main/java/onlab/kvizserver/QuestionListAdapter.java +++ b/KvizServer/app/src/main/java/onlab/kvizserver/QuestionListAdapter.java @@ -42,7 +42,7 @@ public class QuestionListAdapter extends RecyclerView.Adapter<QuestionListAdapte public void onBindViewHolder(final QuestionViewHolder holder, final int position) { final Question item = items.get(position); holder.indexOfQuestionTextView.setText(Integer.toString(position + 1)); - holder.questionTextTextView.setText(item.getQuestionText()); + holder.questionTextTextView.setText("[" + item.getTopic() + "]\n" + item.getQuestionText()); String answersString = item.getCorrectAnswer(); if (item.getType() == Question.MULTIPLE_CHOICE) { List<String> otherAnswers = item.getOtherAnswers(); @@ -124,8 +124,15 @@ public class QuestionListAdapter extends RecyclerView.Adapter<QuestionListAdapte int index = selected; if (index != -1) { selected = -1; - items.get(index).setEnabled(false); + Question question = items.get(index); + question.setEnabled(false); + question.save(); notifyItemChanged(index); } } + + public void refreshCompleteList(List<Question> questions) { + items = questions; + notifyDataSetChanged(); + } } diff --git a/KvizServer/app/src/main/java/onlab/kvizserver/QuestionListFragment.java b/KvizServer/app/src/main/java/onlab/kvizserver/QuestionListFragment.java index 0aca790..f3bd0d3 100644 --- a/KvizServer/app/src/main/java/onlab/kvizserver/QuestionListFragment.java +++ b/KvizServer/app/src/main/java/onlab/kvizserver/QuestionListFragment.java @@ -1,9 +1,14 @@ package onlab.kvizserver; +import android.Manifest; import android.content.Context; +import android.content.pm.PackageManager; import android.os.Bundle; import android.support.annotation.Nullable; +import android.support.v4.app.ActivityCompat; +import android.support.v4.app.DialogFragment; import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentTransaction; import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; @@ -61,12 +66,24 @@ public class QuestionListFragment extends Fragment { exportButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { + ActivityCompat.requestPermissions(getActivity(), + new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, + 1); SaveFileDialog dialog = new SaveFileDialog(); dialog.show(getActivity().getSupportFragmentManager(), SaveFileDialog.class.getName()); } }); Button generateButton = (Button) getView().findViewById(R.id.GenerateButton); + generateButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + FragmentTransaction ft = getFragmentManager().beginTransaction(); + ft.addToBackStack(null); + DialogFragment newFragment = QuestionListGeneratorDialogFragment.newInstance(); + newFragment.show(ft, "QuestionListGeneratorDialogFragment"); + } + }); } @Override @@ -98,7 +115,7 @@ public class QuestionListFragment extends Fragment { recyclerView.setAdapter(adapter); } - public void selecetedQuestionDisplayed() { + public void selectedQuestionDisplayed() { adapter.deselectActualQuestion(); } @@ -118,4 +135,9 @@ public class QuestionListFragment extends Fragment { Collections.sort(questions); } + public void refreshQuestionList() { + initQuestionList(); + adapter.refreshCompleteList(questions); + } + } diff --git a/KvizServer/app/src/main/java/onlab/kvizserver/QuestionListGeneratorDialogFragment.java b/KvizServer/app/src/main/java/onlab/kvizserver/QuestionListGeneratorDialogFragment.java new file mode 100644 index 0000000..ba4540e --- /dev/null +++ b/KvizServer/app/src/main/java/onlab/kvizserver/QuestionListGeneratorDialogFragment.java @@ -0,0 +1,130 @@ +package onlab.kvizserver; + +import android.content.Context; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.app.DialogFragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.List; + +import onlab.kvizserver.model.Question; + +public class QuestionListGeneratorDialogFragment extends DialogFragment { + + private OnFragmentInteractionListener mListener; + + List<String> topicList; + + List<CheckBox> checkBoxes = new ArrayList<>(); + + public QuestionListGeneratorDialogFragment() { + // Required empty public constructor + } + + public static QuestionListGeneratorDialogFragment newInstance() { + QuestionListGeneratorDialogFragment fragment = new QuestionListGeneratorDialogFragment(); + Bundle args = new Bundle(); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (getArguments() != null) { + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_question_list_generator_dialog, container, false); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + LinearLayout topicsLinearLayout = (LinearLayout) getView().findViewById(R.id.TopicsLinearLayout); + final EditText numberOfMultipleChoiceEditText = (EditText) getView().findViewById(R.id.NumberOfMultipleChoiceEditText); + final EditText numberOfGuessEditText = (EditText) getView().findViewById(R.id.NumberOfGuessEditText); + final CheckBox onlyEnabledQuestionsCheckBox = (CheckBox) getView().findViewById(R.id.OnlyEnabledQuestionsCheckBox); + Button generateButtonOnDialog = (Button) getView().findViewById(R.id.GenerateButtonOnDialog); + + List<Question> allQuestions = Question.listAll(Question.class); + topicList = Question.getTopicList(allQuestions); + for (String topic : topicList) { + LinearLayout topicLinearLayout = new LinearLayout(getContext()); + topicLinearLayout.setOrientation(LinearLayout.HORIZONTAL); + CheckBox topicCheckBox = new CheckBox(getContext()); + checkBoxes.add(topicCheckBox); + TextView topicNameTextView = new TextView(getContext()); + topicNameTextView.setText(topic); + topicLinearLayout.addView(topicCheckBox); + topicLinearLayout.addView(topicNameTextView); + topicsLinearLayout.addView(topicLinearLayout); + } + + generateButtonOnDialog.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + restrictTopicList(); + int numberOfMultipleChoice; + try { + numberOfMultipleChoice = Integer.parseInt(numberOfMultipleChoiceEditText.getText().toString()); + } catch (NumberFormatException e) { + numberOfMultipleChoice = 0; + } + int numberOfGuess; + try { + numberOfGuess = Integer.parseInt(numberOfGuessEditText.getText().toString()); + } catch (NumberFormatException e) { + numberOfGuess = 0; + } + mListener.generateQuestionList(topicList, numberOfMultipleChoice, numberOfGuess, + onlyEnabledQuestionsCheckBox.isChecked()); + dismiss(); + } + }); + } + + //a ki nem jelölt topicok kidobása + private void restrictTopicList() { + for (int i=checkBoxes.size()-1;i>=0;i--) { + if (!checkBoxes.get(i).isChecked()) { + topicList.remove(i); + } + } + } + + @Override + public void onAttach(Context context) { + super.onAttach(context); + if (context instanceof OnFragmentInteractionListener) { + mListener = (OnFragmentInteractionListener) context; + } else { + throw new RuntimeException(context.toString() + + " must implement OnFragmentInteractionListener"); + } + } + + @Override + public void onDetach() { + super.onDetach(); + mListener = null; + } + + public interface OnFragmentInteractionListener { + void generateQuestionList(List<String> topics, int numberOfMultipleChoice, int numberOfGuess, boolean onlyEnabled); + } +} diff --git a/KvizServer/app/src/main/java/onlab/kvizserver/model/Question.java b/KvizServer/app/src/main/java/onlab/kvizserver/model/Question.java index 9c041b8..e679b09 100644 --- a/KvizServer/app/src/main/java/onlab/kvizserver/model/Question.java +++ b/KvizServer/app/src/main/java/onlab/kvizserver/model/Question.java @@ -6,7 +6,9 @@ import com.orm.SugarRecord; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; public class Question extends SugarRecord implements Comparable<Question> { private String topic; @@ -97,6 +99,10 @@ public class Question extends SugarRecord implements Comparable<Question> { return currentIndex; } + public void setCurrentIndex(int currentIndex) { + this.currentIndex = currentIndex; + } + @Override public int compareTo(@NonNull Question question) { return this.currentIndex - question.currentIndex; @@ -116,4 +122,14 @@ public class Question extends SugarRecord implements Comparable<Question> { line += "\t" + (enabled ? "enabled" : "disabled") + "\t" + currentIndex; return line; } + + public static List<String> getTopicList(List<Question> questions) { + Set<String> topicSet = new HashSet<>(); + for (Question question : questions) { + topicSet.add(question.getTopic()); + } + List<String> topicList = new ArrayList<>(topicSet); + Collections.sort(topicList); + return topicList; + } } diff --git a/KvizServer/app/src/main/res/layout/fragment_question_list.xml b/KvizServer/app/src/main/res/layout/fragment_question_list.xml index 4551460..780876c 100644 --- a/KvizServer/app/src/main/res/layout/fragment_question_list.xml +++ b/KvizServer/app/src/main/res/layout/fragment_question_list.xml @@ -15,7 +15,6 @@ android:layout_height="wrap_content" android:layout_gravity="center" android:id="@+id/GenerateButton" - android:enabled="false" android:text="Generate new list"/> <Button diff --git a/KvizServer/app/src/main/res/layout/fragment_question_list_generator_dialog.xml b/KvizServer/app/src/main/res/layout/fragment_question_list_generator_dialog.xml new file mode 100644 index 0000000..31a319e --- /dev/null +++ b/KvizServer/app/src/main/res/layout/fragment_question_list_generator_dialog.xml @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="utf-8"?> +<ScrollView 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" + tools:context=".QuestionListGeneratorDialogFragment"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Topics"/> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:id="@+id/TopicsLinearLayout"> + + </LinearLayout> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Multiple choice questions per topic" + android:layout_marginTop="20dp"/> + + <EditText + android:layout_width="30dp" + android:layout_height="wrap_content" + android:id="@+id/NumberOfMultipleChoiceEditText" + android:inputType="number"/> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Guess questions per topic" + android:layout_marginTop="20dp"/> + + <EditText + android:layout_width="30dp" + android:layout_height="wrap_content" + android:id="@+id/NumberOfGuessEditText" + android:inputType="number"/> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="20dp"> + + <CheckBox + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:id="@+id/OnlyEnabledQuestionsCheckBox"/> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Only enabled questions"/> + + </LinearLayout> + + <Button + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Generate" + android:id="@+id/GenerateButtonOnDialog"/> + + </LinearLayout> + +</ScrollView> \ No newline at end of file -- GitLab