My android aplication crashes a second time I load a dialog - java

I have an adroid aplication that shows a Dialog that displays some data when you tap the respective item in the listview and works fine, but the second time I tap on another item, it crashes.
The list view calls an xml and inside I call a map fragment, that map fragment makes it crash, for some reason.
This is the itemlistdialog
<?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">
<fragment
android:layout_width="match_parent"
android:layout_height="285dp"
android:name="com.google.android.gms.maps.MapFragment"
android:id="#+id/map" />
</LinearLayout>
Here I call open the dialog everytime there is a tap in the list.
lista.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
LayoutInflater factory = LayoutInflater.from(this);
View listDialogView = factory.inflate(R.layout.itemlistdialog, null);
Dialog d = new AlertDialog.Builder(aux,AlertDialog.THEME_HOLO_LIGHT)
//HERE I ADD THE DATA THAT WILL BE DISPLAYED IN THE DIALOG
}
Edit:
This is the full error.
Error is too large to add here
http://prntscr.com/6gyng6

You have to dismiss the dialog every time.
For example:
You can try both, either
dialog.cancel();
or
dialog.dismiss();
in the both implementation of setPositiveButton and setNegativeButton.
AlertDialog.Builder builder1 = new AlertDialog.Builder(context);
builder1.setMessage("Write your message here.");
builder1.setCancelable(true);
builder1.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
builder1.setNegativeButton("No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert11 = builder1.create();
alert11.show();

Use MapView instead of MapFragment. MapFragment has some detatching problem, so when you open the dialog second time, it crashes because first MapFragment is still not detached.

Related

How to set ImageView in the AlterDialog Box

I am fetching the text and imageUrl from Firebase Realtime Database. I want to show the image and then display the text in the AlertDialogBox.
I am able to fetch the text and imageUrl. Able to set the text using setTitle() but when trying to display the image, not able to implement so.
Referred this but there in they are using drawable or static images.
Code
ImageView imageView = new ImageView(context);
imageView.setImageResource(R.mipmap.ic_launcher);
AlertDialog dialog = new AlertDialog.Builder(context)
.setView(imageView)
.setPositiveButton("ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).create();
dialog.show();
Or just the Text using below code
AlertDialog.Builder builder = new AlertDialog.Builder(context,R.style.CustomDialogTheme);
builder.setTitle("Explanation");
builder.setMessage(list.get(position).getExplaination());
url = list.get(position).getImageUrl();
Log.i("URL", url);
builder.setNegativeButton("Close", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
// dismiss dialog
dialogInterface.dismiss();
}
});
builder.show();
I have also created a CustomDialogBox view but not able to understand how should I pass the text and imageUrl value to that particular AlertDialogBox.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CustomDialog">
<ImageView
android:id="#+id/eImageView"
android:layout_width="300dp"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:layout_marginTop="30dp"
android:layout_marginRight="10dp"/>
<TextView
android:id="#+id/eTextView"
android:layout_width="150dp"
android:layout_height="300dp"
android:layout_margin="8dp"
android:gravity="center"
android:padding="20dp"
android:text=""
android:textColor="#000000"
android:translationX="120dp"
android:translationY="10dp"
android:textSize="20sp"
android:textStyle="bold" />
</LinearLayout>
To, set the image you need to get ImageView id from CustomDialog XML file and then you can set particular image into ImageView.
So, first of all, get your custom view using getLayoutInflater().
Note: use one of the following as per your requirement.
View view = getLayoutInflater().inflate(R.layout.CustomDialog, null); // for activity
View view = ((ViewHolder) holder).mainActivity.getLayoutInflater().inflate(R.layout.CustomDialog, null); // for adapter class
View view = getActivity().getLayoutInflater().inflate(R.layout.CustomDialog, null); // for fragment
Then, add view into builder.setView();
builder.setView(view);
However, you also need to get ID of the all views which is located into your CustomDialog XML file.
TextView textview = view.findViewById(R.id.eTextView);
ImageView imageview = view.findViewById(R.id.eImageView);
Now, you can set your Image into ImageView Using Glide dependency.
Glide.with(context).load(url).into(imageview);
Full example:
View view = getLayoutInflater().inflate(R.layout.CustomDialog, null);
ImageView imageview = view.findViewById(R.id.eImageView);
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Explanation");
builder.setView(view);
builder.setMessage(list.get(position).getExplaination());
url = list.get(position).getImageUrl();
Glide.with(context).load(url).into(imageview);
Log.i("URL", url);
builder.setNegativeButton("Close", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
// dismiss dialog
dialogInterface.dismiss();
}
});
builder.show();
you can't set URL directly into Imageview for that you have to use these library
Glide
Picasso
Glide Example :
Glide.with(context).load(your_url).into(imageview);
Picass Example :
Picasso.get().load(your_url).into(imageview);
You can user Dialog class. I'm writing the code below
Dialog dialog = new Dialog(context);
dialog.setCancelable(true);
ImageView imageView = dialog.findViewById(imageView);
TextView textView = dialog.findViewById(textView);
dialog.show();
dialog.getWindow().setBackgroundDrawable(new
ColorDrawable(context.getResources().getColor(android.R.color.transparent)));
I have also created a CustomDialogBox view but am not able to understand how should I pass the text and imageUrl value to that particular AlertDialogBox.
When you create a custom dialog class set a contractor with parameters for the text and image url. Use this text and imgUrl on your view. Use Picasso or Glide to load images from the online URL.
/*** On Activity class when you show your custom Dialog Box ****/
//Pass the text and img URL to your Custome Dialog constructor while create an instance
DialogFragment dialogBox= new CustomDialogBox(text, ImgUrl);
dialogBox.show(getSupportFragmentManager(), "custom_dialog_tag");
// Custom DialogBox Class
public class CustomDialogBox extends DialogFragment{
private String text;
private String imgUrl;
//Constructor to receive argument from Activity
public CustomDialogBox (String text, String imgUrl) {
this.text = text;
this.imgUrl= imgUrl;
}
#NonNull
#Override
public Dialog onCreateDialog(#Nullable Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the layout inflater
View view = getLayoutInflater().inflate(R.layout.custom_dialog, null); // for activity
// Inflate and set the layout for the dialog
builder.setView(view)
TextView textView = view.findViewById(R.id.yourTextView);
ImageView imgView= view.findViewById(R.id.yourImgView);
// View online img with glide library
Glide.with(context).load(imgUrl).into(imgView);
return builder.create();
}
}
To learn more about custom dialog - Official Documentation

