Android DialogFragment newInstance optional parameters - java

I've been following the official android developer docu and this one for the use of DialogFragment inside my project. so far so good, since I have to pass data to the DialogFragment for it to create a multichoice list, I call the DialogFragment from inside my MainActivity via the newInstance method (passing the items) and I am getting a correct result. Now, I would like to pass another argument, also data for the DialogFragment but it has to be optional since I dont need to pass it all the time. Is there a way for me to achieve this?
EDIT:
so I took the Advice from the comments below and created a setter and passed the items i wished to pass to the DiagramFragment. It worked just fine, sadly it didn't help me solve my problem. The reason I wanted to pass the second data is that I thought, if the user opens the DialogFragment and makes a selection and after that reopens the DialogFragment his last choice is gone. I wanted to check the checkboxes he already had checked programmatically, by passing the checked once back to the DialogFragment and then setting the right indexes back into mSelectedItems - but even tho the indexes are set correctly the checkboxes stay unchecked.. is there a workaround?
static MyDialogFragment newInstance(int num) {
MyDialogFragment f = new MyDialogFragment();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
...
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
mSelectedItems = new ArrayList(); // Where we track the selected items
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Set the dialog title
builder.setTitle(R.string.pick_toppings)
// Specify the list array, the items to be selected by default (null for none),
// and the listener through which to receive callbacks when items are selected
.setMultiChoiceItems(R.array.toppings, null,
new DialogInterface.OnMultiChoiceClickListener() {
#Override
public void onClick(DialogInterface dialog, int which,
boolean isChecked) {
if (isChecked) {
// If the user checked the item, add it to the selected items
mSelectedItems.add(which);
} else if (mSelectedItems.contains(which)) {
// Else, if the item is already in the array, remove it
mSelectedItems.remove(Integer.valueOf(which));
}
}
})
// Set the action buttons
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
// User clicked OK, so save the mSelectedItems results somewhere
// or return them to the component that opened the dialog
...
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
...
}
});
return builder.create();
}

