How to fix "Avoid passing null as the view root" in android? - android

In my android app, I create a dialog like this:
private void handleEdit() {
LayoutInflater inflater = getLayoutInflater();
View dialoglayout = inflater.inflate(R.layout.dialog_gallery, null);
final AlertDialog d = new AlertDialog.Builder(this)
.setView(dialoglayout)
.setTitle(R.string.edit)
.setNegativeButton(R.string.cancel, null)
.create();
CheckBox mainCB = (CheckBox)dialoglayout.findViewById(R.id.main);
CheckBox usedCB = (CheckBox)dialoglayout.findViewById(R.id.used);
mainCB.setChecked(image.getIsMain());
usedCB.setChecked(image.getApproved());
mainCB.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
if (Network.isNetworkAvailable(GalleryScreen.this)) {
new Async_update_image_state(GalleryScreen.this, fish, image, !image.getIsMain(), image.getApproved(), false);
d.dismiss();
} else {
Popup.ShowErrorMessage(GalleryScreen.this, R.string.no_internet, false);
}
}
});
usedCB.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
if (Network.isNetworkAvailable(GalleryScreen.this)) {
new Async_update_image_state(GalleryScreen.this, fish, image, false, !image.getApproved(), true);
d.dismiss();
} else {
Popup.ShowErrorMessage(GalleryScreen.this, R.string.no_internet, false);
}
}
});
d.show();
}
But I get a warning on View dialoglayout = inflater.inflate(R.layout.dialog_gallery, null); underlining the null.
Avoid passing null as the view root (needed to resolve layout parameters on the inflated layout's root element)
What does this mean and how can I fix it?
Thanks.

this works for me
View.inflate(getActivity(), R.layout.dialog, null);
without any warnings nor errors.

When inflating a layout for use in a dialog, You can safely pass null here and ignore the warning.
From This Link
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.

Instead of :
inflater.inflate(R.layout.dialog_gallery, null);
do:
inflater.inflate(R.layout.dialog_gallery, parent, false);
Using a #SuppressLint annotation as suggested by Eugen in the comment above might "suppress" the warning, but it doesn't solve the problem.Using null as an argument for the ViewGroup will cause you problems in the future.

Instead of
inflater.inflate(R.layout.dialog_gallery, null);
try
inflater.inflate(R.layout.dialog_gallery, null, false);
It will not attach view to the parent that is null in your case.
See details on Android Reference

Related

Changing Dialog Image from Within Adapter?

So I have a ListView with list-items that each have different images in them. I have my code setup so that when the user clicks an image, it will show an expanded version of that particular image by using the Dialog class.
However, no matter what code I've tried, it doesn't seem like I can make the Dialog image change! Am I not able to modify layout elements from within an adapter? I could only figure out how to reference my individual list-item images by putting the relevant code within my adapter.
What needs to change, and what am I doing wrong?
Here's the applicable code in my adapter for reference:
viewHolder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i(LOG_TAG, "Calling ImageView OnClickListener");
int imageId = currentWord.getImageResourceId();
Dialog aD = new Dialog(mContext);
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
View popupLayout = layoutInflater.inflate(R.layout.popup_image_layout, null);
ImageView popupImageView = (ImageView) popupLayout.findViewById(R.id.popup_imageView);
Glide
.with(mContext)
.load(imageId)
.apply(new RequestOptions().circleCrop())
.into(popupImageView);
aD.setContentView(R.layout.popup_image_layout);
aD.show();
}
});
Thanks for any of your help!
So I ended up figuring the answer out on my own.
Under aD.setContentView(), I should have had popupLayout as the target, which had already had R.layout.popup_image_layout assigned and inflated in the same line... By referencing the layout anew, the code wasn't actually inflating the layout, so there was nothing able to be shown.
So all that needed to be changed was: modifying aD.setContentView(R.layout.popup_image_layout) to aD.setContentView(popupLayout) and now when I click on the individual images in my ListView items, the proper image for each pops up in an expanded ImageView, which is shown by way of the Dialog class.
UPDATE:
Added some extra code in order to make sure that the Dialog is completely removed after being closed. Otherwise, it is kept in memory and the memory use continues to stack and increase indefinitely upon each subsequent Dialog being opened.
Updated code below:
Dialog aD = null;
final int imageId = currentWord.getImageResourceId();
final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
viewHolder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
View popupLayout = layoutInflater.inflate(R.layout.popup_image_layout, null);
final ImageView popupImageView = (ImageView) popupLayout.findViewById(R.id.popup_imageView);
if (aD == null) {
aD = new Dialog(mContext);
aD.getWindow().setBackgroundDrawableResource(R.color.transparent);
}
Log.i(LOG_TAG, "Calling ImageView OnClickListener");
Glide
.with(mContext)
.load(imageId)
.apply(new RequestOptions().circleCrop())
.into(popupImageView);
aD.setContentView(popupLayout);
aD.show();
popupLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
aD.dismiss();
aD = null;
}
});
}
});