Google Map flickers under alert dialog due to being compressed

I have implemented a dialog box on my marker info box click listener and the code logic is working fine, but when I show the dialog box the map is pushed up and flickers in the back ground. I tried it on a Pixel emulator as well as Galaxy S8 and both show the map as flickering behind the alert dialog box.
Here is the image and you can not really see it flickering but the text is distorted and flickering. It looks like its being compressed between the keyboard and top. The word ...calculating is on the bottom of the screen with no dialog so not sure why its at the top.
Any help would be appreciated. I did check for similar questions and what I think I am after is the keyboard simply overlaying the image not pushing it up.
googleMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
#Override
public void onInfoWindowClick(Marker marker) {
showEditTextDialog();
}
});
public void showEditTextDialog()
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
LayoutInflater layoutInflater = LayoutInflater.from(this);
final View dialogView = layoutInflater.inflate(R.layout.mymap_marker_alert_dialog, null);
final EditText editText = (EditText) dialogView.findViewById(R.id.alert_dialog_editText);
// Keyboard
final InputMethodManager imm = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
// Auto show keyboard
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean isFocused) {
if (isFocused)
{
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}
}
});
builder.setView(dialogView)
.setPositiveButton("Okay", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
String regNum = editText.getText().toString();
Log.d("STACKOVERFLOW", "Registration number: " + regNum);
// Hide keyboard
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// Hide keyboard
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
dialog.cancel();
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
SO it was the Adview that was trying to show in the compress screen area above the keyboard. I had to find a way to remove the adview while the keyboard was visible and then return it again on the keyboard was dismissed. In my case I had to ensure to re-enable the adview in the Alert Dialog onclick methods and the full solution is as follows:
Set up your LinearLayout and note the #id for both the LinearLayout and adView.
<TextView
android:id="#+id/mydistanceToMarker"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentStart="true"
android:gravity="fill"
android:text="Tap to change map type."
android:textAlignment="center"
android:textSize="36sp"
android:textColor="#color/colorBlack"
android:textStyle="bold" />
<com.google.android.gms.ads.AdView
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:id="#+id/myAdMapView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
ads:adUnitId="#string/UNIT_ID"
ads:adSize="BANNER"/>
</LinearLayout>
Connect the variable to the LinearLayout
private LinearLayout parentLinearLayout;
and
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_map);
parentLinearLayout = (LinearLayout) findViewById(R.id.mydistanceLayout);
NOTE: I have a few LinearLayout layers in my xml file so this #id is for the LinearLayout that just contains the adView that I need to remove and re-add when needed, NOT the top level LinearLayout.
In my progarm logic that is not included and irrelevant, I call the Alert Dialog method
public void showEditTextDialog()
{
parentLinearLayout.removeView((View) adMapView);
Here I remove the add at the start of the Alert Dialog and since I force the keyboard to show immediately and I need the ad not to be visible.
Now at the OK and Cancel responses in the Alert Dialog I add the view back.
builder.setView(dialogView).setPositiveButton("Okay", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
parentLinearLayout.addView((View) adMapView);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) { imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
dialog.cancel();
parentLinearLayout.addView((View) adMapView);
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
And this fixed the issue. Not sure if it was the best solution and happy to edit or fix the solution if there is a better way, but it solved my issue. Hope it helps someone in the same situation.

Deselect item in ListView

This is the scenario:
in a ListView i would like that the selected item remain selected until the user click on a DialogFragment button. The problem is that if the user click on back button, without any click in the DialogView, the item in the ListView remains selected.
I read this post , and the solutions work quite well: i click on a item, the dialog appears, i click the back button and the selector is gone.
But if i scroll the list, the selector comes back! Where am I wrong?
Here the code:
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/listView"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:layout_marginTop="15dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="15dp"
android:divider="#android:color/transparent"
android:visibility="visible"
android:dividerHeight="5dp"
android:choiceMode="singleChoice"
android:drawSelectorOnTop="true"
android:listSelector="#color/primario_1_alfa"/>
and the DialogFragment where i'm trying to deselect the listview element
public class MyDialog extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("Test dialog view")
.setPositiveButton("action 1", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
})
.setNegativeButton("action 2", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
return builder.create();
}
#Override
public void onDestroy(){
super.onDestroy();
ListView listView = (ListView) getActivity().findViewById(R.id.listView);
listView.clearChoices();
listView.requestLayout();
}
}
This is due to recycling of views using the ViewHolder pattern.
Since you only need a single select item at any moment, you can keep track of the position of the item that is selected in the Adapter and then check that position against the current position of the view to be populated with the ViewHolder data.
int selectedPosition;
...
onItemClickListener(int position, ...) {
selectedPosition = position;
}
...
getView(int position, ...) {
if (selectedPosition == position) {
view.setSelected(true);
} else {
view.setSelected(false);
}
}
Something along these lines.

