I've created a multi purpose AlertDialog with one WebView in it. In all the devices that I've tested the dialog size is ok, that it, the height is always wrapping to the content. Unfortunately, on a Nexus 5 with 4.4.2 it's not showing properly. Sometimes it wraps, other don't.
Here is a screenshot of what I mean on a emulated Nexus 5.
Here is the xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/white"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/white"
android:orientation="horizontal"
tools:ignore="DisableBaselineAlignment"
android:id="#+id/alertdialog_title"
android:weightSum="4">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal"
android:layout_weight="1"
android:gravity="center">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="#string/app_name"
android:fitsSystemWindows="true"
android:id="#+id/alertdialog_icon"
android:layout_margin="12dp"
android:layout_gravity="center"
android:background="#drawable/info"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="3"
android:gravity="center"
android:orientation="horizontal"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:textColor="#color/white"
android:textStyle="bold"
tools:ignore="HardcodedText"
android:layout_gravity="center"
android:id="#+id/alertdialog_titletext"
android:layout_marginTop="12dp"
android:layout_marginRight="12dp"
android:layout_marginBottom="12dp"
android:textAppearance="#android:style/TextAppearance.DeviceDefault.Large"
style="#android:style/TextAppearance.Large"/>
</LinearLayout>
</LinearLayout>
<View
android:id="#+id/linearLayout1"
android:layout_width="fill_parent"
android:layout_height="2dp"
android:background="#color/orange"
android:orientation="vertical"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical"
tools:ignore="DisableBaselineAlignment"
android:id="#+id/alertdialog_content">
</LinearLayout>
</LinearLayout>
And the code for creating the AlertDialog
void showAlertDialog(String title, String message, final int messageType) {
int padding = (int) getResources().getDimension(R.dimen.all_margins);
LayoutInflater inflater = getLayoutInflater();
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
View layout = inflater.inflate(R.layout.alertdialog, null);
LinearLayout alertDialogContent = (LinearLayout) layout.findViewById(R.id.alertdialog_content);
ImageView alertDialogIcon = (ImageView) layout.findViewById(R.id.alertdialog_icon);
TextView alertDialogTitle = (TextView) layout.findViewById(R.id.alertdialog_titletext);
alertDialogTitle.setTypeface(fontBold);
alertDialogIcon.setBackgroundDrawable(getResources().getDrawable(R.drawable.info));
alertDialogTitle.setText(title);
alertDialogTitle.setTextColor(getResources().getColor(R.color.orange));
WebView webview = new WebView(this);
ScrollView scrollPane = new ScrollView(this);
webview.loadDataWithBaseURL(null, message, "text/html", "utf-8", null);
scrollPane.setPadding(padding, padding, padding, padding);
scrollPane.addView(webview);
alertDialogContent.addView(scrollPane);
alertDialog.setView(layout);
alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Do something
}
});
if (messageType == 0 || messageType == 3) {
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Do something
}
});
}
AlertDialog alert = alertDialog.create();
alert.show();
boolean tabletSize = getResources().getBoolean(R.bool.isTablet);
if (tabletSize) {
DisplayMetrics metrics = getResources().getDisplayMetrics();
alert.getWindow().setLayout((int) (metrics.widthPixels * 0.8), ViewGroup.LayoutParams.WRAP_CONTENT);
}
}
What should I change to the AlertDialog always wraps it's content??
It is the ScrollView default behaviour to get all the available space (that's my direct experience). I came across this issue some days ago, My solution was to measure the content of the ScrollView, and forcing its height. Something like (my situation was a LinearLayout as direct child of theScrollViewthat containsTextView`s - pseudo-code)
int height = 0;
for (view I am going to add in the LL) {
view.measure(0, 0);
height += view.getMeasuredHeight();
}
after this measure operation, I retrieve the root layout of the view hierarchy (FrameLayout in my case), and I forced its params.height to the calculated
Related
I had problems with this when I was programming it. I thought I'd cured it by specifying a fixed percentage height for the body of the dialog. I thought this was bad form, because the user might have a slim display, or set large fonts, which would cut of the EditText box.
Anyway that solution has failed beyond the emulator.
It looks like Android is assigning a fixed height to a dialog, and if my custom title has devoured too much of this height, squeezing everything else off. Is this correct and how do I fix it?
Problem
public class GetUserNameDialogFragment extends DialogFragment {
final String TAG = "GetUserNameDialog";
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.MyAlertDialogStyle);
//TODO getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
LayoutInflater inflater = getActivity().getLayoutInflater();
final View sunburst =inflater.inflate(R.layout.dialog_user_name, null);
builder.setView(sunburst);
builder.setCancelable(false)
.setPositiveButton("Let's go!", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Log.wtf(TAG, "button press");
EditText name = (EditText) sunburst.findViewById(R.id.nameEditText);
String userName = name.getText().toString().trim();
//TODO needs to be validated
SharedPreferences sharedPref = getActivity().getSharedPreferences("userDetails", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString("userName", userName );
editor.commit();
}
});
// Create the AlertDialog object and return it
return builder.create();
}
}
Here's the xml
<?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"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:adjustViewBounds="true"
app:srcCompat="#drawable/ic_ball_sunburst_classic"
android:background="#color/colorAccent"
/>
<LinearLayout
android:layout_width="250dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:layout_height="125dp">
<EditText
android:id="#+id/nameEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:hint="Enter your first name"/>
</LinearLayout>
</LinearLayout>
All help very much appreciated, the first impression of my app - what a disaster!
Why don't you use Dialog instead of AlertDialog ?
I built the example using a Dialog and it works perfectly
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_gravity="center_horizontal"
android:layout_width=" 290dp"
android:layout_height="wrap_content"
android:background="#4CAF50">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:adjustViewBounds="true"
android:src="#drawable/base"
android:background="#color/colorAccent"
/>
<EditText
android:textColor="#fff"
android:textColorHint="#fff"
android:layout_marginTop="10dp"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp"
android:id="#+id/nameEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter your first name"/>
<Button
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp"
android:id="#+id/letsGo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="Let's Go"
android:textColor="#fff"
android:background="#android:color/transparent"/>
final Dialog dialog = new Dialog(context);
if(dialog.getWindow() != null){
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
dialog.setContentView(R.layout.dialog);
Button letsGO = (Button) dialog.findViewById(R.id.letsGo);
EditText nameEditText = (EditText) dialog.findViewById(R.id.nameEditText);
letsGO.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "Lets GO!", Toast.LENGTH_SHORT).show();
dialog.dismiss();
}
});
dialog.show();
I have a question. I made an alert dialog that is showing an message and view with a "do not show again" check-box. When i'm running this app on android KK it is displaying fine, however when I run it on android JB it is showing me a blank space like on this image(i also get this blank space when the view contains only a linear layout with a height of 0dp):
http://foto.modelbouwforum.nl/images/2014/08/15/Screenshot2014-08-15-14-33-40.png
My code of the alert dialog:
final SharedPreferences sharedPreferences=getSharedPreferences("appPrefs", Context.MODE_PRIVATE);
if(!sharedPreferences.getBoolean("isTutorialMainScreenChecked", false)){
View checkBoxView = View.inflate(MainScreenHandler.this, R.layout.checkbox_alert_dialog,null);
checkBox = (CheckBox) checkBoxView.findViewById(R.id.checkbox);
AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder.setMessage(getString(R.string.alertDialog_main_screen_tutorial));
builder.setCancelable(false);
builder.setView(checkBoxView);
builder.setPositiveButton("Ok",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
if(checkBox.isChecked()){
SharedPreferences.Editor editor=sharedPreferences.edit();
editor.putBoolean("isTutorialMainScreenChecked", true);
editor.commit();
}
dialogInterface.dismiss();
}
});
builder.setNegativeButton(getString(R.string.alertDialog_cancel),
new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialogInterface, int i){
dialogInterface.cancel();
}
});
alertDialog = builder.create();
alertDialog.show();
And here is my checkbox layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:baselineAligned="false">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#ffff3bb2"/>
<CheckBox
style="#android:style/TextAppearance.Small"
android:textColor="#ff000000"
android:text="#string/alertDialog_checkbox_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/checkbox"/>
</LinearLayout>
Thanks in advance
P.s:
This is how it looks on android KK:
http://foto.modelbouwforum.nl/images/2014/08/15/QuickMemo2014-08-15-14-42-41.png
I looked through sources of alert_dialog.xml layout in API 19 and found the following layout for inserting a custom view:
<FrameLayout android:id="#+id/customPanel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
<FrameLayout android:id="#+android:id/custom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="5dip"
android:paddingBottom="5dip" />
</FrameLayout>
Then I tried to set background to see which view takes the space. customPanel was colored in red, custom view was colored in green.
AlertDialog d = builder.create();
d.show();
View v = (View)d.getWindow().findViewById(android.R.id.custom).getParent();
v.setBackgroundColor(Color.RED);
This picture means that customPanel should have some paddings, or custom should have non-zero layout params or something else. After checking those attributes which were equal to zero I tried to test minimumHeight of the customPanel and got 192 on xxhdpi or 64dp. This setting cause the frame to be larger than a nested custom view.
I haven't figured out where this setting is applied, but here is the workaround:
AlertDialog d = builder.create();
d.show();
View v = (View)d.getWindow().findViewById(android.R.id.custom).getParent();
v.setMinimumHeight(0);
Tested on API 18,19.
In addition to vokilam's answer:
If you're using android.support.v7.app.AlertDialog.
Tested on API 27 (pretty sure this works on API 28 too)
The layout:
<FrameLayout
android:id="#+id/contentPanel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="48dp">
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Space
android:id="#+id/textSpacerNoTitle"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="#dimen/dialog_padding_top_material" />
<TextView
android:id="#+id/message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingEnd="?attr/dialogPreferredPadding"
android:paddingStart="?attr/dialogPreferredPadding"
style="#style/TextAppearance.Material.Subhead" />
<Space
android:id="#+id/textSpacerNoButtons"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="#dimen/dialog_padding_top_material" />
</LinearLayout>
</ScrollView>
</FrameLayout>
<FrameLayout
android:id="#+id/customPanel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="48dp">
<FrameLayout
android:id="#+id/custom"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</FrameLayout>
The android:minHeight="48dp" for contentPanel and customPanel are causing the unwanted blank space.
Unwanted space dialog
What I did is:
alertDialog.SetView(view);
alertDialog.show();
...
View customPanel = (View) view.getParent().getParent();
if (customPanel != null)
customPanel.setMinimumHeight(0);
View contentPanel = (View) alertDialog.findViewById(android.R.id.message).getParent().getParent().getParent();
if (contentPanel != null)
contentPanel.setMinimumHeight(contentPanel.getMinimumHeight() * 2 / 3);
Result:
Blank space removed
Did you try playing around with paddings and margins?
You could copy your layout in res/layout-vXX and set a specific (negative) margin.
I'm building a simple AlertDialog with custom layout from XML. Here is how it's supposed to look (taken from Eclipse): It's simply 4 columns:
Here is the xml of the image above:
<?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="horizontal"
android:weightSum="1.0" >
<ImageView
android:id="#+id/colorpicker_dialog_color1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.25"
android:background="#FFF"
android:tag="0xFFF" />
<ImageView
android:id="#+id/colorpicker_dialog_color2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.25"
android:background="#FFDD66"
android:tag="0xFFDD66" />
<ImageView
android:id="#+id/colorpicker_dialog_color3"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.25"
android:background="#66CCFF"
android:tag="0x66CCFF" />
<ImageView
android:id="#+id/colorpicker_dialog_color4"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.25"
android:background="#B6C0D2"
android:tag="0xB6C0D2" />
</LinearLayout>
Here is the code of the costume Alert Dialog:
public void showColorPickerDialog() {
LayoutInflater inflater = LayoutInflater.from(this);
View layout = inflater
.inflate(R.layout.color_picker_dialog, null);
ImageView clr1 = (ImageView) layout
.findViewById(R.id.colorpicker_dialog_color1);
clr1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// .. code
}
});
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("cccc");
builder.setView(layout)
.setCancelable(true)
.setPositiveButton("ok",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
}).show();
}
The problem is that in my dialog I dont see any column.
Try using Views instead of ImageViews in your layout. The problem using ImageViews in your case is that since you do not specify the src attribute for the ImageView, it will display a 0x0-sized image, which leaves your views invisible.
I have a problem when creating a popup for my app. I'm trying to show a popup that fills the total size of my screen. The problem is that i'm getting 1px line at the left side that isn't filled.
my popup xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:id="#+id/popup"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginBottom="20dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:background="#drawable/popup_round_corners"
android:orientation="vertical"
android:padding="5dp" >
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="5dp"
android:text="#string/zm_main_uvod" />
<Button
android:id="#+id/close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginTop="10dp"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:text="Ok" />
</LinearLayout>
</LinearLAyout>
and my function to show popup:
private void showPopup(final Activity context) {
// Inflate the popup_layout.xml
LinearLayout viewGroup = (LinearLayout)findViewById(R.id.popup);
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = layoutInflater.inflate(R.layout.startpopup, viewGroup);
// Creating the PopupWindow
final PopupWindow popup = new PopupWindow(context);
popup.setContentView(layout);
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height=display.getHeight();
popup.setWidth(width+5);
popup.setHeight(height+5);
popup.setFocusable(true);
popup.showAtLocation(layout, Gravity.FILL, 0, 0);
Button close = (Button) layout.findViewById(R.id.close);
close.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
popup.dismiss();
}
});
}
I tried with gravity.center and try setting offsets to -30,-30 but nothing happend. Any ideas?
Good evening, programmers. I have a problem. Please help me to solve it.
I am writing an android application. I can't create custom dialogs. I have errors or my application looks very awfully. I have some dialogs in my application. Here is of a part of my programm:
The view is very terrible, isn't it? I want that one of the layouts to be in the dialog but it appears in the main activity. Why?
dialogtable.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LinearLayout01"
android:orientation="vertical"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
>
<LinearLayout
android:id="#+id/LinearLayout02"
android:orientation="horizontal"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
>
<TextView
android:id="#+id/textRows"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:text="Amount of rows "/>
<TextView
android:id="#+id/textColumns"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:text="Amount of columns"/>
</LinearLayout>
<LinearLayout
android:id="#+id/LinearLayout03"
android:orientation="horizontal"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
>
<EditText
android:id="#+id/EditText01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:inputType="number"
android:gravity="right"/>
<EditText
android:id="#+id/EditText02"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="right"/>
</LinearLayout>
<LinearLayout
android:id="#+id/LinearLayout04"
android:orientation="vertical"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
>
<TextView
android:id="#+id/textBorder"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:text="Width of border"/>
<EditText
android:id="#+id/EditText03"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="right"/>
</LinearLayout>
</LinearLayout>
The code from MainActivity
#Override
protected Dialog onCreateDialog(int id) {
LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.dialogtable, (ViewGroup)findViewById(R.id.LinearLayout01));
AlertDialog.Builder alert = null;
alert = new AlertDialog.Builder(this);
alert.setView(layout);
alert.setTitle("Create table");
alert.setCancelable(false);
alert.setNegativeButton("Cancel",new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
alert.setPositiveButton("OK",new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Editable rows = fieldForRows.getText();
Editable columns = fieldForColumns.getText();
Editable border = fieldForWidthOfBroder.getText();
TableAction tableAction = new TableAction(MainActivity.this.visualPane);
tableAction.insertTable(rows, columns, border);
}
});
Dialog dialog = null;
dialog = new Dialog(this);
switch (id) {
case IDD_CUSTOM_INSERT_TABLE:
dialog.setTitle("Insert table");
dialog.setContentView(R.layout.dialogtable);
return dialog;
case IDD_CUSTOM_INSERT_IMAGE:
dialog.setTitle("Insert image");
return dialog;
default:
return alert.create();
}
}
The appearance of the application before calling showDialog():
http://s015.radikal.ru/i330/1101/d0/f7cc38852dc6.jpg
The appearance of the application after calling showDialog():
http://s003.radikal.ru/i201/1101/f0/d1ebc436427f.jpg
Why it looks so terrible? What is wrong?
In your case you should use RelativeLayout instead of LinearLayout. So that you can set android:layout_weight and other relative properties on the TextViews to make their width equal.
Have a look at http://developer.android.com/resources/tutorials/views/hello-relativelayout.html and http://developer.android.com/reference/android/widget/RelativeLayout.html