Java/Android OOP style for randomizer - java

This is a basic coding style question as I'm trying to be super accurate on best practices. I've browsed around and pieced together some Java code for generating a random string from a list and adding it to an existing string in my Android App.
On investigation I found two approaches, one was to use a single line of code to generate the random string by selecting an item from a list, another was to call a routine to do basically the same thing. I know it can be good to break the code up into smaller chunks, but in this case would one method be generally preferred over the other? Note that the first option is commented out in the code.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get the message from the intent
Intent intent = getIntent();
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
//Add a random day to the string
List<String> list = new ArrayList<>();
list.add("Monday");
list.add("Tuesday");
list.add("Wednesday");
list.add("Thursday");
list.add("Friday");
list.add("Saturday");
list.add("Saturday");
//Random rand = new Random();
//String random = list.get(rand.nextInt(list.size()));
String random = getRandom(list);
message += " " + random;
// Create the text view
TextView textView = new TextView(this);
textView.setTextSize(40);
textView.setText(message);
// Set the text view as the activity layout
setContentView(textView);
}
static public <T> T getRandom(List<T> list){
Random rand = new Random();
if(list == null || list.isEmpty()){
return null;
}else{
return list.get(rand.nextInt(list.size()));
}
}

Here in this case a good idea can be moving the code in to a routine. Though the function call may slow down the app(invisibly) this will be a best approach for code reuse. Consider you need the same functionality in another activity, you can simply call this function.

Related

How to make my variable with queue.poll() value accessible to another activity

I have a class project, in Java, and I'm using android studio for coding.
The project is rock paper scissors.
Basically, I made a queue containing the names of the enemy.
I q.poll() them and gave each a variable with the name firstenemy, secondenemy, and thirdenemy.
In the first game, I want to set my text view as the first enemy. Then, after the user won, it will take the user to the next activity with a similar layout, but with a different enemy name.
Here, I want to set the textview name with the variable secondenemy from the first game activity.
How can I do that ? Or, is there a way to convert the q.poll() into a string ?
Sorry for asking (maybe) such a noob question.
This is my code on the first game activity :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gameplay);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
Queue<String> q = new LinkedList<>();
Intent intent = getIntent();
String text = intent.getStringExtra(Page2Activity.EXTRA_TEXT);
nama = findViewById(R.id.name);
nama.setText(text);
q.add("Jackson");
q.add("Diamante");
q.add("Borsalino");
String firstenemy = q.poll();
String secondenemy = q.poll();
String thirdenemy = q.poll();
TextView textView4 = findViewById(R.id.textView4);
textView4.setText(firstenemy);
winners = findViewById(R.id.winners);
userresult = findViewById(R.id.userresult);
enemyresult = findViewById(R.id.enemyresult);
userresult.setText(text);
enemyresult.setText(firstenemy);
userresult2 = findViewById(R.id.userresult2);
enemyresult2 = findViewById(R.id.enemyresult2);
rand = new Random();
}

Print several inputs into different plain texts - Android Studio

I'm working on a project in Android Studio where I have one EditText where the user will insert one word at a time, 10 times. Everytime the user writes a new input and clicks on the button it goes to a different TextView than the previous ones and different from the next ones.
How can I put the different inputs into the specific (different) TextViews?
Every TextView has a different sequencial ID like, word1, word2, etc.
I haven't done java in a long time, so I'm having problems with logic. I tried to do the following but the app crashes.
gameword = (EditText) findViewById(R.id.wordj);
public void onClick(View v) {
printwords(gameword.getText().toString());
}
});
public void printwords(String word) {
String[] array = new String[10];
TextView[] positions = new TextView[10];
for (int i=0; i < 10; i++){
array[i] = word;
positions[i].setText(array[i]);
}
}
}
You're creating a new array of TextView's and String every time the button is clicked. Change your code to the code below and it should work.
Make your int[] textViews , String[] array & int i = 0 class variables and then initialize them in onCreate() after setContentView()
In above code, int[] textViews is the array of ID's of TextView's from your activity.
After doing that, change your code to following:
gameword = (EditText) findViewById(R.id.wordj);
public void onClick(View v) {
array[i] = gameword.getText().toString();
YourActivity.this.findViewById(textViews[i]).setText(array[i]);
i++;
}
});

