Why does my bitmap image appears behind the alertdialog? - android

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

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

fullScreen ImageView close

this is my code:
final ImageView imageView1 = (ImageView) findViewById(R.id.imageView8);
imageView1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
imageView1.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT));
}
});
by this code when i click on my ImageView i can see it in fullScreen.
Now i have a question:
when I see imageView in fullscreen I want when I press Back, this imageView close and back to previous situation and my app doesn't back to previous activity
Rather then opening an image on full screen you can use a custom dialog to open that image which is called a Full Image Dialog, which works exactly as AlertDialog, for that you just need to design a custom layout including width and height of image you are opening. It is easy to maintain as on clicking anywhere on screen dialog automatically closes and your activity will resume.
If you want then I can give you more idea?
Step 1: Make a class FullImageDialog having this method:
public static void showImage(Context context, String strImagePath) {
AlertDialog.Builder imageDialog = new AlertDialog.Builder(context);
LayoutInflater inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.custom_fullimage_dialog, null);
ImageView image = (ImageView) layout.findViewById(R.id.fullImage);
Glide.with(context)
.load(strImagePath)
.placeholder(R.drawable.default_user_image)
.dontAnimate()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(image);
//image.setImageDrawable(tempImageView.getDrawable());
imageDialog.setView(layout);
final AlertDialog alert= imageDialog.create();
alert.getWindow().getAttributes().windowAnimations=R.style.FadeInTheme;
alert.show();
}
Step 2: create xml of full_image_dialog as:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/layout_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="#+id/fullImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:background="#drawable/default_user_image"
android:scaleType="fitXY" />
</LinearLayout>
step 3: call method where you need to open this dialog:
final ImageView imageView1 = (ImageView) findViewById(R.id.imageView8);
imageView1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//call FullImageDialog class by giving parameter of imageUrl
FullImageDialog.showImage(imageUrl);
}

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

Retrieving Value from EditText in DialogFragment

