Creating Custom AlertDialog ? What is the root view? - android

what i am trying to do:
Create a custom Alert Dialog. Buttons just like any Alert Dialog but above are two TextEdit input boxes. I don't want to create a custom Dialog but a customized Alert Dialog
Here is what I am trying #3:
http://developer.android.com/guide/topics/ui/dialogs.html
It says:
AlertDialog.Builder builder;
AlertDialog alertDialog;
Context mContext = getApplicationContext();
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.custom_dialog,
(ViewGroup) findViewById(R.id.layout_root));
TextView text = (TextView) layout.findViewById(R.id.text);
text.setText("Hello, this is a custom dialog!");
builder = new AlertDialog.Builder(mContext);
builder.setView(layout);
alertDialog = builder.create();
Documentation says:
View layout = inflater.inflate(R.layout.custom_dialog,
(ViewGroup) findViewById(R.id.layout_root));
where the first parameter is the layout resource ID and the second is the ID of the root View.
Problem is I don't know what the layout root is? this is a dialog I am going to kick of in an Activity. Should I use the layout id if the activity? Is layout_root pulled out of a hat?
Also tried:
View layout = inflater.inflate(R.layout.my_custom_layout,
(ViewGroup) findViewById(android.R.id.content).getRootView());
result null pointer.

Even though an older question, this article might be useful for others who search for this answer:
Layout Inflation as Intended:
If you’ve ever written something like the following code using
LayoutInflater in your Android application:
inflater.inflate(R.layout.my_layout, null);
PLEASE read on, because you’re doing it wrong and I want to explain to
you why.
...BUT...
Every Rule Has An Exception
There are of course instances where you can truly justify a null
parent during inflation, but they are few. One such instance occurs
when you are inflating a custom layout to be attached to an
AlertDialog. Consider the following example where we want to use our
same XML layout but set it as the dialog view:
AlertDialog.Builder builder = new AlertDialog.Builder(context);
View content = LayoutInflater.from(context).inflate(R.layout.item_row, null);
builder.setTitle("My Dialog");
builder.setView(content);
builder.setPositiveButton("OK", null);
builder.show();
The issue here is that AlertDialog.Builder supports a custom view, but
does not provide an implementation of setView() that takes a layout
resource; so you must inflate the XML manually. However, because the
result will go into the dialog, which does not expose its root view
(in fact, it doesn’t exist yet), we do not have access to the eventual
parent of the layout, so we cannot use it for inflation. It turns out,
this is irrelevant, because AlertDialog will erase any LayoutParams on
the layout anyway and replace them with match_parent.
The article has an explanation on why you should supply a parent ViewGroup in most other cases than Dialog building.

Ok. The root view in the documentation refers to the element in the custom layout. So the custom layout will have an outermost view called the root view. You need to give this an Id and than you can pass it in as shown. So first argument is the custom view id, the second argument is id of the root layout element within the custom view.
View layout = inflater.inflate(R.layout.custom_dialog,
(ViewGroup) findViewById(R.id.layout_root));
So in this example given in the documentation above, R.id.layout_root refers to the id you give to say for example the outermost LinearLayout within the custom_dialog layout.

Have you tried this?
View layout = inflater.inflate(R.layout.custom_dialog,null);

builder.setView(layout);
layout.getRootView();
Should give LinearLayout.

Related

Change TextView from another XML

I my app, I have somes XML. I want to modify a TextView, but it is not in the primary XML file for this Activity.
I tried:
TextView nav_playerid = (TextView) findViewById(R.id.nav_username);
nav_playerid.setText(id_joueur_connect);
But that won't work. How can I tell the app to get this specific XML File and modify this TextView?
An unqualified findViewById will search the present contentView of the Activity
to get this specific XML File
You need to inflate the other one.
LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
final View v = inflater.inflate(R.layout.other_layout, null);
// See 'v.findViewById'
TextView nav_playerid = (TextView) v.findViewById(R.id.nav_username);
nav_playerid.setText(id_joueur_connect);
But that creates a new, blank layout, so you'd also need to add that inflated view to the content view of the activity in order to see it.

Why should I use LayoutInflater to obtain a view if I can directly obtain it using findViewById()

I am a beginner in android development and am having a hard time understanding the use of Inflater.I have already read this question:
What does it mean to inflate a view from an xml file?
Now consider this example:
LayoutInflater inflater = getLayoutInflater();
View layout = inflater.inflate(R.layout.custom_toast,
(ViewGroup) findViewById(R.id.toast_layout_root));
Toast toast = new Toast(getApplicationContext());
toast.setView(layout);
toast.show();
From what I understood we used inflater to inflate(convert) the xml layout into a View object and then we set the view using setView(layout).
But if we just had to set view of toast then why not simply use findviewbyid as follows:
Toast toast=new Toast(this);
toast.setView(findViewById(R.id.toast_layout_root));
toast.setDuration(toast.LENGTH_LONG);
toast.show();
The above code compiles but it causes the application to crash at start up.I know it is wrong to do it this way but why?
What will be the difference between the view obtained by using inflater and the view obtained using findViewById.
Its not the same thing.
Inflate takes a Layout xml file and makes a View out of it.
findViewById looks for a view inside a viewGroup.
In your example:
Your first code will inflate R.layout.custom_toast and attach it to the parent ViewGroup R.id.toast_layout_root
Your second code will take the R.id.toast_layout_root ViewGroup and set it as the layout of the dialog.
Basically your first code will end up with R.layout.custom_toast as the dialog layout while your second code will use R.id.toast_layout_root as the dialog layout.
Its clearly not the same thing, findViewById needs an already inflated View.
Hope this helps.