Android: Programmatically reading view IDs for LayoutParams

What I am trying to do is programmatically creating a row of buttons with a constraint view.
I am creating two buttons and I want to have them next to each other without doing something to the .xml file, since the number of buttons can vary depending on the user.
I want to use something like (this code is part of an Activity):
ConstraintLayout layout = findViewById(R.id.layout);
Button btn1 = new Button(this);
Button btn2 = new Button(this);
ConstraintLayout.LayoutParams params1 = new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.WRAP_CONTENT,ConstraintLayout.LayoutParams.WRAP_CONTENT);
ConstraintLayout.LayoutParams params2 = new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.WRAP_CONTENT,ConstraintLayout.LayoutParams.WRAP_CONTENT);
layout.addView(btn1, 1, params1);
params2.topToTop = btn1.getId();
params2.leftToRight = btn1.getId();
layout.addView(btn2, 2, params2);
Setting the two params2 values does not work because apparently I cannot really access the ID of button1.
What would be a working solution to this?
Things I have read and tried:
Using tags instead of ids
Accessing the buttons using an ArrayList of all the created buttons as a private member for the Activity
Giving some random id (that I have chosen) to the Views using setId()
Using something like this works, because I have predefined that btn3 in the xml file:
params2.topToTop = layout.findViewById(R.id.btn3).getId();
params2.leftToRight = layout.findViewById(R.id.btn3).getId();
But in all the other cases my btn2 just lands on top of btn1 (or rather on the top left edge of the layout)
Thank you in advance!
You can use the following method to generate view id programmatically:
private static final AtomicInteger nextGeneratedId = new AtomicInteger(10000);
public static int generateViewId() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
for (;;) {
final int result = nextGeneratedId.get();
// aapt-generated IDs have the high byte nonzero; clamp to the range under that.
int newValue = result + 1;
if (newValue > 0x00FFFFFF) newValue = 10000; // Roll over to 10000, not 0.
if (nextGeneratedId.compareAndSet(result, newValue)) {
return result;
}
}
} else {
return View.generateViewId();
}
}
call .setId(generatedId) for the buttons you create.

How to give Format to a text in a String

I am working on a Android App on Android Studio. The app will show several phrases randomly when a button is pressed.
I already have a simple script for that, using a String variable which contains all the possible texts.
However, I want each text to appear as follows:
"text 1
- Text1 a"
But I am not able to add the break on the string variable I created.
I currently have it as:
final TextView textOne = (TextView) findViewById(R.id.textView);
Button motivateYou = (Button) findViewById(R.id.button);
final String[] misFrases = {"Texto 1", "texto 2", "Texto 3", "Texto 4"};
motivateYou.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Random randGen = new Random();
final int rando = randGen.nextInt(4);
textOne.setText(misFrases[rando]);
}
});
Is this a good way to create the list to add the format?
Or should I add the format on the String file on the res folder and then call the string from there?
As a side comment, I am planning to have lists of 100+ texts
Let me know your comments
What you want to do is this:
myTextView.setText(Html.fromHtml("Text1<br/>next line"));
Use Html formatted strings inside of textviews. This should cover most of usecases.
If you want a lot of strings inside of your app, I'd recommnd using an array inside arrays.xml
If you want to port the app to another language, it makes it a lot easier, if you have all strings in one place.
Furthermore you shorten your code inside the Class, since you will have over hundred strings in those lists.

How to make a Random Layout when button clicked