I'm going through Google's Android Developer page on Dialogs, specifically this section. However, instead of creating the DialogFragment's message programmatically, I made a pre-set layout named layout_newpayperiod.xml with the following elements:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Spinner
android:id="#+id/spinner_payperiod"
android:layout_width="fill_parent"
android:layout_height="48dp"
android:padding="8dp"
android:entries="#array/pay_periods"
/>
<EditText
android:id="#+id/edittext_savepercent"
android:layout_width="fill_parent"
android:layout_height="48dp"
android:padding="8dp"
android:inputType="number"
android:hint="Percent to Save"
/>
<EditText
android:id="#+id/edittext_payment"
android:layout_width="fill_parent"
android:layout_height="48dp"
android:padding="8dp"
android:inputType="numberDecimal"
android:hint="Total Payment"
/>
</LinearLayout>
When I call the DialogFragment it shows up as normal, with the Spinner having the proper values. I filled in the entries and hit "OK", but when I try to retrieve the values from the Spinner and two EditText fields, the app forces close with a NumberFormatException: Invalid double "". I get the feeling I'm not retrieving the Views properly. Can anyone help me figure this out please? Thanks!
public class StartPayperiodDialogFragment extends DialogFragment {
/* The activity that creates an instance of this dialog fragment must
* implement this interface in order to receive event callbacks.
* Each method passees the DialogFragment in case the host needs to query it.
*/
public interface StartPayperiodDialogListener{
public void onDialogPositiveClick(DialogFragment dialog);
public void onDialogNegativeClick(DialogFragment dialog);
}
// Use this instance of the interface to deliver action events
StartPayperiodDialogListener listener;
// Override the Fragment.onAttach() method to instantiate the StartPayperiodDialogListener
#Override
public void onAttach(Activity activity){
super.onAttach(activity);
// Verify that the host activity implements the callback interface
try{
// Instantiate the NoticeDialogListener so we can send events to the host
listener = (StartPayperiodDialogListener) activity;
}catch(ClassCastException e){
// The activity doesn't implement the interface, throw exception
throw new ClassCastException(activity.toString() + " must implement StartPayperiodDialogListener");
}
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState){
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
View transactionLayout = View.inflate(getActivity(), R.layout.layout_newpayperiod, null);
builder.setView(transactionLayout)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// Send the positive button event back to the calling activity
listener.onDialogPositiveClick(StartPayperiodDialogFragment.this);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// Send the negative button event back to the calling activity
listener.onDialogNegativeClick(StartPayperiodDialogFragment.this);
}
});
return builder.create();
}
}
In MainActivity.class, the callback method:
#Override
public void onDialogPositiveClick(DialogFragment dialog) {
// User pressed OK, so we need to grab the values from the
// dialog's fields and apply them to the Views in the Main
// Activity
View transactionLayout = View.inflate(this, R.layout.layout_newpayperiod, null);
// Start with the payment amount
EditText paymentEt = (EditText) transactionLayout.findViewById(R.id.edittext_payment);
TextView paymentTv = (TextView) findViewById(R.id.text_paycheck);
paymentTv.setText(moneyFormat.format(Double.parseDouble(paymentEt.getText().toString())));
// Next, the percent to save
EditText savingsEt = (EditText) transactionLayout.findViewById(R.id.edittext_savepercent);
TextView savingsTv = (TextView) findViewById(R.id.text_savings);
savingsTv.setText(savingsEt.getText().toString() + "%");
// Then, the pay period
Spinner periodSp = (Spinner) transactionLayout.findViewById(R.id.spinner_payperiod);
TextView periodTv = (TextView) findViewById(R.id.text_payperiod);
periodTv.setText(periodSp.getSelectedItem().toString());
// Finally, let's update the daily allowance amount and clear
// the adapter
adapter.clear();
adapter.notifyDataSetChanged();
TextView allowanceTv = (TextView) findViewById(R.id.text_allowance);
Double allowanceValue;
switch(periodSp.getSelectedItemPosition()){
case(0): // Daily
allowanceValue = Double.parseDouble(paymentTv.getText().toString());
break;
case(1): // Weekly
allowanceValue = Double.parseDouble(paymentTv.getText().toString()) / 7;
break;
case(2): // 2 Weeks
allowanceValue = Double.parseDouble(paymentTv.getText().toString()) / 14;
break;
case(3): // 30 Days
allowanceValue = Double.parseDouble(paymentTv.getText().toString()) / 30;
break;
default: // Debugging purposes only
allowanceValue = 42.0;
break;
}
allowanceTv.setText(Double.toString(allowanceValue));
}
Try this:
#Override
public void onDialogPositiveClick(DialogFragment dialog) {
// User pressed OK, so we need to grab the values from the
// dialog's fields and apply them to the Views in the Main
// Activity
// Start with the payment amount
Dialog dialogView = dialog.getDialog();
EditText paymentEt = (EditText) dialogView.findViewById(R.id.edittext_payment);
... etc. (Retrieve any other views from the dialog by querying the dialogView in the same way.)
Your inflate code "inflates" a brand new version of that view. You want to access the one that was created in the dialog.
I think that this line View transactionLayout = View.inflate(this, R.layout.layout_newpayperiod, null); messes everything. Maybe it's not messing, but you're getting address of freshly created layout and assign it to transactionLayout reference. Then you're getting Views from that layout EditText paymentEt = (EditText) transactionLayout.findViewById(R.id.edittext_payment); which are certainly uninitialisted. It has value empty string value -> "";
I think you should use findViewById to get reference to your EditText's as you do with your TextView's. But as you are in your MainActivity which layout is probably not a parent view to your R.layout.layout_newpayperiod, you must find a way to do that properly.
You've got your DialogFragment as parameter in this onDialogPositiveClickcallback method. So you can obtain it's View and the layout you're looking for - that contains your EditText's
Sorry for editing this post so many times.

how can I make such dialog in android?

I would like to implement dialog such this one
User hits the button "Icon", this dialog opens, user chooses appropriate icon by pressing on it, then dialog closes and returns to me id of this icon.
How could I do it?
Thanks.
You want to create an alertDialog with a custom grid in it. In my answer I assume that OP wanted to know how to create such a dialog in general. Therefore I am using a normal style. If you want to use a dark style, create a custom styling and use it in your AlertDialog.Builder:
AlertDialog.Builder builder = new AlertDialog.Builder(context, <YourCustomStyle>);
Result:
Create the layout for a single entry. Since OP is only showing icons, I only use an ImageView. If the icon should for example have text under it, you simply could create a TextView below it and fill it with your text.
view_icon_chooser_entry.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/image_choose_icon_entry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:contentDescription="#null"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>
Create an adapter that can deal with the data and create the layout. In my example I am extending from a BaseAdapter since this is quite easy to do. A little bit more modern would be to use a RecyclerView and create your own custom adapter for it.
AlertDialogImageAdapter.java:
public class AlertDialogImageAdapter extends BaseAdapter {
private LayoutInflater layoutInflater;
AlertDialogImageAdapter(Context context) {
layoutInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return iconList.length;
}
#Override
public Object getItem(int position) {
return iconList[position];
}
#Override
public long getItemId(int position) {
return position;
}
#SuppressLint("InflateParams")
#NonNull
public View getView(int position, View convertView, #NonNull ViewGroup parent) {
AlertDialogViewHolder alertDialogViewHolder;
if (convertView == null) {
// This is an alertDialog, therefore it has no root
convertView = layoutInflater.inflate(R.layout.view_icon_chooser_entry, null);
DisplayMetrics metrics = convertView.getResources().getDisplayMetrics();
int screenWidth = metrics.widthPixels;
convertView.setLayoutParams(new GridView.LayoutParams(screenWidth / 6, screenWidth / 6));
alertDialogViewHolder = new AlertDialogViewHolder();
alertDialogViewHolder.icon = convertView.findViewById(R.id.image_choose_icon_entry);
convertView.setTag(alertDialogViewHolder);
} else {
alertDialogViewHolder = (AlertDialogViewHolder) convertView.getTag();
}
alertDialogViewHolder.icon.setAdjustViewBounds(true);
alertDialogViewHolder.icon.setScaleType(ImageView.ScaleType.CENTER_CROP);
alertDialogViewHolder.icon.setPadding(8, 8, 8, 8);
alertDialogViewHolder.icon.setImageResource(iconList[position]);
return convertView;
}
// This is your source for your icons, fill it with your own
private Integer[] iconList = {
android.R.drawable.ic_media_play, android.R.drawable.ic_media_pause,
android.R.drawable.ic_delete, android.R.drawable.ic_btn_speak_now,
android.R.drawable.ic_media_previous, android.R.drawable.ic_media_next,
android.R.drawable.ic_menu_my_calendar, android.R.drawable.ic_menu_agenda,
android.R.drawable.ic_media_play, android.R.drawable.ic_media_pause,
android.R.drawable.ic_delete, android.R.drawable.ic_btn_speak_now,
android.R.drawable.ic_media_previous, android.R.drawable.ic_media_next,
android.R.drawable.ic_menu_my_calendar, android.R.drawable.ic_menu_agenda,
android.R.drawable.ic_media_play, android.R.drawable.ic_media_pause,
android.R.drawable.ic_delete, android.R.drawable.ic_btn_speak_now,
android.R.drawable.ic_media_previous, android.R.drawable.ic_media_next,
android.R.drawable.ic_menu_my_calendar, android.R.drawable.ic_menu_agenda
};
private class AlertDialogViewHolder {
ImageView icon;
}
}
Then, place a method to create a new AlertDialog with your custom AlertDialogImageAdapterand use a grid for the layout. You can change how many columns you have with setNumColumns(4).
Put this method where you want to show the alert dialog and simply call it:
private void showAlertDialog(Context context) {
GridView gridView = new GridView(context);
gridView.setAdapter(new AlertDialogImageAdapter(context));
gridView.setNumColumns(4);
gridView.setGravity(Gravity.CENTER);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// TODO: Implement
Toast.makeText(view.getContext(), "Clicked position is: " + position, Toast.LENGTH_LONG).show();
}
});
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setView(gridView);
builder.setTitle(R.string.title_chose_icon);
builder.show();
}
I will suggest you to "imitate" the dialog and not using the android one.
For that, you can create a second layout with the dark grey background and all your clickable icons inside. When you will call the dialog, set the dimming to the main layout and put the one with the icons on the top.
I am using this in my app. I will provide you some code in 10min.
Have a look at the fragments section in the API Demo app. There are some dialogs you can use

Categories

Resources