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

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);
...

Related

Why does my bitmap image appears behind the alertdialog?

Code:
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
image_person = (ImageView) findViewById(R.id.dialog_imageview);
}
public void checkBox_checker(String checkerID, String checkerName, String checkerSurname, String
checkerDescription, Blob picture) throws SQLException
{
int blobLength = (int) picture.length();
byte[] bytes = picture.getBytes(1,blobLength);
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
Log.d(TAG, "Checker box");
LayoutInflater factory = LayoutInflater.from(MainActivity.this);
final View alertDialog= factory.inflate(R.layout.sample, null);
image_person.setImageBitmap(bitmap);
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setCancelable(true);
builder.setView(alertDialog);
builder.setTitle("Information");
builder.setMessage(message);
builder.setNegativeButton("Report", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
builder.setPositiveButton("Enter", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
builder.show();
}
Sample.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<ImageView
android:id="#+id/dialog_imageview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
My problem is that the image is inserted behind the alert dialog and not inside the alert dialog. Can someone help me as to why this is happening?
I have entered the image in the xml file and it does get displayed in the alert dialog. So not too sure why this is happening.
It looks like you have a separate ImageView called dialog_imageview inside the layout activity_main. Otherwise, the activity wouldn't be able to find a View here:
image_person = (ImageView) findViewById(R.id.dialog_imageview);
which then would cause a Null Pointer Exception a few lines below:
image_person.setImageBitmap(bitmap);
To fix all of this, delete the dialog_imageview from activity_main XML layout.
Then, find the correct ImageView in your inflated sample layout rather than in the activity by calling findViewById on it:
final View alertDialog = factory.inflate(R.layout.sample, null);
image_person = (ImageView) alertDialog.findViewById(R.id.dialog_imageview);
image_person.setImageBitmap(bitmap);
You cannot do a "findViewById()" before have Inflated its Layout...
I think you have a "dialog_imageview" in your MainActivity's Layout and then the Image is updated in the wrong ImageView.
You just have to move "image_person = (ImageView)alertDialog.findViewById(R.id.dialog_imageview);" after the "factory.inflate(R.layout.sample, null);" row.
Firstly as Hoffman pointed out correctly, I did duplicate the ImageView in the activty_man.xml.
However, the problem still persisted.
After much investigations, I realized I missed a single line of code,
Before:
image_person = (ImageView) findViewById(R.id.dialog_imageview);
After/Correction:
image_person = (ImageView) alertDialog.findViewById(R.id.dialog_imageview);

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;
}
});
}
});

How to fix "Avoid passing null as the view root" in 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

setOnClickListener for a button inside onOptionsItemSelected causing app crash

I am invoking from a menu Item a Dialog and I have a Button inside that Dialog and trying to do something when I press the button. The part of my code for this is as followed:
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.itTip:
final Dialog tipCalculator = new Dialog(this);
tipCalculator.setTitle("Tip Calculator");
tipCalculator.setContentView(R.layout.tip_layout);
totalBill = (EditText) findViewById(R.id.editTBill);
tips = (EditText) findViewById(R.id.editTTip);
calculate = (Button) findViewById(R.id.bCalcTip);
tvResult = (TextView) findViewById(R.id.tvTipResult);
calculate.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "Calculate clicked", Toast.LENGTH_SHORT).show();
}
});
tipCalculator.setCancelable(true);
tipCalculator.show();
break;
}
return super.onOptionsItemSelected(item);
}
When I run my app, without the setOnClickListener, it works fine and shows the Dialog perfectly. But whenever I am trying to use the Listener, it crashes. I checked in LogCat and could actually not understand the problem clearly. Hope anyone can help me here.
I think the problem is because you attempt to find the view before you have actually shown it, this causes 'calculate' to be null when attempting to assign a onClickListener, and thus throws a null pointer exception.
To explain in a bit more detail, findViewById searches all the views currently being displayed and returns the view that matches that id. The button is contained in R.layout.tip_layout, but that view is not inflated until tipCalculator.show() is called and it won't be included in the list of views searched, so findViewById returns null.
There are a few approaches you could take to make this work, but I think the following would require the least alterations to your original code:
case R.id.itTip:
final Dialog tipCalculator = new Dialog(this);
tipCalculator.setTitle("Tip Calculator");
View contentView = View.inflate(this, R.layout.tip_layout, null);
totalBill = (EditText) contentView.findViewById(R.id.editTBill);
tips = (EditText) contentView.findViewById(R.id.editTTip);
calculate = (Button) contentView.findViewById(R.id.bCalcTip);
tvResult = (TextView) contentView.findViewById(R.id.tvTipResult);
calculate.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "Calculate clicked", Toast.LENGTH_SHORT).show();
}
});
tipCalculator.setContentView(contentView);
tipCalculator.setCancelable(true);
tipCalculator.show();
break;
What we do different is inflate the view in advance (contentView) and define where to find each widget by searching that view specifically.

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

Categories

Resources