Actually i want to make it Random class but then i think to much activity can make the app slow so i just want to make Relative layout Random
so i have 5 layout in one activity class
layout1 = (RelativeLayout)findViewById(R.id.layout1);
layout2 = (RelativeLayout)findViewById(R.id.layout2);
layout3 = (RelativeLayout)findViewById(R.id.layout3);
layout4 = (RelativeLayout)findViewById(R.id.layout4);
layout5 = (RelativeLayout)findViewById(R.id.layout5);
and in each layout there is the button in there to make layout random again
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v){
//The code to how make layout random
}
});
}
and then how to make layout that already opened not open again if the button random was pressed? then if all layout was already opened it will open new activity class
can anyone help me explain with give some example code of that?
Initially set visibility gone to all relative layouts and put all of them into View's ArrayList.
Get random number from 0 to List size.
Get View at random position and set its visibility to Visible and remove from ArrayList.
Do same thing until ArrayList is empty.
Create new activity when ArrayList is empty.
Code:
ArrayList<View> viewList=new ArrayList<>();
initLayouts(){
layout1 = (RelativeLayout)findViewById(R.id.layout1);
layout2 = (RelativeLayout)findViewById(R.id.layout2);
layout3 = (RelativeLayout)findViewById(R.id.layout3);
layout4 = (RelativeLayout)findViewById(R.id.layout4);
layout5 = (RelativeLayout)findViewById(R.id.layout5);
viewList.add(layout1);
viewList.add(layout2);
viewList.add(layout3);
viewList.add(layout4);
viewList.add(layout5);
for(int i=0;i<viewList.size();i++){
viewList.get(i).setVisibility(View.GONE);
}
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v){
loadRandomLayout();
}
});
}
public loadRandomLayout(){
if(viewList.size()>0) {
Random r = new Random();
int number = r.nextInt(viewList.size());
viewList.get(number).setVisibility(View.VISIBLE);
viewList.remove(number);
}else{
startActivity(new Intent(this,NewActivity.class));
}
}
You could create random int as follows:
//To get a Random number 1-5 (I saw your RelativeLayouts and you've 5
Random rand = new Random();
int randomNum = rand.nextInt((5 - 1) + 1) + 1;
And then you could create a method to choose what to show :
public void ShowRelativeLayout(int rand){
switch(rand){
case 1:
if (layout1.getVisibility() == View.VISIBLE) {
//Do nothing cause it's visible
break;
} else {
layout1.setVisibility(View.VISIBLE);
break;
}
case 2:
..........
}
Make an array to store the layout indexes.
RelativeLayout[] layout = new RelativeLayout[5];
layout[0] = (RelativeLayout)findViewById(R.id.layout[0]); // 0
layout[1] = (RelativeLayout)findViewById(R.id.layout[1]); // 1
layout[2] = (RelativeLayout)findViewById(R.id.layout[2]); // 2
layout[3] = (RelativeLayout)findViewById(R.id.layout[3]); // 3
layout[4] = (RelativeLayout)findViewById(R.id.layout[4]); // 4
Make a simple random number generator.
public void FindNewLayout ()
{
Random r_generator = new Random();
int randomNum;
//now the only way to know which layouts have been shown before, you
//need to store the indexes that have been used before, somewhere.
//I recommend using an array.
// count, and the array below should be initialized somewhere else
//rather than inside the method so that only one instance of each is
//created, but for simplicity I'll just put their initialization here
int static count = 0;
//I'll explain below what count does.
// the log array that remembers each layout change
boolean[] log = new boolean[5];
do
{
//select new random number
randomNum = r_generator.nextInt((max - min) + 1) + min;
//in this case max = 4, min = 0, so replace these values in the
//equation above
// check the log to see if the number has appeared again
if ( log[randomNum] == false )
{
//Great! it hasn't appeared before, so change layout
log[randomNum] = true;
layout[randomNum].setVisibility = true;
count++; // increases step
break; //stops while because an unused layout has been found
}
}while (count<5)
//if the value of count is equal to 5 then every layout has been used
//before so the do-while code should not be run again
}// end method
And the above method should be called whenever you want to try to change layout.
Finally, you can use something like the Debugger.log("message"); statement
to be printed on the console for debugging purposes if you want, in order to find out when the layout has changed.

Categories

Resources