I am done with a flag quiz app, it turns out however, that the app doesn't run smoothly. I have debugged several times. Presently, I am stuck. Initially the exception was fragment null must be public static in order to recreate Instance..or something like that. After several, several hours of surfing the net for solutions I created a new class, there is no error in this class but it is coloured red. Why is this?, also what do I need to use the complete or correct this code. eg Studio is saying void showDialog() is not used below is a portion of my MainActivity Fragment
guessButton = ((Button) v);
String guess = guessButton.getText().toString();
String answer = getCountryName(correctAnswer);
++totalGuesses;
if (guess.equals(answer)) {
++correctAnswers;
answerTextView.setText(answer + "!");
answerTextView.setTextColor(
getResources().getColor(R.color.correct_answer));
disableButtons();
if (correctAnswers == FLAGS_IN_QUIZ) {
resetQuiz();
void showDialog(){
DialogFragment newFragment = MyNewFragment.newInstance();
newFragment.show(getFragmentManager(), "QUIZ RESULTS");
newFragment.setCancelable(false);
}
public void doPositiveClick(){
Log.i(" fragmentdialog" , "positive click");
}
}
else {
handler.postDelayed(
new Runnable() {
#Override
public void run() {
animate(true);
}
}, 2000);
}
} else {
flagImageView.startAnimation(shakeAnimation);
answerTextView.setText((R.string.incorrect_answer));
answerTextView.setTextColor(ContextCompat.getColor(getContext(),
R.color.incorrect_answer));
guessButton.setEnabled(false);
}
}
;
private void disableButtons() {
for (int row = 0; row < guessRows; row++) {
LinearLayout guessRow = guessLinearLayouts[row];
for (int i = 0; i < guessRow.getChildCount(); i++)
guessRow.getChildAt(i).setEnabled(false);
}
}
};
}
Below is the new class that keeps on appearing red.
public class MyNewFragment extends DialogFragment {
public static MyNewFragment newInstance() {
MyNewFragment frag = new MyNewFragment();
Bundle args = new Bundle();
frag.setArguments(args);
return frag;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder;
builder = new AlertDialog.Builder(getActivity())
.setMessage("fff")
.setPositiveButton(R.string.reset_quiz,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
}
);
return builder.create();
}
};
I will appreciate a precise answer that helps solve these problems
Looks to me that you are somehow declaring methods within if-then-else clauses, hence Android Studio is saying the are unused. The snippet of code where you attempt to launch the DialogFragment should look more like this (i.e. without the surrounding void showDialog() {} method definition):
if (correctAnswers == FLAGS_IN_QUIZ) {
resetQuiz();
DialogFragment newFragment = MyNewFragment.newInstance();
newFragment.show(getFragmentManager(), "QUIZ RESULTS");
newFragment.setCancelable(false);
}
I can't see anything significantly wrong with your definition of MyNewFragment, although you have an empty OnClickListener.OnClick() definition and you are setting the fragment arguments to an empty Bundle. However neither of these issues would generate a Studio compiler error making it show red. Find where Studio is indicating the errors and it will tell you what's wrong with your code.
Related
This question already has answers here:
How do I print my Java object without getting "SomeType#2f92e0f4"?
(13 answers)
Closed 1 year ago.
I'm making an application, where I have a central recyclerview where items that the user will type are listed, below 2 buttons, one for adding items and the other for finishing. The problem I am having is that when the user finishes the task and clicks on finish I want to get all the data that was listed on his screen that is inside a List and store it in firebase, but I am not able to get this data in shape array, it always returns the object reference.
Searching the internet I found how to use the .toString in the array, but it returns me the same thing.
Here is the example of the return I am receiving.
return
the code of my object
public class ListItem {
private float measure;
public ListItem(float measure) {
this.measure = measure;
}
public float getMeasure() {
return measure;
}
public void setMeasure(float measure) {
this.measure = measure;
}
}
the code of my button add
private View.OnClickListener addItem = new View.OnClickListener() {
#Override
public void onClick(View v) {
DialogForm();
mAdapter.notifyItemInserted(listItems.size());
}
};
void DialogForm() {
AlertDialog.Builder alert = new AlertDialog.Builder(MainActivity.this);
final View customLayout = getLayoutInflater().inflate(R.layout.layout_dialog, null);
alert.setView(customLayout);
alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
EditText measure = customLayout.findViewById(R.id.edit_measure);
String response = measure.getText().toString();
if (response.isEmpty() || response.equals("0")) {
Toast.makeText(MainActivity.this, "A medida não pode ser vazia",
Toast.LENGTH_SHORT).show();
} else {
listItems.add(new ListItem(Float.parseFloat(response)));
btnFinish.setEnabled(true);
btnFinish.setBackgroundResource(R.drawable.bg_button_enabled);
}
}
});
AlertDialog dialog = alert.create();
dialog.show();
}
the code of my button finish, when I'm listing
private View.OnClickListener finishListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
for (int i=0; i<listItems.size(); i++){
Log.d("teste", listItems.get(i).toString());
}
}
};
toString() will always return the hash of the object if not override as it is an inherited method from java.lang.Object and not specific to your object
If you want toString to return the measure variable then add the following to your ListItem class
#Override
public String toString() {
return Integer.toString(measure);
}
In order to add more entries to the method, just add another + myData but perhaps ensure there is some sort of divider to make it moire readable - such as + " || " + or something
Good luck with the project
So i'm developing Android app where user is often asked what he wants to do on some actions (Button click etc.). For that i was using AlertDialog and wrote text on it and added Buttons i needed. It was working super until i realized, that on device rotation, an opened AlertDialog would disappear.
I found on the web that the proper way to handle rotation is to use Fragment, so i choose to make class extending DialogFragment:
public class MyDialogFragment extends DialogFragment {
public interface YesNoListener {
void onYes();
void onNo();
void onNeu();
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
String[] data = getArguments().getStringArray("data"); //vzame vrednosti, ki smo jih nastavili preden se pokliče .show();
if(data != null) {
switch (data.length) {
case 3:
return new AlertDialog.Builder(getActivity())
.setTitle(data[0])
.setMessage(data[1])
.setNeutralButton(data[2], new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
((YesNoListener) getActivity()).onNeu();
}
})
.create();
case 4:
return new AlertDialog.Builder(getActivity())
.setTitle(data[0])
.setMessage(data[1])
.setPositiveButton(data[2], new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
((YesNoListener) getActivity()).onYes();
}
})
.setNegativeButton(data[3], new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
((YesNoListener) getActivity()).onNo();
}
})
.create();
case 5:
return new AlertDialog.Builder(getActivity())
.setTitle(data[0])
.setMessage(data[1])
.setPositiveButton(data[2], new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
((YesNoListener) getActivity()).onYes();
}
})
.setNegativeButton(data[3], new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
((YesNoListener) getActivity()).onNo();
}
})
.setNeutralButton(data[4], new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
((YesNoListener) getActivity()).onNeu();
}
})
.create();
default:
return null;
}
}
else
return null;
}
}
I used interface too so i could implement Button.onClick() behaviour in the class where i would use MyDialogFragment. With getArguments() i passed all texts that would be used in Dialog.
The problem is that i can only use this class for one Dialog, since i have to Override interface functions, but i have multiple Dialogs with different behaviour.
I wanted to solve this issue with three public Objects Runnable, where i would just initialize Runnable where i need to change the behaviour of the Button.onClick()
...
Runnable runnablePositive, runnableNegative, runnableNeutral;
...
#Override
public void onYes(){
threadPositive.start();
}
#Override
public void onNo(){
threadNegative.start();
}
#Override
public void onNeu(){
threadNeutral.start();
}
static MyDialogFragment newInstance(String[] arg) {
MyDialogFragment f = new MyDialogFragment();
Bundle args = new Bundle();
args.putStringArray("data", arg);
f.setArguments(args);
return f;
}
...and on usage:
threadPositive = new Thread()
{
public void run()
{
//do A
}
};
threadNegative = new Thread()
{
public void run()
{
//do B
}
};
threadNeutral = new Thread()
{
public void run()
{
//do C
}
};
newInstance(new String[]{title, besedilo, nevtralno}).show(getFragmentManager(), "tag");
It is working good untill i open Dialog and rotate (this is the main problem, other things somehow work) the device (reason why i use DialogFragment in the first place). All the variables are "deleted" on the rotation and i already passed all variables i needed for further work, but there comes new issue, which i have no idea how to solve: i can't pass Objects on rotation, whether i try with onRetainCustomNonConfigurationInstance() or onSaveInstanceState() all in vain...
So i have no idea how to solve this, i had gone through hundreds of question regarding similar issue, but had no luck... And i would be grateful for any helpful advice or answer regarding this problem (even if it is a different way to solve the problem).
Thanks in advance!
If you have multiple dialogs with different behavior, then you should simply create more instances of your dialog and assign them different tags. Instead of doing just
newDialogFragment(someArgs).show(getFragmentManager(), "tag")
you can do
newDialogFragment(someArgs).show(getFragmentManager(), "dialogWithArgs")
newDialogFragment(someOtherArgs).show(getFragmentManager(), "dialogWithOtherArgs")
and so on. Your interface should be changed to
public interface YesNoListener {
void onYes(String tag);
void onNo(String tag);
void onNeu(String tag);
}
When you call its methods from the dialog, pass the fragment tag so you know which dialog called the method. That way you can handle any number of dialogs easily.
As to saving the objects, those that don't change, go into the arguments, those that do, should be made Parcelable and saved to Bundle, if you can't, then you can create a separate fragment and call setRetainInstance(true) on it, then store the objects in it.
I have a "DialogHelper" class wherein a bunch of static methods are used in various contexts to make using Dialogs easier. One such method is a "three choice dialog" where the user has three buttons to choose from to go forward:
public static AlertDialog createThreeChoiceDialog(final MyActivity activity, String title, String firstChoiceText,
String secondChoiceText, String thirdChoiceText, View.OnClickListener firstChoiceListener, View.OnClickListener secondChoiceListener,
View.OnClickListener thirdChoiceListener) {
final View dView = activity.getLayoutInflater().inflate(R.layout.three_choice_dialog, null);
final TextView explanatoryTV = (TextView) dView.findViewById(R.id.explanatoryTV);
final TextView firstChoiceTV = (TextView) dView.findViewById(R.id.firstChoiceTV);
final TextView secondChoiceTV = (TextView) dView.findViewById(R.id.secondChoiceTV);
final TextView thirdChoiceTV = (TextView) dView.findViewById(R.id.thirdChoiceTV);
explanatoryTV.setText(title);
firstChoiceTV.setText(firstChoiceText);
secondChoiceTV.setText(secondChoiceText);
thirdChoiceTV.setText(thirdChoiceText);
firstChoiceTV.setOnClickListener(firstChoiceListener);
secondChoiceTV.setOnClickListener(secondChoiceListener);
thirdChoiceTV.setOnClickListener(thirdChoiceListener);
AlertDialog = etc...
return alertDialog;
}
And I call it like this:
private void doSomething() {
final AlertDialog alert = DialogHelper.createThreeChoiceDialog(activity, "title", "choice1", "choice2", "choice3",
new View.OnClickListener() {
#Override
public void onClick(View v) {
//do something 1
alert.dismiss();
}
}, new View.OnClickListener() {
#Override
public void onClick(View v) {
//do something 2
alert.dismiss();
}
}, new View.OnClickListener() {
#Override
public void onClick(View v) {
//do something 3
alert.dismiss();
}
});
alert.show();
}
However, the "alert.show()" method rings up the error:
variable 'alert' might not have been initialized yet
My question is, what is the best way to handle this situation? I want to dismiss the dialog when the user selects a choice.
This is my current workaround:
private void doSomething() {
final ArrayList<AlertDialog> alerts = new ArrayList<>(); //<-- added ArrayList of AlertDialogs
final AlertDialog alert = DialogHelper.createThreeChoiceDialog(activity, "title", "choice1", "choice2", "choice3",
new View.OnClickListener() {
#Override
public void onClick(View v) {
//do something 1
alerts.get(0).dismiss(); //<-- accessed via ArrayList
}
}, new View.OnClickListener() {
#Override
public void onClick(View v) {
//do something 2
alerts.get(0).dismiss(); //<-- accessed via ArrayList
}
}, new View.OnClickListener() {
#Override
public void onClick(View v) {
//do something 3
alerts.get(0).dismiss(); //<-- accessed via ArrayList
}
});
alerts.add(alert); //<-- add alert to ArrayList
alert.show();
}
It works, but there's no way that this can be a best practice. I've run into this problem a few times, so I finally decided to ask what the best way to handle it is.
You are basically trying to reference an instance of a class while declaring and creating that instance - this is not possible.
I see your options as the following:
1. Wrap AlertDialog
This is basically your work-around which uses an ArrayList, but you can create you own class for this purpose also.
2. Make AlertDialog a member
Declare alert be a private member of the class which contains the doSomething method, instead of declaring it in the method itself.
3. Replace your DialogHelper with a Builder
There are several advantages (and 1 disadvantage) to this approach.
The first advantage is that it will solve your problem. The second is because it's good coding practice: in general, having methods with take many parameters is considered dirty. In the case of them being constructor methods, Clean Code conventions recommend replacing them with builders.
The disadvantage of the implementation I am about to suggest is that the Dialog behaviour is that clicking an option will always dismiss the dialog.
public class MyDialogBuilder {
private AlertDialog alert;
public MyDialogBuilder withActivity(Activity activity){
final View dView = activity.getLayoutInflater().inflate(R.layout.three_choice_dialog, null);
alert = ...;
return this;
}
public MyDialogBuilder withFirstChoice(String choiceText, final ChoiceAction action){
final TextView firstChoiceTV = (TextView) alert.findViewById(R.id.firstChoiceTV);
firstChoiceTV.setText(choiceText);
firstChoiceTV.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
action.perform();
alert.dismiss();
}
});
return this;
}
// Similar implementations for the other methods here...
public AlertDialog create() {
return alert;
}
interface ChoiceAction {
void perform();
}
}
Your calling code would be like
MyDialogBuilder builder = new MyDialogBuilder();
AlertDialog alert = builder.withActivity(activity)
.withTitle("Dialog title")
.withFirstChoice("choice 1", new MyDialogBuilder.ChoiceAction() {
#Override
public void perform() {
//do something 1
}
})
.withSecondChoice("choice 2", new MyDialogBuilder.ChoiceAction() {
#Override
public void perform() {
//do something 2
}
})
.withThirdChoice("choice 3", new MyDialogBuilder.ChoiceAction() {
#Override
public void perform() {
//do something 3
}
})
.create();
I would recommend the third approach, as I think in most cases you want to close the Dialog when the user selects an option. If you want to show some progress bar in the dialog, you can create additional methods on MyDialogBuilder which would call alert.dismiss() in a callback. Hope this helps.
I am trying to make a speech powered app, however I have run into a major problem.
My UtteranceProgressListener Class will not call any of the given methods regardless of where I place the Speak method.
Here is my code:
This is my OnCreate Method:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
voiceBtn = (Button) findViewById(R.id.startListeningBtn);
voiceBtn.setEnabled(false);
textToSpeech = new TextToSpeech(mContext,new botListener());
}
This is the OnInitListner Imeplementation
public class botListener implements TextToSpeech.OnInitListener{
#Override
public void onInit(int i) {
if(i == TextToSpeech.SUCCESS)
{
int s = textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
#Override
public void onStart(String s) {
Toast.makeText(getApplicationContext(),"Done Speaking",Toast.LENGTH_SHORT).show();
}
#Override
public void onDone(String s) {
Toast.makeText(getApplicationContext(),s,Toast.LENGTH_SHORT).show();
}
#Override
public void onError(String s) {
Toast.makeText(getApplicationContext(),"Done Speaking",Toast.LENGTH_SHORT).show();
}
});
Log.d(TAG,String.valueOf(s));
int result = textToSpeech.setLanguage(Locale.ENGLISH);
if(result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED){
Log.e(TAG,"Language not supported");
Intent installLanguage = new Intent(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(installLanguage);
}
Log.d(TAG,"Started Voice Speaker");
}
else{
Log.e(TAG,"initialization failed");
}
}
}
Now, when I press the button, the event that fires is:
public void initVoiceRecog(View v){
//Toast.makeText(mContext,"Clicked",Toast.LENGTH_SHORT).show();
Speak("hello","1");
// does some other things here after that
}
private void Speak(String text,String identifierID){
if(Build.VERSION.SDK_INT>21) {
Bundle params = new Bundle();
params.putString(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,identifierID);
textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, params, identifierID);
}
else{
// ttsMap is a HashMap
ttsMap.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,identifierID);
textToSpeech.speak(text,TextToSpeech.QUEUE_FLUSH,ttsMap );
}
}
My Question is, after saying hello, it does not fire the OnStart() or the OnError() or the OnDone() methods. Why is this happening?
I tried with the deprecated setOnUtteranceListner() as well, same result. It does not fire any of the methods, the Toasts don't show up.
Please tell a fix or a workaround for this.
The Devices I tried on are:
API 19 Micromax Canvas Nitro
API 21 Samsung S4
API 23(Marshmellow) ASUS Zenfone
I finally figured out why the callbacks were not working. Turns out, they were working and calling on a separate thread. So to execute the normal functionality, call the functions in the 'Activity.this.RunOnUiThread' and put this in the call back fuctions.
I want to create a function that shows a dialog with 2 buttons on screen and return 1 if user pressed OK and 0 if user pressed Cancel.
public class CDlg {
static int ShowConfirm(String caption, String msg, Context context) {
int rez;
AlertDialog.Builder delAllDialog = new AlertDialog.Builder(context);
delAllDialog.setTitle(caption);
TextView dialogTxt_id = new TextView(context);
LayoutParams dialogTxt_idLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
dialogTxt_id.setLayoutParams(dialogTxt_idLayoutParams);
dialogTxt_id.setText(msg);
LinearLayout layout = new LinearLayout(context);
layout.setOrientation(LinearLayout.VERTICAL);
layout.addView(dialogTxt_id);
delAllDialog.setView(layout);
delAllDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
rez = 1;
}
});
delAllDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
rez = 0;
}
});
delAllDialog.show();
return rez;
}
}
I am now shure that I am doing right because I do not know how to pass a result from unner class to outer one. There is a error message
Cannot refer to a non-final variable rez inside an inner class defined in a different method
So as a result I want to use that function something like this:
if (CDlg.ShowConfirm("User confirmation","Delete?",this)==1){
...
}
You can't do this like that. ShowConfirm can only show the dialog. When the user clicks either the OK or Cancel button, only then you can execute what you want:
public class CDlg {
void ShowConfirm(String caption, String msg) {
AlertDialog.Builder delAllDialog = new AlertDialog.Builder(this);
delAllDialog.setTitle(caption);
TextView dialogTxt_id = new TextView(this);
LayoutParams dialogTxt_idLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
dialogTxt_id.setLayoutParams(dialogTxt_idLayoutParams);
dialogTxt_id.setText(msg);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
layout.addView(dialogTxt_id);
delAllDialog.setView(layout);
delAllDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
handleButtonClick(1);
}
});
delAllDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
handleButtonClick(2);
}
});
delAllDialog.show();
}
void handleButtonClick(int rez) {
switch(rez) {
case 1: ..... break;
case 2: ..... break;
.....
}
}
}
The if (CDlg.ShowConfirm("User confirmation","Delete?",this)==1) statement is useless in Android here, since the ShowConfirm will not wait until the user presses a button.
Instead just call ShowConfirm("User confirmation","Delete?"); an implement the appropriate code in the onClicks.
If you want to code in the spirit of Android, you should actually use startActivityForResult. Look at the linked answer for details how it should work. (here is the documentation)
Define a static variable in the class you want, for example I will define in MyAuxiliaryClass.java:
public static USER_DECISION = -1;
Whenever you choose an option, then you do the following:
if (//Desicion == OK) {
MyAuxiliaryClass.USER_DECISION = 1;
} else (//Decision == NOT OK){
MyAuxiliaryClass.USER_DECISION = 2;
}
Since you are changing this static variable, then you can get the value 1 or 2 in another class. Hope it helps. Best regards.
Make rez an attribute instead of a local variable. As your method is static, the attribute should be too. This means moving the definition outside the method.
public class CDlg {
static int rez;
static int ShowConfirm(String caption, String msg, Context context) {
...
In the inner classes, you need to refer to the CDlg class
public void onClick(DialogInterface arg0, int arg1) {
CDlg.rez = 1;
}
As a side note, it is strange that you use an static method for this. One of the mistakes of the people new to Java/OOP is to abuse static code, that feels more like C was. Maybe you want to reconsider your code.