an optional parameter can be done like this:
static MyDialogFragment newInstance() {
return newInstance(-1);
}
static MyDialogFragment newInstance(int num) {
MyDialogFragment f = new MyDialogFragment();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
You can call newInstance() if you have no number or newInstance(300) if you have.
On the other side:
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
int num = getArguments().getInt("num");
if(num == -1) {
// no extra number
} else {
// do something with the extra number
}
...
Alternatively instead of using -1 you could not add the Int at all and just check for the default value (I think its 0 in the API docs)

I got it, it was already answered - funny I didn't find it when I googled..
There are easiest ways of doing what you want but let's take this approach:
As you have noticed, the setMultiChoiceItems() method receives a String[] as the items of your DialogFragment and a boolean [] to define if they are checked or not. We are going to use this array to persist our choices. This array must have the same length as the items array and will be initially set to false.
So all I had to do was create a boolean[] itemsChecked and set the correct indexes to true, to re-check the right checkboxes..
Original Question Persist AlertDialog checked options - all credit to #joao2fast4u

Related

Why am I getting an IndexOutOfBoundsException error when calling an activity method from my dialog? [duplicate]

This question already has answers here:
index out of bounds exception java [duplicate]
(3 answers)
how to fix java.lang.IndexOutOfBoundsException
(7 answers)
Closed 1 year ago.
I have a Recycler View full of items, when you long press on a row, a remove buttons appears to allow the user to delete the row - I managed to get that working correctly but I then wanted to add a bit of safety to it by adding a dialog which asks the user whether or not they want to delete the row. However when I call the method in my dialog I get an IndexOutOfBoundsException as below:
2021-10-19 15:52:06.774 16238-16238/com.example.it_stock E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.it_stock, PID: 16238
java.lang.IndexOutOfBoundsException: Index: 6, Size: 0
at java.util.ArrayList.get(ArrayList.java:411)
at com.example.it_stock.MainActivity.deleteItemRow(MainActivity.java:93)
at com.example.it_stock.ConfirmDeleteDialog.lambda$yes$1$ConfirmDeleteDialog(ConfirmDeleteDialog.java:48)
at com.example.it_stock.-$$Lambda$ConfirmDeleteDialog$VgpDlH3zTD1jVLwQl8Gp5RaCjYw.onClick(lambda)
at android.view.View.performClick(View.java:5637)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
at android.view.View$PerformClick.run(View.java:22433)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6121)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
I am using an interface to long click on the recycler view rows:
package com.example.it_stock;
public interface StockViewInterface {
void onItemClick(int position);
void onLongItemClick(int position);
}
This is in my Adapter:
// Uses the StockViewInterface to implement click listeners. These can then be used in Main Activity.
stockView.setOnClickListener(v -> {
stockViewInterface.onItemClick(getAdapterPosition());
notifyItemChanged(selectedPosition);
selectedPosition = RecyclerView.NO_POSITION;
notifyItemChanged(selectedPosition);
});
stockView.setOnLongClickListener(v -> {
stockViewInterface.onLongItemClick(getAdapterPosition());
// Highlight row
notifyItemChanged(selectedPosition);
selectedPosition = getAdapterPosition();
notifyItemChanged(selectedPosition);
return true; // doesn't allow multiple rows to be selected. False would highlight multiple rows but the remove method only allows one deletion at a time for now.
});
These are the long click and delete row methods in my Main Activity:
// Long tap on a row in the Recycler View. Remove button becomes visible and once clicked opens the confirmation dialog.
#Override
public void onLongItemClick(int position) {
btnRemoveItem.setVisibility(View.VISIBLE);
btnRemoveItem.setOnClickListener(v -> {
ConfirmDeleteDialog confirmDeleteDialog = new ConfirmDeleteDialog();
Bundle bundle = new Bundle();
bundle.putInt("position", position);
confirmDeleteDialog.setArguments(bundle);
confirmDeleteDialog.show((MainActivity.this).getSupportFragmentManager(),"confirm");
});
System.out.println(position);
}
// Deletes row.
public void deleteItemRow(int position) {
String stock = allStock.get(position).getItem();
db.deleteStockItem(db.getStockItem(allStock.get(position).getID()));
allStock.remove(position);
stockAdapter.notifyItemRemoved(position);
stockAdapter.notifyDataSetChanged();
btnRemoveItem.setVisibility(View.INVISIBLE);
stockAdapter.selectedPosition = RecyclerView.NO_POSITION;
Toast.makeText(this, stock + " successfully deleted!", Toast.LENGTH_SHORT).show();
}
The issue occurs in that deleteItemRow() method when I call it from my Dialog in the yes() method:
public class ConfirmDeleteDialog extends DialogFragment {
private MainActivity mainActivity;
public static final String TAG = "confirm";
int position;
Button no, yes;
#NonNull
#Override
public Dialog onCreateDialog(#Nullable Bundle savedInstanceState) {
LayoutInflater inflater = getActivity().getLayoutInflater();
View v = inflater.inflate(R.layout.dialog_confirm_delete, null);
Bundle bundle = getArguments();
position = bundle.getInt("position", position);
no = v.findViewById(R.id.btnNo);
yes = v.findViewById(R.id.btnYes);
mainActivity = new MainActivity();
System.out.println(position);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(v);
no();
yes();
return builder.create();
}
private void no() {
no.setOnClickListener(v -> {
dismiss();
});
}
private void yes() {
yes.setOnClickListener(v -> {
mainActivity.deleteItemRow(position);
System.out.println(position);
dismiss();
});
}
}
As mentioned at the start, the deleteItemRow() works correctly if I call it on the remove item button press if I do this:
#Override
public void onLongItemClick(int position) {
btnRemoveItem.setVisibility(View.VISIBLE);
btnRemoveItem.setOnClickListener(v -> {
deleteItemRow(position);
});
System.out.println(position);
}
I have used the System.out lines to makes sure position is correct.
Can anyone help me understand why the list is empty when calling the method from my dialog but isn't empty if I call it in my main activity. And is there a way to fix this? Thanks in advance.
EDIT: My allStock ArrayList is empty when the method is called from the dialog. This is how I get the ArrayList:
private DBHandlerStock db;
private ArrayList<Stock> allStock = new ArrayList<>();
db = new DBHandlerStock(this);
allStock = db.getAllStock();
I managed to 'fix' this by making my DBHandler, ArrayList, Adapter and Button static. However this creates memory leaks so I'm going to find another way round it. Thanks for the replies though.
Edit: I just had to change mainActivity = new MainActivity(); to mainActivity = ((MainActivity)getActivity()); in my Dialog. The arrayList was empty because it was creating a new mainActivity every time the dialog was opened.