How to create a custom alertDialog with a list inside bound to an onClick event android?

I guess I am going slightly mad... But I can't figure it out. I would like to show a custom alert dialog bound to an Onclick event with a list of data which come from a database.
All works perfectly if I use a simple Dialog, but I would like to make it custom in order to set a title, some text views and buttons on the top of the alert dialog (instead of just show a title with the .setTitle() method).
Here is my code:
protected void onPostExecute(String file_url) {
pDialog.dismiss();
runOnUiThread(new Runnable() {
#Override
public void run() {
infoListButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// custom Dialog
AlertDialog.Builder builder;
AlertDialog alertDialog;
Context mContext = getApplicationContext();
LayoutInflater inflater = (LayoutInflater)
mContext.getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.custom_dialog_institutionalinfos, null);
TextView text = (TextView) layout.findViewById(R.id.custom_dialog_text);
text.setText("Hello, this is a custom dialog!");
builder = new AlertDialog.Builder(mContext);
builder.setView(layout);
alertDialog = builder.create();
// inflating the custom institutional expandable list layout
LayoutInflater li = (LayoutInflater) thisContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = li.inflate(R.layout.institutional_info_custom_list, null, false);
alertDialog.setContentView(v);
InstitutionalInfoListView = (ListView) v.findViewById(android.R.id.list);
final MasterDetailArrayAdapter adapter = new MasterDetailArrayAdapter(HomeComune.this, MasterDetailInstitutionalInfoList);
InstitutionalInfoListView.setAdapter(adapter);
alertDialog.show();
}
});
}
});
}
the app crashes when I click on the infoListButton and I get A message in the LogCat:
03-16 19:25:22.905: E/AndroidRuntime(5301): FATAL EXCEPTION: main
03-16 19:25:22.905: E/AndroidRuntime(5301): android.util.AndroidRuntimeException:
requestFeature() must be called before adding content
and an error on the line where I call alertDialog.show(); method. Why this happens? How to resolve?
I just want to add a custom title, a button and a text view to my AlertDialog.
How to do that?
EDIT: how can I custom the title and add a button to the top-right of the dialog to bind it with an onclick event that will dismiss() the dialog???
EDIT: I have created a MyCustomDialog class with this code:
public class MyCustomDialog extends Dialog {
public MyCustomDialog(Context context) {
super(context);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.custom_dialog_institutionalinfos);
TextView dialogTitle = (TextView) findViewById(R.id.custom_dialog_text);
dialogTitle.setText("My First Custom Dialog");
}
}
And this XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="fill_parent" >
<TextView
android:id="#+id/custom_dialog_text"
android:layout_width="80dp"
android:layout_height="wrap_content"
/>
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="20dp"/>
</RelativeLayout>
The code where I instantiate the dialog:
// custom Dialog
MyCustomDialog dialog = new MyCustomDialog(thisContext);
// inflating the custom institutional expandable list layout
LayoutInflater li = (LayoutInflater) thisContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = li.inflate(R.layout.institutional_info_custom_list, null, false);
dialog.setContentView(v);
InstitutionalInfoListView = (ListView) v.findViewById(android.R.id.list);
final MasterDetailArrayAdapter adapter = new MasterDetailArrayAdapter(HomeComune.this, MasterDetailInstitutionalInfoList);
InstitutionalInfoListView.setAdapter(adapter);
dialog.show();
But there's no Text displayed in the dialog. I only see the list:
What am I missing?
UPDATE: MyCustomDialog class:
public class MyCustomDialog extends Dialog {
public MyCustomDialog(Context context) {
super(context);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.custom_title);
TextView dialogTitle = (TextView) findViewById(R.id.custom_dialog_text);
dialogTitle.setText("Hello I am a dialog");
}
}
The custom_title.xml:
<?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="40dp"
android:background="#3FD100"
android:orientation="vertical" >
<TextView
android:id="#+id/custom_dialog_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
The code where I instantiate MyCustomDialog class:
// custom Dialog
MyCustomDialog dialog = new MyCustomDialog(thisContext);
InstitutionalInfoListView = (ListView) dialog.findViewById(R.id.custom_dialog_list);
final MasterDetailArrayAdapter adapter = new
MasterDetailArrayAdapter(HomeComune.this, MasterDetailInstitutionalInfoList);
InstitutionalInfoListView.setAdapter(adapter);
dialog.show();
The app crashes with a null pointer exception at
InstitutionalInfoListView.setAdapter(adapter);
UPDATE: the TextView is inside the ListView, how to proceed?
Why do you use an AlertDialog? You can use a simple Dialog which generally causes less problems and is more appropriate for custom layouts.
EDIT: Details
First create an XML layout file, just like you would do for an Activity. Then create a class that extends Dialog. Say your custom dialog class is called CustomDialog. In public CustomDialog(Context context) call:
super(context);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.custom_dialog);
// find your views and customize them here
EDIT: HOW TO CREATE CUSTOM DIALOG INSTANCE
in your xml, also give the ListView a custom id: android:id="#+id/custom_dialog_list"
check the comments in the section below
// custom Dialog
MyCustomDialog dialog = new MyCustomDialog(thisContext);
// you DO NOT need to inflate a new view. by dialog.setContentView(v); you *replace* your XML file with another layout.
// inflating the custom institutional expandable list layout
//LayoutInflater li = (LayoutInflater) thisContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//View v = li.inflate(R.layout.institutional_info_custom_list, null, false);
//dialog.setContentView(v);
// dont forget to check this line
InstitutionalInfoListView = (ListView) dialog.findViewById(R.id.custom_dialog_list); // set a custom id for your list in the layout
final MasterDetailArrayAdapter adapter = new MasterDetailArrayAdapter(HomeComune.this, MasterDetailInstitutionalInfoList);
InstitutionalInfoListView.setAdapter(adapter);
dialog.show();

Android: put 2 buttons in custom dialog to appear in center

I have a custom dialog.
I want to put 2 buttons one near the other horizontally, to appear in center.
How can I achieve that?
Very similiar to Yes/No message box.
I am seeking a way to do it in layout xml file.
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:orientation="horizontal"
android:width="wrap_content"
android:height="wrap_content"
android:layout_centerHorizontal="true">
... And two buttons here
From Android Dev
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure you want to exit?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
MyActivity.this.finish();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
You may be looking for something similar to this. You can set the "Positive" and "Negative" button to say whatever you want and have each one do its own thing. In your case (and most cases) Yes and No would be perfect here!
Some examples of xml files can also be found by following that link as well as this one that I have used before.
Blog about custom dialogs. (Nice Example Code)
You can use an xml to define the layout of the content of the Dialog anyway you want, then you use an layoutInflater to set as a view in an AlertDialog:
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!");
ImageView image = (ImageView) layout.findViewById(R.id.image);
image.setImageResource(R.drawable.android);
builder = new AlertDialog.Builder(mContext);
builder.setView(layout);
alertDialog = builder.create();
Documentation source: http://developer.android.com/guide/topics/ui/dialogs.html#CustomDialog

Categories