Target must be not null (Load an ImageView with Picasso on Dialog)

i have a problem which the log cat said target must be no null
i want to show an image in a Dialog by onclick button with Picasso Loader.
this my code
viewsim.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(DetailBookingAdmin.this, ""+pathSIM, Toast.LENGTH_SHORT).show();
final Dialog dialog = new Dialog(DetailBookingAdmin.this);
dialog.setContentView(R.layout.view_sim);
dialog.setTitle("SIM");
final ImageView imgsim = (ImageView)v.findViewById(R.id.img_sim);
Picasso.with(v.getContext()).load(pathSIM).into(imgsim);
dialog.show();
}
});
Log cat said in line Picasso.with(v.getContext()).load(pathSIM).into(imgsim); target must be not null. Please help me, thanks in advance.
use layout inflater.
LayoutInflater inflater = getLayoutInflater();
View newView = (View) inflater.inflate(R.layout.view_sim, null);
dialog.setContentView(newView);
final ImageView imgsim = (ImageView)newView.findViewById(R.id.img_sim);
...

Check if view element is added to layout or not programmatically

In my fragment class, I add a child view element programmatically to my layout conditionally :
LinearLayout child = (LinearLayout) inflater.inflate(R.layout.child_view, null);
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,100);
container.addView(child, params);
Since the above code will be run conditionally, so, at some point, I would like to check if the child view has added or not, how to make this checking programmatically?
If you creating view via inflater, you can check his parent
if(view.getParent() != null) {...}
I think you can simply use
findViewById(your_view_id)
method: If its result is null the view does not exists, otherwise the view is present
Sorry for late reply but you may try this alternative:
use container.getChildCount(); before adding and after adding a view. Like :
int x = container.getChildCount();
container.addView(child, params);
int y = container.getChildCount();
if(y > x)
Toast.makeText(context, "View Successfully Added!", Toas.LENGTH_SHORT).show();
Or if you have a view instance to find, you could:
if (container.indexOfChild(childView) == -1) {
// Add child to container.
}
With AndroidX you can use ViewGroup.contains(view: View): Boolean extension function.
I cannot write a comment so I write it here as a solution:
From API level 19 you can call isAttachedToWindow() which doesn't help a lot, but if you are aiming API 19 or higher, then this should work by the documentation.
maybe you can try this
child.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
child.getViewTreeObserver().removeOnGlobalLayoutListener(this);
// add to parent
}
});
or this one
child.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
#Override
public void onViewAttachedToWindow(View v) {
}
#Override
public void onViewDetachedFromWindow(View v) {
}
});

How make a layout available to a dialog