My Method always return 0 ignoring the condition

I have read some related questions like this and this but there the problem is int can't hold much bigger value. In my case its not that.
I'm calling the below method in OnClick of button but it return always 0
public int showRadioAlertDialog(final Button button, String title,
final List<String> list, int selectedIndex) {
final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setTitle(title);
builder.setCancelable(false);
builder.setSingleChoiceItems(list.toArray(new String[list.size()]),
selectedIndex, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (which > -1) {
position = which;
}
}
});
builder.setPositiveButton("Confirm", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
printLog("List position = " + list.get(position));
if (position > -1) {
button.setHint(list.get(position));
}
}
});
builder.setNegativeButton("Cancel", null);
AlertDialog dialog = builder.create();
dialog.show();
if (position > -1) {
return position;
} else {
return -1;
}
}
position is a global variable.
What I'm expecting is it should return -1 or the index of selected position.
First thing that I noticed is it return value before user select an
item from single choice, it should not return anything before user
select an item.
Second if it return before selection the I have a check at the end
so it should be -1 why 0.
Please explain a bit why its 0. Any effort would be appreciated.
You call this:
if (position > -1) {
return position;
} else {
return -1;
}
After setting the onClickListeners. The thing is that the onClickListeners are invoked from a different thread when the event happens, meaning by the time position is set, the value has been returned already.
You can't get proper return methods when you use onClickListeners, as they are called as inner classes (or a method if you extend onCLickListener). Use callback methods instead (the following is pseudocode and isn't valid. Don't copy-paste and expect it to work):
... onClick(){
callback(position);
}
...
void callback(position){
do whatever with the variable
}
If you define integer variable as global, default value is automatically given and the value is 0. In your case, you have conditional code that is after show() method call. This means will execute the code immediately after calling show() method. Since 0 > -1 hence you will always get 0. Hope this helps you. If you want to add position after clicking the dialogue then in call back method of dialogue you need to set the value to that variable position explicitly. Return will not work. Because by the time you click the dialogue button value has already been returned. And why is o returning I have already mentioned the begining of my answer.

Callback function did't trigger when calling from DialogFragment to Fragment

