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.
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 want to make a bottom dialog which will display a text I provide and I can hide and show it whenever I want. This dialog will be shown in all activities. For example, if the app is not connected to the server right now I will show this bottom dialog saying "No connection" and this dialog will be displayed in any activity which is on the screen. How to make this dialog, I tried to make it in XML but I needed to write its show/hide methods in every activity which is a tedious work.
Here is an image which shows the bottom dialog which I am trying to make.
Create a custom dialog box that is easy to show on all activities. A dialog box can be customized as the style in your picture.
Here is an example, requestFeature() must be called before adding content, Other settings need to be after setContentView().
public class YOUR_DIALOG extends Dialog {
private String mText;
public YOUR_DIALOG(Context context, String text) {
super(context);
requestWindowFeature(Window.FEATURE_NO_TITLE);
mText = text;
}
#Override
public void onStart() {
super.onStart();
Window dialogWindow = getWindow();
dialogWindow.getAttributes().width = android.widget.ListPopupWindow.MATCH_PARENT;
dialogWindow.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL);
dialogWindow.setBackgroundDrawable(new ColorDrawable(0xffff7320));
dialogWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
}
// Everything else remains the same, as is the case with the normal dialog box.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_dialog_layout);
textview = findViewById(...);
textview.setText(mText);
}
}
And the layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/textview"
android:textAppearance="#android:style/TextAppearance.Material.Medium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:padding="10dp"
android:drawablePadding="10dp"
android:drawableLeft="#mipmap/ic_launcher"
android:textStyle="bold"
android:textColor="#fff"/>
</LinearLayout>
In your activity
new YOUR_DIALOG(this,"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.
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.
Edit: I have looked at the error page for this; no answers work. It seems it is an Android system bug that has not yet been solved.
First off I've referred to this similar question. But the solution to that question does not seem to be the solution to mine. I have a DialogFragment that contains only a WebView. Everything in the WebView seems to be touchable. However, the problem is that when I touch a form field, the cursor appears but the soft keyboard never shows up!
Here's my code in the onCreateDialog() method within the DialogFragment class:
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
WebView web = new WebView(getActivity());
web.loadUrl(InternetDialog.this.url);
web.setFocusable(true);
web.setFocusableInTouchMode(true);
web.requestFocus(View.FOCUS_DOWN);
web.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_UP:
if (!v.hasFocus()) {
v.requestFocus();
}
break;
}
return false;
}
});
builder.setView(web);
return builder.create();
How can I get the soft keyboard to show up when I select a form field?
This is a system bug that has not yet been fixed. More information can be found here. It seems as though this bug occurs differently for people and therefore has different solutions. For my particular case, there is only one solution (as I've tried everything else). Solution:
First, I created a layout for the Dialog:
<?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"
android:orientation="vertical" >
<EditText
android:id="#+id/edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true"
android:visibility="invisible"/>
<WebView
android:id="#+id/web"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
Then, in the DialogFragment class in the onCreateDialog method:
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = LayoutInflater.from(getActivity());
View v = inflater.inflate(R.layout.internet_dialog, null);
WebView web = (WebView) v.findViewById(R.id.web);
EditText edit = (EditText) v.findViewById(R.id.edit);
edit.setFocusable(true);
edit.requestFocus();
web.loadUrl(url);
this.webView = web;
builder.setView(v);
return builder.create();
And that's all there was to it. The reason this worked was because I made an EditText which I gave the focus to yet made invisible. Since the EditText is invisible it doesn't interfere with the WebView and since it has focus it pulls the soft keyboard up appropriately. I hope this helps any stuck in a similar situation.