In my activity there are 3 buttons. By clicking on the first button, I want a dialog to appear with a graph (in the layout itself it works fine).
btn1 = (Button)findViewById(R.id.btn1);
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog = new Dialog(ChartsDuration.this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog_charts1);
// code to show a graph. Here I have a function that calls drawChartAll(),
// but since the layout is declared outside the dialog it cannot render it to the
// linearlayout, and my graph1 linearlayout will be empty.
dialog.show();
}
});
Tha graph uses data that are queried in functions outside like
public void drawChartAll()
{
//blablabla and this is how I define the layout and render the graph to it:
LinearLayout layout = (LinearLayout) findViewById(R.id.graph1);
mChartView = ChartFactory.getBarChartView(ChartsDuration.this, buildBarDataset(titles, values),renderer,Type.DEFAULT);
mChartView.setBackgroundColor(renderer.getBackgroundColor());
layout.addView(mChartView);
}
So without the dialog, I can easily show the graph in the graph1 LinearLayout e.g below the buttons, because they are "on the same levels", but I want to show the graph in a dialog opened by clicking on a button. Because if I were in a dialog I would do this: LinearLayout layout = (LinearLayout)dialog.findViewById(R.id.graph1); But now I cannot do this, since I am outside the dialog.
How do I reach this layout?
Edit:
user113215 I did this:
in the activity:
LayoutInflater inflater = LayoutInflater.from(ChartsDuration.this);
customDialog = (ViewGroup) inflater.inflate(R.layout.dialog_charts1, null);
btn1 = (Button)findViewById(R.id.btn1);
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.setContentView(customDialog);
//queries
dialog.show();
}
});
and in drawChartAll:
public void drawChartAll()
{
//code
LinearLayout layout = (LinearLayout) customDialog.findViewById(R.id.graph1);
}
Is this what you mean? This throws me a nullpointer exception to dialog.setContentView(customDialog); line.
If I understand the problem correctly, you're having trouble manipulating things on the layout that's going into the dialog. Instead of calling setContentView(int), inflate the layout yourself and then use setContentView(View).
LayoutInflater inflater = LayoutInflater.from(this);
ViewGroup customDialog = (ViewGroup) inflater.inflate(R.layout.dialog_charts1, null);
// Do chart things here
// Prefix all calls to findViewById with "customDialog."
LinearLayout layout = (LinearLayout) customDialog.findViewById(R.id.graph1);
mChartView = ChartFactory.getBarChartView(ChartsDuration.this, buildBarDataset(titles, values),renderer,Type.DEFAULT);
mChartView.setBackgroundColor(renderer.getBackgroundColor());
layout.addView(mChartView);
// Put the manipulated layout into the dialog
dialog.setContentView(customDialog);
You can use this same trick to take advantage of the AlertDialog.Builder class while still filling the dialog with a custom layout.
Make the dialogvariable a field in your Activity class. You can reach it from anywhere. You can still use dialog.findviewbyid throughout you Activity. Just make sure setcontentView has been called before you call findviewbyid
Edit: I hope when you wrote since I am outside the dialog. you meant you could not access the variable

How to add a clear button in a popup window

I am new to android development. I have created a popup window which is being called on a button click from the main activity class. I have some Edit text field on my pop window. can i clear all these edit text field on the pop up window through a button click? if yes then how? Thanks in advance!!
Below is what i am trying but it is giving null point exception.
public void initatePopupWindow(View view)
{
try
{
LayoutInflater inflater=(LayoutInflater) ContactdetailsActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout=inflater.inflate(R.layout.popupwindow,(ViewGroup)findViewById(R.id.popuplayout));
pw = new PopupWindow(layout, 500, 500, true);
pw.showAtLocation(layout, Gravity.CENTER, 0, 0);
Button b1=(Button)layout.findViewById(R.id.cancel);
b1.setOnClickListener(cancel_button_click_listener);
Button b2=(Button)layout.findViewById(R.id.clear);
b2.setOnClickListener(clear_fields);
}
catch (Exception e)
{
}
}
private OnClickListener clear_fields= new OnClickListener()
{
public void onClick(View v)
{
ViewGroup group= (ViewGroup)findViewById(R.id.popuplayout);
for(int i=0,count=getChildCount(); i<count; ++i)
{
View v1= group.getChildAt(i);
if(v1 instanceof EditText)
{
((EditText)v1).setText("");
}
if(v1 instanceof ViewGroup && (((ViewGroup)v1).getChildCount() > 0))
onClick((ViewGroup)v1);
}
}
};
private OnClickListener cancel_button_click_listener=new OnClickListener()
{
public void onClick(View v)
{
pw.dismiss();
}
};
}
Are you getting your errors on this line?
ViewGroup group= (ViewGroup)findViewById(R.id.popuplayout);
ViewGroup group= (ViewGroup) layout.findViewById(R.id.popuplayout);//layout is your inflated
I think it might be beacuse you need to use the value you called on the layout inflator.
Anyway, I guess you should do instead: Get a reference of all your edit texts and then clear them one by one. Maybe keep an array of edit texts and walk through them and set their texts to "" instead of checking for the type.

Categories

Resources