Right now i'm having :-
1) 1 activity which is the main activity that extends from AppCompactActivity.
2) 1 fragment class that extends from fragment, this is the fragment that being called from main activity (1) - ProfileTeacherActivity.java
3) 1 fragment class that extends from DialogFragment, this dialog getting called from fragment (2) - ModalBox.java
So, basically, this is just a simple flow of execution. At start, the applications showing the main activity (1) having drawer that have a few links as example a profile link, when click this link, the application call the fragment (2) showing details of profile with one edit button. After clicking edit button, the applications will invoke DialogFragment (3) that contains some of EditText for editing user's profile.
What i want to achieve is, after editing user's profile and successful saved into database, i tried to send user's data back to fragment (2) just to show latest updated info, unfortunately it didn't work.
Here is what i'm tried :
1) Creating Interface inside DialogFragment (3) - ModalBox.java
public class ModalBox extends DialogFragment{
....
public interface EditProfileModalBoxInterface {
void onFinishEditProfile( HashMap<String, String> dataPassing );
}
...
...
}
2) Inside DialogFragment also i have .setPositiveButton function for OK button. - ModalBox.java
public class ModalBox extends DialogFragment{
...
...
public Dialog onCreateDialog(Bundle savedInstanceState ) {
...
builder
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, int id) {
// At here i'm using retrofit2 http library
// to do updating stuff
// and inside success's callback of retrofit2(asynchronous)
// here i call the below function to send data
// dataToSend is a HashMap value
sendBackResultToParent( dataTosend );
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
}
});
.....
}
// Function called inside success's callback of retrofit2
public void sendBackResultToParent( HashMap<String, String> data ) {
// instantiated interface
EditProfileModalBoxInterface ls=(EditProfileModalBoxInterface)getTargetFragment();
// declaring interface's method
ls.onFinishEditProfile( data );
}
}
3) Finally, i'm implements those interface inside fragment (2) - ProfileTeacherActivity.java
public class ProfileTeacherActivity extends Fragment
implements ModalBox.EditProfileModalBoxInterface{
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState ) {
.....
.....
}
// At here the interface's method did't triggered
#Override
public void onFinishEditProfile( HashMap dataPassedFromDialog ) {
Toast.makeText(getActivity(), "Testing...." , Toast.LENGTH_LONG).show();
}
}
What i'm confuses right now is, the problem happens only when i called this function sendBackResultToParent( dataTosend ); inside retrofit2 success's callback, it does triggered when calling outside of it. I'm assumed the async called caused this. If i could use Promise or something like that or is there any workaround on this?
The following existing solutions didn't work in my case :
Callback to a Fragment from a DialogFragment
How to send data from DialogFragment to a Fragment?
Send Data from DialogFragment to Fragment
Ask me for more inputs if above use case didn't clear enough or misunderstanding. Thanks for the helps. Regards.
This is a sample DialogFragment code used to send message to selected contact. I too required to capture the click event on the DialogFragment and redirect.
Ideally to achieve this , this is what needed to be done
Override the positive/negative button clicks of AlertDialog.Builder and do no action
After this , using getButton method mention AlertDialog.BUTTON_NEGATIVE or AlertDialog.BUTTON_POSITIVE and assign an action
public class SMSDialogFrag extends DialogFragment {
private static String one="one";
private EditText messageContent;
private AlertDialog dialog;
private String mobNumber;
public static SMSDialogFrag showDialog(String mobNumber){
SMSDialogFrag customDialogFrag=new SMSDialogFrag();
Bundle bundle=new Bundle();
bundle.putString(one, mobNumber);
customDialogFrag.setArguments(bundle);
return customDialogFrag;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
View view = getActivity().getLayoutInflater().inflate(R.layout.sms_dialog, null);
alertDialogBuilder.setView(view);
setupUI(view);
alertDialogBuilder.setTitle("");
alertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//Do nothing here because we override this button later
}
});
alertDialogBuilder.setPositiveButton("Send", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//Do nothing here because we override this button later
}
});
dialog = alertDialogBuilder.create();
dialog.show();
dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
//else dialog stays open. Make sure you have an obvious way to close the dialog especially if you set cancellable to false.
}
});
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sendMessage();//IN YOUR USE CASE YOU CAN REDIRECT TO YOUR CALLER FRAGMENT
}
});
return dialog;
}
void setupUI(View view){
TextView textViewMob=(TextView)view.findViewById(R.id.mobNumber);
messageContent=(EditText)view.findViewById(R.id.messageContent);
mobNumber=getArguments().getString(one);
textViewMob.setText("Send message to : "+mobNumber);
}
void sendMessage(){
if( ! TextUtils.isEmpty(messageContent.getText())){
try {
SmsManager smsManager = SmsManager.getDefault();
Log.v(Constants.UI_LOG,"Number >>>>>>> "+mobNumber);
smsManager.sendTextMessage(mobNumber, null, messageContent.getText().toString(), null, null);
} catch (Exception e) {
e.printStackTrace();
}
Toast.makeText(getActivity(),"Message Sent!",Toast.LENGTH_SHORT).show();
dialog.dismiss();
}else{
Toast.makeText(getActivity(),"Please enter message to send!",Toast.LENGTH_SHORT).show();
}
}
}
Consider using eventBus, for example
Otto
The usage is very simple. All you need to do is create an evenbus:
public static Bus bus = new Bus(ThreadEnforcer.MAIN); //use Dagger2 to avoid static
Then create a receiver method (in fragment 2 in your case):
#Subscribe
public void getMessage(String s) {
Toast.makeText(this, s, Toast.LENGTH_LONG).show();
}
Send you message by calling(from DialigFramgent):
bus.post("Hello");
And don't forget to register your eventBus inside onCreate method(of your Fragment):
bus.register(this);
And that is!
From architectural standpoint, 2 fragments should not directly communicate with one another. Container Activity should be responsible for passing data between it's child fragments. So here's how i would do it:
Implement your interface in the container Activity and just attach your interface implementation in the Activity to the Dialog class and call that interface method when required. Something like this :
public static class ModalBox extends DialogFragment {
EditProfileModalBoxInterface mListener;
// Container Activity must implement this interface
public interface EditProfileModalBoxInterface {
void onFinishEditProfile( HashMap<String, String> dataPassing );
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (EditProfileModalBoxInterface) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement EditProfileModalBoxInterface");
}
}
}
Then call mListener.onFinishEditProfile(....) where ever it's required in the DialogFragment class.
This way you will receive the result back in your Activity class from where you can call your desired fragment's relevant method to pass the results to that fragment.
This whole flow has been described here
Finally the culprit founds. All the answers mentioned above were right. And my script also actually works, the problem is related with my API json's response that did't coming with right structure. In my case, i'm using retrofit2 with GSON converter for parsing into POJO. Found the info on log saying about :
Expected BEGIN_OBJECT but was BEGIN_ARRAY
Means that, GSON expecting the json object, which is my API was returned JSON array. Just change the API's structure then all goods to go. Thanks guys for your hard time. Really appreciated, as i'm right now knowing how to deal with eventBus, replacing default OK and Cancel button and the correct way for communicating between fragments.

