So this is another problem that has been brought up a million times, but I'm still doing something wrong. Using EditText.getText() is returning an empty string.
I'm doing this in a small custom dialog I've made. I'm building it with the AlertDialog Builder, which might be causing the issue? I really don't know at this point.
Some things I've tried/notes on what I know about the issue:
I'm checking for text in the OK button's click listener, so I'm not trying to get a value before there would be one, which was a common error I saw.
I have ID's set for the EditText objects in my XML and the debugger seems to show that I'm referencing them properly.
I've tried defining the EditText objects outside of the onCreateDialog method and that didn't change things (though I am curious which is better practice).
Using EditText.setText() before getText() will allow it to return the argument used in setText(), but it doesn't seem to be fetching a value input by the user.
Here is my custom Dialog Fragment:
public class GPSLocationDialogFragment extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
final View view = inflater.inflate(R.layout.gps_dialog, null);
final EditText latitudeText = (EditText) view.findViewById(R.id.latitude);
final EditText longitudeText = (EditText) view.findViewById(R.id.longitude);
// Define the dialog
builder.setView(inflater.inflate(R.layout.gps_dialog, null))
.setMessage("Manually input a GPS address")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Log.d("myTag", "Text: " + latitudeText.getText()); // This prints ""
// These throw errors since they're trying to parse "" as a double
double latitude = Double.parseDouble(latitudeText.getText().toString());
double longitude = Double.parseDouble(longitudeText.getText().toString());
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
// Create the AlertDialog object and return it
return builder.create();
}
}
Here is how I'm calling the Dialog from my Activity:
GPSLocationDialogFragment gpsDialog = new GPSLocationDialogFragment();
gpsDialog.show(getFragmentManager(), "GPSDialog");
And here is my layout .xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="#+id/longitude"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="16dp"
android:layout_marginBottom="4dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:hint="#string/longitude"
android:inputType="numberSigned|numberDecimal" />
<EditText
android:id="#+id/latitude"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="16dp"
android:layout_marginBottom="4dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:hint="#string/latitude"
android:inputType="numberSigned|numberDecimal" />
</LinearLayout>
If more context is necessary I can share it, I tried to simplify to just the relevant code.
Try changing this:
builder.setView(inflater.inflate(R.layout.gps_dialog, null))
to this:
builder.setView(view)
What's happening is that you inflate gps_dialog xml and turn its layout hierarchy into a View. Then you find the EditText's and a assign a reference to them.
However, by calling setView(inflater.inflate(R.layout.gps_dialog, null))
instead of passing the View that you already inflated, and whose child EditText's you have a reference to, to the dialog, what you are doing is inflating a new version of the gps_dialog.xml and passing that to the dialog. The references that you have are to EditText's that aren't on the screen.
Related
I'm making an android app and i want to put a settings button on every layout in the app. When i press the settings button, a custom dialog pops up and i can access the app settings.
The problem i'm having is that i want to refer to 1 method in some class (doesn't matter to me which one). I'm already using the include in my XML of my layouts like this:
<include android:id="#+id/settingsButton"
layout="#layout/settingsbuttonlayout"/>
The settingsbuttonlayout.xml file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/root_vg">
<ImageButton
android:layout_width="50dp"
android:layout_height="50dp" app:srcCompat="#drawable/settingsicon"
android:id="#+id/settings_dialog"
android:cropToPadding="true"
android:adjustViewBounds="false" android:scaleType="fitCenter"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintHorizontal_bias="0.133"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintVertical_bias="0.123"
android:clickable="true"
android:focusable="true"
android:background="#drawable/customdialog" android:onClick= "showSettings"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
You can see that there is an onclick defined in this layout. However (for as far as i know) this means i need the same "showSettings" method in every layout class. How can i work around this so i should only write the "showSettings" method once and can refer to it?
This is the showSettings method:
public void showSettings(View v){
Dialog dialog = new Dialog(this, R.style.DialogStyle);
dialog.setContentView(R.layout.settings_dialog);
dialog.getWindow().setBackgroundDrawableResource(R.drawable.dialogbackground);
Button btnClose = dialog.findViewById(R.id.close_settings);
btnClose.setOnClickListener(view -> dialog.dismiss());
dialog.show();}
PS: I'm pretty new into making apps and GUI's. I didn't learn it yet in school and i'm just figuring out everything myself so sorry if this is some straightforward or stupid question :)
you can remove the onClick attribute from your setttings_dialog which calls the showSettings, next create a Utility.java file in which you can make your function as static
public static void showSettings(View v){
Dialog dialog = new Dialog(this, R.style.DialogStyle);
dialog.setContentView(R.layout.settings_dialog);
dialog.getWindow().setBackgroundDrawableResource(R.drawable.dialogbackground);
Button btnClose = dialog.findViewById(R.id.close_settings);
btnClose.setOnClickListener(view -> dialog.dismiss());
dialog.show();}
now in whichever class you want to call this method just write
Button settingsButton = (Button) findViewById(R.id.settingsButton);
settingsButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Utility.showSettings(v);
}
});
After searching some more I found the following:
From whichever class i wanted to open the dialog i have to write this:
SettingsDialog.showSettings(this);
In my SettingsDialog class i have the following:
public class SettingsDialog {
static void showSettings(Context context) {
Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.settings_dialog);
Dialog.getWindow().setBackgroundDrawableResource(R.drawable.dialogbackground);
}
dialog.show();}
}
I'm trying to make a custom NumberPicker to display in a DialogFragment. So far I've succeeded in getting the picker to display in a dialog fragment and getting it to display the custom strings I want it to. I've also disabled the descendantFocusability so the text is not editable. Here is an overview of the questions I have about NumberPicker behaviour, I'll go more in depth after:
How does one 'commit' their selection?
How to return the selected value?
How does one 'commit' their selection?
When the dialog appears, I don't see a clear way to 'select' an option (see image below). Looking at native Android selection dialogs, I often see radiobuttons. Is that the way to go? And am I using the wrong UI component to build this?
How to return the selected value?
This question is tightly knit with the last one, as not knowing how to commit a selection obviously doesn't help here. Right now I use NumberPicker.OnValueChangeListener to see if the value changed, however it never fires. Here's how I structured the code:
class PlatePickerFragment: DialogFragment() {
lateinit var listener: NumberPicker.OnValueChangeListener
//I set up the fragment with onCreateDialog here.
}
And this is the code I use when I create an instance:
val platePicker = PlatePickerFragment()
platePicker.listener = NumberPicker.OnValueChangeListener { numberPicker, i1, i2 ->
//set what to do on value change here.
}
However, this block never gets called.
TL;DR: Am I using the right UI component? If I am, how would I implement this in a way that it works? Why does the NumberPicker not have a cancel/ok section by default (see image of DatePicker below)? Thanks in advance!
Answer to first part :
This is the ideal way of implementing NumberPicker. One thing you can do
is add an OK button to side to catch selection.See screenshot
Code for same :
picker.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="#+id/rl"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:padding="16dp">
<TextView
android:id="#+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:padding="5dp"
android:text="OK"
android:textSize="15dp" />
<NumberPicker
android:id="#+id/numberPicker"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/tv"
android:layout_marginTop="10dp" />
</RelativeLayout>
</LinearLayout>
In your activity :
final NumberPicker aNumberPicker = (NumberPicker) dialog.findViewById(R.id.numberPicker);
aNumberPicker.setMaxValue(12);
aNumberPicker.setMinValue(1);
aNumberPicker.setValue(1);
aNumberPicker.setFocusable(true);
aNumberPicker.setFocusableInTouchMode(true);
aNumberPicker.setOnScrollListener(new NumberPicker.OnScrollListener() {
#Override
public void onScrollStateChange(NumberPicker view, int scrollState) {
value = view.getValue();
}
});
aNumberPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
#Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
value = newVal;
}
});
TextView ok = (TextView) parent.findViewById(R.id.tv);
ok.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// value variable can be used here
}
});
Declare value as global variable.
Answer to the second part of your question :
int hour;
numberPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
#Override
public void onValueChange(final NumberPicker numberPicker, final int i, final int i1) {
hour = Integer.valueOf(numberPicker.getDisplayedValues()[numberPicker.getValue()]);
}
});
On clicking of OK button you will have answer in hour variable.
Im having trouble regarding dialogs, so Ive been re-reading the android docs several times over, and am still unsure about the following things and would really appreciate if anyone can answer my questions...
Before i ask my questions ill show my code...
CustomDialog (Straight copy from android dev. site)
public class FireMissilesDialogFragment extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the layout inflater
LayoutInflater inflater = getActivity().getLayoutInflater();
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
builder.setView(inflater.inflate(R.layout.dialog_createlocation, null))
.setTitle(R.string.dialog_createlocationtitle)
// Add action buttons
.setPositiveButton(R.string.create, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
FireMissilesDialogFragment.this.getDialog().cancel();
}
});
return builder.create();
}
}`
and here is the layout for the dialog(dialog_createlocation.xml)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<EditText
android:id="#+id/EditTextName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginBottom="4dp"
android:hint="#string/name"
android:maxLines="1"/>
<EditText
android:id="#+id/EditTextAddress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginBottom="16dp"
android:fontFamily="sans-serif"
android:hint="#string/address"
android:maxLines="2"/>
Questions:/n
In my main activity, I want to get the text from the two EditText in the dialog. Although Ive seen some SO questions about this but im so overwelmed and cant seem to understand the answers./n
2.Is it necessary for me to create this dialog in its own class?-can i just create it in my main activity(- without creating an inner class)?/n
3.Im confused with why to create a custom dialog, it has to extend a fragment-why not just an activity?/n
4.I create an instance of the above dialog in my main activity (which is not a fragment) and i got some issues doing this:
public void showNoticeDialog() {
// Create an instance of the dialog fragment and show it
DialogFragment dialog = new FireMissilesDialogFragment();
dialog.show(getSupportFragmentManager(), "NoticeDialogFragment");
}
Thanks!
In my main activity, I want to get the text from the two EditText in
the dialog. Although Ive seen some SO questions about this but im so
overwelmed and cant seem to understand the answers.
EditText editTextName = dialog.getDialog().findViewById(R.id.EditTextName);
String name = editTextName.getText().toString();
Is it necessary for me to create this dialog in its own class?-can i just create it in my main activity(- without creating an inner
class)?
Yes, you can. AlertDialog just give you already present structure for your dialog. But to make your own just use Dialog Class.
3.Im confused with why to create a custom dialog, it has to extend a fragment-why not just an activity?
Its not necessary to use only Fragment for Dialog. as per second answer.
4.I create an instance of the above dialog in my main activity (which is not a fragment) and i got some issues doing this:
Post stacktrace or error log for this.
This question already has answers here:
Multiple EditText objects in AlertDialog
(4 answers)
Closed 8 years ago.
I've implemented an alert dialog containing one edit text for name but I need to store other info such a quantity location using the same alert dialog.
I tried to add another edit text by simply declaring another but this didn't populate the dialog with another edit text.
Does anyone now how you can add extra edit text object to an alert dialog?
This is how I've implemented an alert dialog for containing one edit text:
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("Generic Info");
alert.setMessage("Ship Name");
// Set an EditText view to get user input
final EditText input = new EditText(this);
alert.setView(input);
//need to add two more edit text fields for extra input.
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
Editable value = input.getText();
// Do something with value!
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Canceled.
}
});
alert.show();
return true;
Try this
Create res/layout/custom_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Text 1"
android:id="#+id/editText" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Text 2"
android:id="#+id/editText2" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Text 3"
android:id="#+id/editText3"
android:layout_gravity="center_horizontal" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Text 4"
android:id="#+id/editText4" />
</LinearLayout>
Then in your Activity that you want AlertDialog to show use:
AlertDialog.Builder builder = new AlertDialog.Builder(context);
LayoutInflater inflater = getActivity().getLayoutInflater();
builder.setTitle("Custom view with 4 EditTexts");
builder.setMessage("AlertDialog");
builder.setView(R.layout.custom_view);
//In case it gives you an error for setView(View) try
builder.setView(inflater.inflate(R.layout.custom_view, null));
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
return builder.create();
And this will give you the following result:
Create a Relative Layout
add as many edittext as you want
and then set relative layout in alert.setView(relativeLayout);
can not write whole code for you
but see here custom layout , this will surely help you .
Can someone tell me how should i create the above view here via xml or java coding in android?
This is what i have tried so far... But the view just seems to look too plain without any pictures by the side of each string as shown in the above link? What should i do to get the sort of more professional view?
final String [] items = new String []{"Details", "Delete File"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("File Options");
builder.setItems(items, new OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
if(arg1 == 0)
{
startActivity(new Intent(getApplicationContext(), DialogBox.class));
}
else
{
deleteFile();
}
}
});
builder.create().show();
You can check this code
This to show the dialog and code for each button,as we do in onCreate.
private void showRules() {
final Dialog ruleDialog = new Dialog(this);
ruleDialog.setContentView(R.layout.ruledialog);
Button cancelbtn = (Button)ruleDialog.findViewById(R.id.cancelbtn);
//cancelbtn.setOnClickListener(this);
cancelbtn.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
ruleDialog.dismiss();
}
});
ruleDialog.setCancelable(true);
ruleDialog.show();
//dialog.setTitle("How");
}
This the xml that I have use for it,
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/dialogHead"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="#string/dialogHead"
android:paddingBottom="20px"
android:layout_alignParentTop="true"
/>
<Button
android:id="#+id/cancelbtn"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:background="#drawable/ic_cancel"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:paddingRight="3px"
android:paddingTop="3px"
/>
<ScrollView
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:layout_below="#id/dialogHead"
>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="#string/dialogBody"
/>
</ScrollView>
</RelativeLayout>
I hope this will help you.
see here: http://developer.android.com/guide/topics/ui/dialogs.html#CustomDialog you can create your own layout and define what ever you'd like. as for professionalism - thats in the eye of the beholder.
Edit:
so don't use your string array to set your text.
create a layout that has a TextView ImageView TextView. use the layout inflator to inflate the view. find the 1st textview and setText("Details") (if you didn't do it statically in the xml)
find the second textview and setText("Delete") (if you didn't do it statically in the xml)
find the image and setImageResource (if you didn't do it statically in the xml)
set the builders view to your layout.
oh and maybe add some buttons with onclick listeners to do your stuff. or use an alertdialogbuilder.