I can't seem to wrap my head around custom dialogs. I've tried many variations, but so far no luck.
This is my current xml for the dialog:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/edit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical" >
<TextView
android:id="#+id/Word"
android:text="Word?"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left|center_vertical"/>
<EditText
android:layout_height="100dp"
android:layout_width="match_parent"
android:id="#+id/lookupWordEdit"
android:inputType="text"/>
</RelativeLayout>
And here is the code:
public class LookupWordDialogFragment extends DialogFragment {
private EditText mEditText;
public LookupWordDialogFragment() {
// Empty constructor required for DialogFragment
}
public interface LookupWordDialogListener {
void onFinishEditDialog(String inputText);
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the layout inflater
LayoutInflater inflater = getActivity().getLayoutInflater();
final EditText lookupWordEdit = (EditText)getActivity().findViewById(R.id.lookupWordEdit);
// 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_lookupword, null))
// Add action buttons
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
// Return input text to activity
LayoutInflater inflater = getActivity().getLayoutInflater();
final EditText lookupWordEdit = (EditText)getActivity().findViewById(R.id.lookupWordEdit);
LookupWordDialogListener activity = (LookupWordDialogListener) getActivity();
activity.onFinishEditDialog(lookupWordEdit.getText().toString());
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
LookupWordDialogFragment.this.getDialog().cancel();
}
});
return builder.create();
}
}
The code currently crashes with a null pointer exception on this line:
activity.onFinishEditDialog(lookupWordEdit.getText().toString());
I suspect that Im not correctly grabbing the lookupWordEdit. The dialog is very simple. How am I supposed to grab the entered text when the user taps the OK button?
Thank you!
You need to change this
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_lookupword, null);
builder.setView(view);
Now here you rare using EditText inside AlertDialog
EditText lookupWordEdit = (EditText)view.findViewById(R.id.lookupWordEdit);
lookupWordEdit EditText is inside AlertDialog Layout instead of DialogFragment layout so you will need to use same View instance which you are passing in setView of AlertDialog for accessing EditText from AlertDialog layout do it as:
LayoutInflater inflater = LayoutInflater.from(getActivity());
View dialogview = inflater.inflate(R.layout.dialog_lookupword, null);
// now pass dialogview to setView of Dialog
builder.setView(dialogview);
.....
now use dialogview for initializing EditText from dialog_lookupword layout as:
EditText lookupWordEdit = (EditText)dialogview.findViewById(R.id.lookupWordEdit);
Related
Good evening out there,
i am trying to use an alert dialog in an Fragment (Cause of the TabNavigation). It is nessesary that i use the layout "privacy".
But eclipse gave me an error at the "AlertDialog.Builder": (The constructor AlertDialog.Builder(AboutActivity2) is undefined)
and at the ".from" after the inflate: (The method from(Context) in the type LayoutInflater is not applicable for the arguments (AboutActivity2))
Thanks for help,
greetings
View rootView = inflater.inflate(R.layout.activity_about2, container, false);
rootView.findViewById(R.id.privacybutton).setOnClickListener(this);
return rootView;
}
final OnClickListener mGlobal_OnClickListener = new OnClickListener() {
public void onClick(View v) {
switch(v.getId()) {
case R.id.privacybutton:
AlertDialog.Builder alertDialog = new AlertDialog.Builder(getActivity());
LayoutInflater factory = LayoutInflater.from(getActivity());
final View view = factory.inflate(R.layout.privacy, null);
alertDialog.setView(view);
alertDialog.setNegativeButton("Schließen", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {
dialog.dismiss();
}
});
alertDialog.show();
break;
}
}
AlertDialog.Builder receives a context as parameter. And not a fragment.
http://developer.android.com/reference/android/app/AlertDialog.Builder.html#AlertDialog.Builder(android.content.Context)
Use getActivity() instead :
AlertDialog.Builder alertDialog3 = new AlertDialog.Builder(getActivity());
LayoutInflater factory3 = LayoutInflater.from(getActivity());
You also need to add the listener to your button. You can do it like this:
View rootView = inflater.inflate(R.layout.activity_about2, container, false);
rootView.findViewByID(R.id.privacybutton).setOnClickListener(this);
return rootView;
FINAL CODE
View rootView = inflater.inflate(R.layout.activity_about2, container, false);
rootView.findViewById(R.id.privacybutton).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(v.getContext());
LayoutInflater factory = LayoutInflater.from(v.getContext());
final View view = factory.inflate(R.layout.privacy, null);
alertDialog.setView(view);
alertDialog.setNegativeButton("Schließen", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog.show();
}
});
return rootView;
your_dialouge_fragment dppr = new your_dialouge_fragment();
dppr.show(getActivity().getSupportFragmentManager(),"mmtag");
This worked for me.
You can use normal dialog for showing alert. Alert dialog has also derived from dialog, You need to just write an custom XML for view and set the view to dialog.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp" />
<TextView
android:id="#+id/text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#FFF"
android:layout_toRightOf="#+id/image"/>/>
<Button
android:id="#+id/dialogButtonOK"
android:layout_width="100px"
android:layout_height="wrap_content"
android:text=" Ok "
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:layout_below="#+id/image"
/>
</RelativeLayout>
// custom dialog
final Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.custom);
dialog.setTitle("Title...");
// set the custom dialog components - text, image and button
TextView text = (TextView) dialog.findViewById(R.id.text);
text.setText("Android custom dialog example!");
ImageView image = (ImageView) dialog.findViewById(R.id.image);
image.setImageResource(R.drawable.ic_launcher);
Button dialogButton = (Button) dialog.findViewById(R.id.dialogButtonOK);
// if button is clicked, close the custom dialog
dialogButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.show();
In my opinion, the problem is about Context and it's related to fragment.
Try getting the context of the application instead of the context of the class (AboutActivity2.this)
AlertDialog.Builder alertDialog3 = new AlertDialog.Builder(getActivity());
or
AlertDialog.Builder alertDialog3 = new AlertDialog.Builder(v.getContext());
Please try and tell if it works.
Better you go for the DialogFragment instead of AlertDialog or Dialog becasue DialogFragment is easy to implement and it has it own lifecycle methods which can be useful to handle other events or data handling.
See this Google link -
https://developer.android.com/guide/fragments/dialogs
So reading through the Google API Guides I came across how to load a custom layout within an Alert Dialog Box here.
I wrote a class that extends a DialogFragment class like this:
String product;
String description;
String company;
public void getAdInfo(String p, String d, String c)
{
product = p;
description = d;
company = c;
}
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
builder.setView(inflater.inflate(R.layout.ad_dialog, null));
TextView pt = (TextView) getView().findViewById(R.id.product);
pt.setText(product);
TextView dt = (TextView) getView().findViewById(R.id.description);
dt.setText(description);
TextView ct = (TextView)getView().findViewById(R.id.company);
ct.setText(company);
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// do something
}
});
builder.setNegativeButton("Exit", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dismiss();
}
});
return builder.create();
}
}
Here's the layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/product"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textIsSelectable="false"
/>
<TextView
android:id="#+id/company"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textIsSelectable="false"
/>
<TextView
android:id="#+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textIsSelectable="false"
/>
I instanciate the Dialog within an OnClickListener with these lines.
AdDialogFragment ad = new AdDialogFragment();
ad.getAdInfo(j.getAttribute("product"), j.getAttribute("description"), j.getAttribute("company"));
ad.show(getFragmentManager(), null);
j being an element from an xml node.
When I click on the button that's supposed to run the dialog I get this NullPointerException error from LogCat:
E/AndroidRuntime(10483): at com.onix.mallard.android.guifrag.AdDialogFragment.onCreateDialog(AdDialogFragment.java:29)
The error refers to the line:
pt.setText(product);
Ultimately, it crashes the app completely. How can I change the layout of a DialogFragment dynamically? The Android API Guide says that DialogFragments are bound by the same lifecycle as Fragments, but that doesn't tell me much since they don't make use of FragmentTransactions (to my knowledge). If this is not possible and I need to instance the information as an Activity, no harm is done.
If it helps, the dialog is called from within a Fragment.
Here's how I would do that (untested code) ;)
Your custom Dialog:
public class AdDialogFragment extends DialogFragment {
String mProduct;
String mDescription;
String mCompany;
TextView mProductTV;
TextView mDescriptionTV;
TextView mCompanyTV;
public void setAdInfo(String product, String desc, String company)
{
mProduct = product;
mDescription = desc;
mCompany = company;
}
public AdDialogFragment() {
super();
}
public static AdDialogFragment newInstance() {
return new AdDialogFragment();
}
public Dialog onCreateDialog(final Bundle savedInstanceState) {
LayoutInflater factory = LayoutInflater.from(getActivity());
final View content = factory.inflate(R.layout.ad_dialog, null);
mProductTV = (TextView) content.findViewById(R.id.product);
mDescriptionTV = (TextView) content.findViewById(R.id.description);
mCompanyTV = (TextView) content.findViewById(R.id.company);
fillTextViews();
AlertDialog.Builder dialog;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
dialog = new AlertDialog.Builder(new ContextThemeWrapper(getActivity(), R.style.Theme.DeviceDefault.Dialog.)); //can't remember the name or create a custom theme.
} else {
dialog = new AlertDialog.Builder(getActivity());//anything below honeycomb can die :).
}
// now customize your dialog
dialog.setTitle(getActivity().getString(R.string.some_title_if_any))
.setView(content)
.setCancelable(true) //this is the default I think.
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// do something
}
});
.setNegativeButton("Exit", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dismiss();
}
});
return dialog.create();
}
private void fillTextViews() {
mProductTV.setText(mProduct);
mDescriptionTV.setText(mDescription);
mCompanyTV.setText(mCompany);
}
And this is how you call it from an Activity for example:
public void showYourFancyDialog() {
AdDialogFragment dialog = AdDialogFragment.newInstance();
dialog.setAdInfo(yourProduct, yourDescription, yourCompany);
dialog.show(getSupportFragmentManager(), "dialog");
}
Using patterns from Google's documentation
You could try the following, it has worked for me:
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View v = inflater.inflate(R.layout.ad_dialog, null));
builder.setView(v);
And then call findViewById like such:
v.findViewById();
I solved this issue a while ago by instead of recurring to the AlertDialog class I used a regular Activity. In AndroidManifest.xml, the activity specification has the following line.
android:theme="#styles/Theme.HoloLight.Dialog"
A word of advice, Linear Layout doesn't work. Try RelativeLayout.
i am displaying a custom dialog for user input on top of my list view activity layout. But when i try to refer the edit text in onCreateDialog() method, its always coming as blank. Below is my code, appreciate if someone can point out where i am doing wrong -
public class QuestionDialog extends DialogFragment
{
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
final View v =inflater.inflate(R.layout.ques_dialog,null);
builder.setView(inflater.inflate(R.layout.ques_dialog, null))
.setTitle("Title Message!")
.setCancelable(true)
.setPositiveButton("GO", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int whichButton)
{
EditText et1 = (EditText)v.findViewById(R.id.et1);
// here not able to get the data from edit text
String s1 = et1.getText().toString().trim();
Log.d("debug","data -"+s1+" and length"+s1.length());
.... rest code goes here
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int whichButton)
{
..rest code goes here
}
});
return builder.create();
}
}
That is happening because of this lines:
final View v =inflater.inflate(R.layout.ques_dialog,null);
builder.setView(inflater.inflate(R.layout.ques_dialog, null))
You first inflate the v View and then set as the content of the dialog a newly inflated view(so in the end you end up looking for a view which isn't the actual content of the dialog). Use this:
final View v =inflater.inflate(R.layout.ques_dialog,null);
builder.setView(v);
I'm trying to make an alert dialog with dynamic text. The problem is that the textview I want to edit is in an inflated Layout.
At the topmost of my code is
TextView tv;
so I can reach it from all methods in my class. Code snippet below:
public class EditNameDialog extends DialogFragment {
public EditNameDialog()
{
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater factory = LayoutInflater.from(getActivity());
View textEntryView = factory.inflate(R.layout.fragment_dialog, null);
this.setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Holo_Light_Dialog);
return new AlertDialog.Builder(getActivity())
.setTitle("Skapa profil")
.setView(textEntryView)
.setNegativeButton(R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
}
)
.setPositiveButton(R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton)
{
}
}
).create();
}
And the layout file "fragment_dialog.xml" looks like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/error_dialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="top"
android:padding="10dp"
android:text="#string/error_connecting"
android:textSize="20sp" />
</LinearLayout>
I want to edit the TextView, which resides in the "textEntryView".
To do this i have tried
tv = (TextView) textEntryView.findViewById(R.id.error_dialog);
and then when I call my method:
public void attemptLogin(View v)
{
System.err.println(tv.getText());
}
it gives me a Nullpointer.
I don't understand why the id error_dialog cannot be found within the textEntryView View.
Thanks.
I can not see a declaration for your variable tv, like:
TextView tv = (TextView) findViewById(R.id.error_dialog);
If you have not declarate it, your framework (eclipse?) should give you a hint.
So did you declarate it in an other part of your class?
your problem is a bit more complicated than it looks. You are losing the reference to your widgets as the View-Object doesn't hold the correct View when you do it like this. I had the same issue and it took me a while figuring it.
I solved it by keeping the View-reference updated and outsourcing the retrieving of the textView-value to a later-in-lifecycle-called-method like onActivityCreated()
I posted my example that does have an editText and a Button.
My Example:
public class EnterNumberFragment extends DialogFragment implements OnClickListener{
private EditText editText = null;
private Button acceptButton = null;
private View mContentView = null;
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflator= getActivity().getLayoutInflater();
mContentView = inflator.inflate(R.layout.dialog_number, null);
builder.setView(mContentView);
return builder.create();
}
#Override
public void onActivityCreated(Bundle arg0) {
super.onActivityCreated(arg0);
acceptButton = (Button) mContentView.findViewById(R.id.accept_change);
editText = (EditText) mContentView.findViewById(R.id.et_number);
acceptButton.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.accept_change:
String num = editText.getText().toString();
SharedPreferences sPrefs = getActivity().getSharedPreferences("PanicPrefs",0);
SharedPreferences.Editor prefEditor = sPrefs.edit();
prefEditor.putString("NumberToCall", num).commit();
dismiss();
break;
default:
break;
}
}
The problem exist in this line:-
LayoutInflater factory = LayoutInflater.from(getActivity());
you don't have a reference of activity. What you can do is to pass an activity context and then get the activity:-
LayoutInflater factory = LayoutInflater.from(mContext.getActivity());
or you can use following code:-
LayoutInflater factory = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
I am a self-taught beginner and appreciate patience! Thanks!
In Eclipse, I made a custom alertdialog with its own xml file ("custom_dialog") and it is called "usernamealert".
I want an alert to pop-up if the user hasn't entered a username yet (ie, username.length == 0).
Inside this layout I have a textView ("What is your name?"), editText and button ("usernameButton").
Before putting in the onclicklistener for the button, everything worked. This was my (relevant) Java:
LayoutInflater inflater = getLayoutInflater();
View dialoglayout = inflater.inflate(R.layout.custom_dialog, (ViewGroup) getCurrentFocus());
AlertDialog.Builder usernamebuilder = new AlertDialog.Builder(this);
usernamebuilder.setView(dialoglayout);
AlertDialog usernamealert = usernamebuilder.create();
When I put the onclicklistener in, it broke! Where should I have put it?
(the following is what I had tried... all in my OnCreate)
LayoutInflater inflater = getLayoutInflater();
View dialoglayout = inflater.inflate(R.layout.custom_dialog, (ViewGroup)getCurrentFocus());
AlertDialog.Builder usernamebuilder = new AlertDialog.Builder(this);
usernamebuilder.setView(dialoglayout);
Button usernameButton = (Button) usernamealert.findViewById(R.id.usernameButton);
usernameButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//store username in sharedprefs
usernamealert.dismiss();
}
});
After the code I said:
if (username.length() == 0) {
usernamealert.show();
}
Again, it worked before I started messing with the button!!
It is needed to specify where will the code search the button, if its only "findViewById" it would search in the xml of the host, it should be
LayoutInflater inflater =getLayoutInflater();
View myview = inflater.inflate(R.layout.dialoghireteachernegotiate, null);
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
builder.setView(myview);
Button addS = (Button) myview.findViewById (R.id.bAddS);
This is part of my class, Hireteachernegotiate.class, which has a layout of hireteachernegotiate.xml
AlertDialog.Builder builder = new AlertDialog.Builder(this);
// Get the layout inflater
LayoutInflater inflater =getLayoutInflater();
View myview = inflater.inflate(R.layout.dialoghireteachernegotiate, null);
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
builder.setView(myview);
Button addS = (Button) myview.findViewById (R.id.bAddS);
addS.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//do some stuff
}
});
Button minusS = (Button) myview.findViewById (R.id.bMinusS);
addS.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//do other stuff
}
});
// Add action buttons
builder.setPositiveButton("YES", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
builder.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
builder.show();
This is the dialog layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="#+id/bAddS"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="#+id/bMinusS"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
Try this.
usernamebuilder.setCancelable(false)
usernamebuilder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//do what you want.
}
});
See if that works, or if it helps in some way.