How to return user input values (double) from EditText- Android

I'm new to OOP, but I've had experience with C previously. I'm learning Java and working on building an app slowly. I find I learn more when I apply what I've read and learned from other sources to projects.
The problem I've been facing for a while now is in regard to returning values users have inputted into EditText fields and using those values to run some calculations. Here is my code:
public class Linmotion extends Activity {
// Creating the variables
EditText time, acc, dis, ivel, fvel;
Button solve;
int count = 0;
double time1,acc1,dis1,ivel1,fvel1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_linmotion1);
time = (EditText) findViewById(R.id.EditText01);
acc = (EditText) findViewById(R.id.EditText02);
dis = (EditText) findViewById(R.id.EditText03);
ivel = (EditText) findViewById(R.id.EditText04);
fvel = (EditText) findViewById(R.id.EditText05);
solve = (Button) findViewById(R.id.buttonSolve);
//Trying to return inputted values
/*
if (!(time.getText() == null)) {
time1=Double.parseDouble(time.getText().toString());
}
if(!(acc.getText()==null)){
acc1=Double.parseDouble(acc.getText().toString());
}
if(!(ivel.getText()==null)){
ivel1=Double.parseDouble(ivel.getText().toString());
}
if(!(fvel.getText()==null)){
fvel1=Double.parseDouble(fvel.getText().toString());
}s
if(!(dis.getText()==null)){
dis1=Double.parseDouble(dis.getText().toString());
}
/*
* Double.parseDouble(time.getText().toString());
* Double.parseDouble(acc.getText().toString());
* Double.parseDouble(ivel.getText().toString());
* Double.parseDouble(fvel.getText().toString());
* Double.parseDouble(dis.getText().toString());
*/
// add button listener
solve.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
if (time1 < 0) {
count++;
if (acc1 < 0) {
count++;
}
if (ivel1 < 0) {
count++;
}
if (fvel1 < 0) {
count++;
}
if (dis1 < 0) {
count++;
}
if (count > 2) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(
Linmotion.this);
final AlertDialog alert = alertDialog.create();
alert.show();
alertDialog.setTitle("Error");
alertDialog
.setMessage("Please input values into at least 3 fields");
alertDialog.setPositiveButton("OK",new DialogInterface.OnClickListener() {
// function of dialog button
public void onClick(DialogInterface dialog,
int id) {
alert.cancel();
}
});
}
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.linmotion, menu);
getActionBar().setDisplayShowTitleEnabled(false);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
The if statements and the other Double.parseDouble lines have been commented out because every time I try to debug the code the app crashes the instant Linmotion is created. I suspect its from the fact that onCreate runs the Double.parseDouble code and the values in the field are null. I tried to fix this with the if statements and it still crashes. I'm not sure where to go from here.
Again, if I wasn't clear I just want the values inputted into the EditText to return a double and then use that double in the Java code to run some equations and an alert dialog if not enough fields have been filled in.
EDIT/UPDATE:
I finally figured out what was wrong with my code. I took in advice from everyone and revised accordingly, so here it is:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_linmotion1);
time = (EditText) findViewById(R.id.eTexttime);
acc = (EditText) findViewById(R.id.eTextacc);
dis = (EditText) findViewById(R.id.eTextdis);
ivel = (EditText) findViewById(R.id.eTextivel);
fvel = (EditText) findViewById(R.id.eTextfvel);
solve = (Button) findViewById(R.id.buttonSolve);
solve.setOnClickListener(new OnClickListener() {
#SuppressWarnings("deprecation")
#Override
public void onClick(View v) {
count=0;
if (time.getText().toString().equals("")){
count++;
}
if(dis.getText().toString().equals("")){
count++;
}
if(fvel.getText().toString().equals("")){
count++;
}
if(ivel.getText().toString().equals("")){
count++;
}
if(acc.getText().toString().equals("")){
count++;
}
if (count>2){
// TODO Auto-generated method stub
final AlertDialog alert= new AlertDialog.Builder(Linmotion.this).create();
alert.setTitle("Oops");
alert.setMessage("Please input values in at least 3 fields.");
alert.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
alert.cancel();
}
});
alert.show();
count=0;
}
if(!(time.getText().toString().equals(""))){
time1=Double.parseDouble(time.getText().toString());
}
if(!(acc.getText().toString().equals(""))){
acc1=Double.parseDouble(acc.getText().toString());
}
if(!(dis.getText().toString().equals(""))){
dis1=Double.parseDouble(dis.getText().toString());
}
if(!(ivel.getText().toString().equals(""))){
ivel1=Double.parseDouble(ivel.getText().toString());
}
if(!(fvel.getText().toString().equals(""))){
fvel1=Double.parseDouble(fvel.getText().toString());
}
} });
}
In regard to the issues I had with the alertdialog I realized that my count integer would continue to increase every time the solve button was clicked. To fix this I simply equaled the integer to 0 at the beginning of the onclicklistener and at the end of the if statement regarding the dialog. Thanks everyone.
It looks to me like you're doing it right. I think the problem might be that it's in your OnCreate method.
Try making the Button Solve's OnClick method run your commented code before doing the logic!
You can get the value from an EditText using getText()..
See this link for more details
According to the docs getText() returns an Editable.
so,
time = (EditText) findViewById(R.id.EditText01);
String value = time.getText().toString();
Now, as i've said earlier, since getText() returns an Editable you need to convert it into String before you use it..
So, change
if (!(time.getText() == null)) {
to
if (!(time.getText().toString() == null)) {
Also, if you want to check if the EditText is empty or not, try like this..
if (!(time.getText().toString() .equals(""))) {
Try this answer..
Your code isn't working because you are trying to read these text fields on creation. This is not what you want to do.
You are trying to access the EditTexts before the page finishes loading. Instead, you need to do this in an event handler, like you have for the buttons. Read the values in an event handler, not in onCreate.
The simplest option would be to add an "update" button and do all those operations in the onClick handler for that button.
Most likely your EditText fields initially contain text, that cannot be parsed with Double.parseDouble (Something like the empty string). A NumberFormatException is thrown is this case. If you want to get the values at the time solve button is clicked, you have to get the text inside OnClickListener.onClick (otherwise you use the initial strings, i.e. the strings in the android:text attributes in the activity_linmotion1 layout). To handle invalid input, you can simply catch the NumberFormatException:
solve.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
try {
double time1 = Double.parseDouble(time.getText().toString());
double acc1 = Double.parseDouble(acc.getText().toString());
double ivel1 = Double.parseDouble(ivel.getText().toString());
double fvel1 = Double.parseDouble(fvel.getText().toString());
double dis1 = Double.parseDouble(dis.getText().toString());
// ... rest of your original listener code
} catch (NumberFormatException ex) {
// show error in dialog or something
}
}
});
Oncreate is the first method called when an activity is created, so by the time the onCreate is called, the editText is having an empty string which you are giving as an input to parseDouble which will give NumberFormatException.
You can avoid this crash by putting a button and handling the button onClick event. Inside this button click you collect the values from editfield. You can handle on click by defining listeners in the following way
<Button android:id="#+id/mybutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click me!"
android:onClick="yourHandlerName" />
Now define your onClick with getText to get text from editfield in the following way
public void yourHandlerName(View v) {
switch(v.getid()) {
case R.id.mybutton: Double.parseDouble(editField.getText().to string());
}
You have to register a Listener. Because onCreate() is called when the Actvity first start. This means that you can't get the text from your EditTexts because the Actvity is creating. But you can use your OnClickListener or other Listeners. You can easily write your commented lines to the OnClickListener. At the time you are clicking the button the method getText().toString() return the values. If you want to do it without clicking on a button use addTextOnChangedListener() on yout EditText.

How to store and retrieve what was selected from a single choice item

I have the following code:
protected void showSelectToDialog() {
boolean[] checkedDate = new boolean[toDate.length];
int count = toDate.length;
DialogInterface.OnClickListener setD2 = new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//TODO Auto-generated method stub
onChangeSelectedTo(which);
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Select To Year");
builder.setSingleChoiceItems(toDate, count, setD2);
builder.setCancelable(true);
builder.setPositiveButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
dialog2 = builder.create();
dialog2.show();
}
protected void onChangeSelectedTo(int j) {
bTo.setText(toDate[j]);
sTo = ((AlertDialog)dialog2).getListView().getCheckedItemPosition();
blTo = true;
displayToast(String.valueOf(sTo));
to = j;
dialog2.dismiss();
}
What I am looking to do is, when the dialog loads the first time and the user selects a choice it is stored. So the next time the user opens the dialog, it will remember what was select and scroll to that choice.
How do I accomplish that?
Save the selected choice's position for the first time using Shared Preferences.
Then at the start of showSelectToDialog() check if any value exists in Shared Preferences, if so, then set the value of count from the Shared Preferences else set value of count to toDate.length.
I can't see the rest of your code, but all you have to do is save the user's choice in a variable somewhere else, and then read that choice every time you open the dialogue. It could be a static variable on the class, or it could be an instance variable of the class, or it could be a public field of some other class you have access to, like a parent object. You just need to assign it when you close the dialogue, and read it back and initialize the value to what you read when you open the dialogue.

Categories