I want to make a button that allows to go to a random page, but I am having trouble with the logic of it, as I can see loopholes but I dont know how to solve them. Or should i use a different approach? Code as below.
qn3_nextBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
for (int i=1; i<4; i++) {
int rng = new Random().nextInt(2) + 1;
if (rng == i && !qns.contains(1)) {
qns.add(1);
Intent qn1 = new Intent(question3.this, question1.class);
qn1.putExtra("name", name);
qn1.putIntegerArrayListExtra("questions", qns);
startActivity(qn1);
} else if (rng == i && !qns.contains(2)) {
qns.add(2);
Intent qn2 = new Intent(question3.this, question2.class);
qn2.putExtra("name", name);
qn2.putIntegerArrayListExtra("questions", qns);
startActivity(qn2);
} else if (rng == i && !qns.contains(3)) {
qns.add(3);
Intent qn3 = new Intent(question3.this, question3.class);
qn3.putExtra("name", name);
qn3.putIntegerArrayListExtra("questions", qns);
startActivity(qn3);
}
}
}
});
loopshole that is... the user will need to press the button multiple times if the function does not meet the conditions
First Add your Intents into an ArrayList<Intent>:
ArrayList<Intent> pages = new ArrayList();
pages.add(qn1);
pages.add(qn2);
pages.add(qn3);
After that generate a random int between 0 and the list.size() inside the onClick and get that page from the list:
int index = new Random().nextInt(pages.size());
Intent page = pages.get(index);
startActivity(page);
Finally remove that page from the list by calling:
pages.remove(index);
Just don't forget to check if the ArrayList is empty or not in the first line of the onClick:
if(pages.size == 0) return;
I hope it works!
Related
I want to navigate Angular single page application without reloading the webpage. On button click I'm calling following code to navigate.
String fullUrl = "https://example.com/page1";
String hashUrl = "/page1";
public void goBackInWebView(String fullUrl, String hashUrl) {
WebBackForwardList history = webview.copyBackForwardList();
int index;
int currentIndex = history.getCurrentIndex();
for (int i = 0; i < history.getSize(); i++) {
index = i - currentIndex;
if ((webview.canGoBackOrForward(1 + i)) || (webview.canGoBackOrForward(1 - i))) {
if (history.getItemAtIndex(i).getUrl().endsWith(hashUrl)) {
webview.goBackOrForward(index);
break;
} else if (i == history.getSize()) {
webview.loadUrl(fullUrl);
break;
}
} else {
//OUTER ELSE
webview.loadUrl(fullUrl);
break;
}
}
}
If the webpage is not saved in the history it will call webview.loadUrl(fullUrl); else it will load the page using webview.goBackOrForward(index);.
but is above code everytime OUTER ELSE is callling.
First of all canGoBackOrForward is used for Getting whether the page can go back or forward the given number of steps. as you mentioned in question your web page is single page so you don't need call this method. I think bellow code can solve your problem.
public void goBackInWebView(String fullUrl, String hashUrl) {
WebBackForwardList history = webview.copyBackForwardList();
if (history.getSize() == 0) {
webview.loadUrl(fullUrl);
}else {
for (int i = 0; i < history.getSize(); i++) {
if (history.getItemAtIndex(i).getUrl().endsWith(hashUrl)) {
webview.goBackOrForward(i);
break;
} else {
webview.loadUrl(fullUrl);
}
}
}
}
I find it difficult to see much relation to Android and WebView, because the problem is SPA.
Better use hashtag # navigation for SPA, because this won't request anything server-side.
The point simply is, that the back button does not matter the least, while never navigating.
One just needs to bind JavaScript, which runs whenever window.location.hash changes.
Demo picture
I try to make a firebase quiz application project.It work's good but when i press the wrong button then it was hang and didn't work for next.
my code is here:
#Override
public void onClick(View v) {
mCountDown.cancel();
//still have question in list
if (index < totalQuestion) {
Button clickedButton = (Button) v;
if (clickedButton.getText().equals(Common.list_question.get(index).getCorrectAnswer())) {
score += 10;
correctAnwer++;
showQuestion(++index);
}
txtScore.setText(String.format("%d", score));
}
}
After right answer it will go this method:
private void showQuestion(int index) {
if (index < totalQuestion) {
thisQuestion++;
txtQuestionNum.setText(String.format("%d / %d", thisQuestion, totalQuestion));
progressBar.setProgress(0);
progressValue = 0;
if (Common.list_question.get(index).getIsImageQuestion().equals("true")) {
Picasso.with(getBaseContext())
.load(Common.list_question.get(index).getQuestion())
.into(question_image);
question_image.setVisibility(View.VISIBLE);
question_text.setVisibility(View.INVISIBLE);
} else {
question_text.setText("Q. "+Common.list_question.get(index).getQuestion());
question_image.setVisibility(View.INVISIBLE);
question_text.setVisibility(View.VISIBLE);
}
btnA.setText(Common.list_question.get(index).getAnswerA());
btnB.setText(Common.list_question.get(index).getAnswerB());
btnC.setText(Common.list_question.get(index).getAnswerC());
btnD.setText(Common.list_question.get(index).getAnswerD());
mCountDown.start();
} else {
Intent intent = new Intent(this, Done.class);
Bundle dataSend = new Bundle();
dataSend.putInt("SCORE", score);
dataSend.putInt("TOTAL", totalQuestion);
dataSend.putInt("CORRECT", correctAnwer);
intent.putExtras(dataSend);
startActivity(intent);
finish();
}
}
But after wrong answer it didn't work.I need to a condition for that but don't know how can i write code for else condition
If I understand correctly, this logic checks if the user has clicked the correct answer button:
if (clickedButton.getText().equals(Common.list_question.get(index).getCorrectAnswer())) {
score += 10;
correctAnwer++;
showQuestion(++index);
}
Now, you only want the score and number of correct answers (correctAnwer) to change if the correct answer is picked (i.e. go inside the if statement), but you always want to show the next question regardless of if the answer is correct or not. The easiest way is just to move showQuestion outside of the if statement like so:
if (clickedButton.getText().equals(Common.list_question.get(index).getCorrectAnswer())) {
score += 10;
correctAnwer++;
}
showQuestion(++index);
txtScore.setText(String.format("%d", score));
Though if you do want to perform additional actions on an incorrect answer before moving to the next question, you can use an else statement like so:
if (clickedButton.getText().equals(Common.list_question.get(index).getCorrectAnswer())) {
score += 10;
correctAnwer++;
showQuestion(++index);
} else {
// Do stuff that only needs to be done for an incorrect answer
showQuestion(++index);
}
txtScore.setText(String.format("%d", score));
I have a listview which contain 3 different values.
The values:
Top problem (getField_top_problem), user id (getUid) difficulty(getField_difficulty)
I would like to sort the list like this.
First part:
Check which user is logged in. Get all the Top problems for that user.
The Top problems from the logged in user, needs to be sorted according to most difficult first.
Second part / Rest of list.
Need to be sorted according to the most difficult first. Does not matter if there is a Top problem from another user, which is not logged in. (If not sure, check image - red box)
If its still unclear, i have added an image. It should look like this.
My progress so far.
I was able to sort it, Top problem first for all users, not just the logged in user. Need to sort it, according to logged in user's Top problem. The id for logged in user is saved as a string.
//Example logged in user id (uid)
String uid = "2";
Any help would be appreciated.
protected void onPostExecute(final List<OcdModel> result) {
super.onPostExecute(result);
dialog.dismiss();
//uid - user id that is logged in.
//Sort - Top problem of user logged in first.
//sort the rest according to difficulty
//check which user is logged in.
//Boolean user1 = a1.getUid().equals(uid);
Collections.sort(result, new Comparator<OcdModel>() {
#Override
public int compare(OcdModel a1, OcdModel a2) {
//Top problem first. Arrange row with most difficult first in top problems list.
Integer tp1 = Integer.parseInt(a1.getField_top_problem().toString());
Integer tp2 = Integer.parseInt(a2.getField_top_problem().toString());
int tpComp = tp1.compareTo(tp2);
//return b1.compareTo(b2);
if (tpComp != 0) {
return tpComp;
} else {
int b1 = Integer.parseInt(a1.getField_difficulty().toString());
int b2 = Integer.parseInt(a2.getField_difficulty().toString());
return (int) (b1-b2);
}
}
});
Collections.reverse(result);
//TODO Need to set data
OcdListAdapter adapter = new OcdListAdapter(getApplicationContext(), R.layout.row_ocd_list, result);
lvToolbox.setAdapter(adapter);
}
Thanks in advance
You need to create multiple camparator like this
public class ModelChainedComparator implements Comparator<OcdModel> {
private List<Comparator<OcdModel>> listComparators;
#SafeVarargs
public ModelChainedComparator(Comparator<OcdModel>... comparators) {
this.listComparators = Arrays.asList(comparators);
}
#Override
public int compare(OcdModel a1, OcdModel a2) {
for (Comparator<OcdModel> comparator : listComparators) {
int result = comparator.compare(a1, a2);
if (result != 0) {
return result;
}
}
return 0;
}
}
public class ModelUserLoginComparator implements Comparator<OcdModel> {
#Override
public int compare(OcdModel a1, OcdModel a2) {
return Boolean.valueOf(a2.isUserLogedIn).compareTo(Boolean.valueOf(a1.isUserLogedIn));
}
}
public class ModelDeficultyComparator implements Comparator<OcdModel> {
#Override
public int compare(OcdModel a1, OcdModel a2) {
int firstObject = Integer.parseInt(a1.getField_difficulty().toString());
int secondObject = Integer.parseInt(a2.getField_difficulty().toString());
return firstObject < secondObject ? 1 : (firstObject == secondObject ? 0 : -1);
}
}
Than you have to use this like
ArrayList<OcdModel> list = getList();
Collections.sort(list, new ModelChainedComparator(
new ModelUserLoginComparator(),
new ModelDeficultyComparator())
);
Let me know if not work
I am developing an App using Eclipse. I have a page where it has different check boxes. I want the user if checking lest say options A and B and D then Activity 7 will open and if the user checks options A and C then Activity 5 will open.
Thank you
You can do so like this:
Get the IDs of the checkboxes. Then add an OnClickListener to the checkboxes like so:
OnClickListener checkBoxListener;
checkBoxListener = new OnClickListener()
{
#Override
public void onClick(View arg0) {
if (checkboxA.isChecked() && checkboxC.isChecked())
{
Intent i = new Intent(this,Activity5.class)
startActivity(i);
}
else if (checkboxA.isChecked() && checkboxB.isChecked() && checkboxD.isChecked())
{
Intent i = new Intent(this,Activity7.class)
startActivity(i);
}
}
};
checkboxA.setOnClickListener(checkBoxListener);
checkboxB.setOnClickListener(checkBoxListener);
checkboxC.setOnClickListener(checkBoxListener);
checkboxD.setOnClickListener(checkBoxListener);
Please give this a try.
I have a view to create an account. If the save button is clicked and any of the fields are left open, it displays a toast. If all fields are filled in, the account is saved. I tried to accomplish this with an onClickListener that has an iteration through all the fields. It works perfectly if a field is not filled in and it works perfectly if alle fields are filled, but when a field isn't filled, I type something in there, try to save again and the button doesn't do anything.
I think it has something to do with the return, but I don't know what to do else. If the return wouldn't be there, I would get a toast for each field that isn't filled in.
Here's the relevant code:
private void registerButtonListeners() {
mCRUDAccountButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for (int i = 0; i < mEditTexts.length; i++) {
if(mEditTexts[i].getText().length() == 0){
CommonCode.showToast(mNoTextTitles[i], mContext, mViewGroup);
mEmptyField = 1;
return;
}
};
if (mEmptyField == 0){
saveState();
}
}
});
}
thanks guys!
You're never resetting your flag back to 0!
so...
#Override
public void onClick(View v) {
mEmptyField = 0;//RIGHT HERE (give them the benefit of the doubt)
for (int i = 0; i < mEditTexts.length; i++) {
if(mEditTexts[i].getText().length() == 0){
CommonCode.showToast(mNoTextTitles[i], mContext, mViewGroup);
mEmptyField = 1; //You were too optimistic, they failed.
return;
}
};
if (mEmptyField == 0){
saveState();
}
}
});
Now, you're doing this test for the first time, every time. Otherwise, you go through and set that flag to 1, and next time, even though your loop never finds a match, when you get to the if mPentyField == 0 test, it fails cause you set that to 1 in the previous go around.