How to set different themes for inflated layout in a view stub

I have a layout that I'm inflating into a ViewStub. When its within view A, I want to have one set of styles applied to the EditText fields, and when it's within view B, I want to have a different set of styles applied to the EditText fields.
First, is this possible, and second (if so), how would I go about it?
I'm not sure about ViewStubs specifically, but if you wanted to inflate a predefined layout and add it to a ViewGroup you could use a ContextThemeWrapper.
View viewOne = View.inflate(new ContextThemeWrapper(context, R.style.Theme_One), R.layout.my_layout)
View viewTwo = View.inflate(new ContextThemeWrapper(context, R.style.Theme_Two), R.layout.my_layout)

Android Custom ProgressDialog with Message

I have found a lot of tutorials on how to make a custom ProgressDialog without text. What is the easiest way to create a custom ProgressDialog with a custom image and a message. Something like this...
Creating a Custom Dialog
If you want a customized design for a dialog, you can create your own layout for the dialog window with layout and widget elements. After you've defined your layout, pass the root View object or layout resource ID to setContentView(View).
For example, to create the dialog shown to the right:
Create an XML layout saved as custom_dialog.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout_root"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
>
<ImageView android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginRight="10dp"
/>
<TextView android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:textColor="#FFF"
/>
</LinearLayout>
This XML defines an ImageView and a TextView inside a LinearLayout.
Set the above layout as the dialog's content view and define the content for the ImageView and TextView elements:
Context mContext = getApplicationContext();
Dialog dialog = new Dialog(mContext);
dialog.setContentView(R.layout.custom_dialog);
dialog.setTitle("Custom Dialog");
TextView text = (TextView) dialog.findViewById(R.id.text);
text.setText("Hello, this is a custom dialog!");
ImageView image = (ImageView) dialog.findViewById(R.id.image);
image.setImageResource(R.drawable.android);
After you instantiate the Dialog, set your custom layout as the dialog's content view with setContentView(int), passing it the layout resource ID. Now that the Dialog has a defined layout, you can capture View objects from the layout with findViewById(int) and modify their content.
That's it. You can now show the dialog as described in Showing A Dialog.
A dialog made with the base Dialog class must have a title. If you don't call setTitle(), then the space used for the title remains empty, but still visible. If you don't want a title at all, then you should create your custom dialog using the AlertDialog class. However, because an AlertDialog is created easiest with the AlertDialog.Builder class, you do not have access to the setContentView(int) method used above. Instead, you must use setView(View). This method accepts a View object, so you need to inflate the layout's root View object from XML.
To inflate the XML layout, retrieve the LayoutInflater with getLayoutInflater() (or getSystemService()), and then call inflate(int, ViewGroup), where the first parameter is the layout resource ID and the second is the ID of the root View. At this point, you can use the inflated layout to find View objects in the layout and define the content for the ImageView and TextView elements. Then instantiate the AlertDialog.Builder and set the inflated layout for the dialog with setView(View).
Here's an example, creating a custom layout in an AlertDialog:
AlertDialog.Builder builder;
AlertDialog alertDialog;
Context mContext = getApplicationContext();
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.custom_dialog,
(ViewGroup) findViewById(R.id.layout_root));
TextView text = (TextView) layout.findViewById(R.id.text);
text.setText("Hello, this is a custom dialog!");
ImageView image = (ImageView) layout.findViewById(R.id.image);
image.setImageResource(R.drawable.android);
builder = new AlertDialog.Builder(mContext);
builder.setView(layout);
alertDialog = builder.create();
Using an AlertDialog for your custom layout lets you take advantage of built-in AlertDialog features like managed buttons, selectable lists, a title, an icon and so on.
For more information, refer to the reference documentation for the Dialog and AlertDialog.Builder classes.

Adding table layout to AlertDialog

I want to display an AlertDialog (button OK) with the content being a TableLayout.
However, I would like the TableLayout creation to be programatically, by Java, as I need to add rows depeding on some variables.
Any Idea how to do that?
Specifically:
1- Can an AlertDialog have TableLayout view, or does it only expect text so I should go with dialog?
2- How do I create TableLayout programmatically and add rows to it.
I have done it in xml but not sure in java
Help is appreciated
Thanks
Why don't you create a custom Dialog?
1 - You can instantiate a Dialog as in Dialog dialog = new Dialog(context, theme)
2 - Then you can make a dialog.setContentView(layout), find your tablelayout by id (dialog.findViewById)
3 - Then do what you need to do. I'd recommend putting this all in a separated method.
You should be able to set whatever layout you desire to the dialog using it 'setContentView' method.
You can inflate ui from an xml file. Like
LayoutInflater mInflater = LayoutInflater.from(context);
View yourView = mInflater.inflate(R.layout.your_layout, null);
alertDialog.setContentView(yourView);
The above code should work.

Categories

Resources