Changing font in AlertDialog - java

Could someone suggest a way to change font in a dynamically created AlertDialog (in title and body)? I tried in loads of ways, but none of them worked. The code is:
public void onClick(View v) {
new AlertDialog.Builder( c )
.setTitle( data.eqselect )
// .set
.setIcon(R.drawable.icon)
.setMessage(Threads.myData[0] )
.setNegativeButton( "Close", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Log.d( "AlertDialog", "Negative" );
}
} )
.show();
}

Instead of setting the text of the alertdialog, you should set a custom view form your layouts. And before you do so, modify your view's font.
TextView mycontent = (TextView) findViewById(R.id.yourid);
mycontent.setTypeface(Typeface.createFromAsset(getAssets(), "font.ttf")
And to set the view of your alert dialog, call .setView(mycontent) instead of setMessage()
Although this doesn't change your title as far as I know.
Update
I'm seeing you're unable to get what I'm saying, so here's a full example
TextView content = new TextView(this);
content.setText("on another font");
content.setTypeface(Typeface.SANS_SERIF);
//Use the first example, if your using a xml generated view
AlertDialog.Builder myalert = new AlertDialog.Builder(this);
myalert.setTitle("Your title");
myalert.setView(content);
myalert.setNeutralButton("Close dialog", null);
myalert.setCancelable(true);
myalert.show();
This is using a TextView that we've just created, and it won't have margins or such. If you use a readily created one form your layout files, you'd be able to customize all those settings, although you can do that for this example to in code.
Of course, replace the font with the one you want..
A sample TextView from xml could be:
<TextView
android:id="#+id/yourid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
android:text="your content" />

Related

Adding basic click animation to dynamic buttons

I have a simple button that looks like:
<?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:tag="general"
android:id="#+id/root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#343535"
android:orientation="vertical"
tools:context=".fragments.GeneralFragment">
<Button
android:id="#+id/hello"
android:layout_width="match_parent"
android:layout_height="60dp"
android:gravity="center_vertical"
android:onClick="onClick"
android:text="#string/hello" />
Instead of static, these buttons should now be dynamic
Button button = (Button) layout.getChildAt(0);
for(String text : readFromSharedPreferences) {
// Set the layout
Button btn = new Button(this.getContext());
btn.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
btn.setText(text);
btn.setTag(text);
btn.setLayoutParams(button.getLayoutParams());
btn.setBackground(button.getBackground());
layout.addView(btn);
The static button has an animation when I click on it. That looks like this:
But the dynamic button has no animation. So when I click on it, nothing happens. That looks like this:
How can I add this animation to my dynamic buttons?
Update
I have figured out that my loop contains an on-touch listener. That looks like this:
btn.setOnTouchListener(new OnSwipeTouchListener(getContext()) {
// No code in here
});
If I remove that listener (even if it contains no code), the animation works great but I would like to keep it, because of my swipe function that is placed into it.
That is my whole code:
// Swiping to link
btn.setOnTouchListener(new OnSwipeTouchListener(getContext()) {
#Override
public void onSwipeLeft() {
super.onSwipeLeft();
// Alert to ask
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("Delete");
builder.setMessage("Do you want to delete?");
// Delete
builder.setPositiveButton("Yes", (dialog, which) -> {
// Set the SharedPreferences as String
ArrayList<String> currentSharedPreferences = readFromSharedPreferences(getContext());
currentSharedPreferences.remove(btn.getTag().toString());
Gson gson = new Gson();
String currentSharedPreferencesAsText = gson.toJson(currentSharedPreferences);
// Update the SharedPreference k-text
SharedPreferences mPrefs = getContext().getSharedPreferences("k-texts", Context.MODE_PRIVATE);
SharedPreferences.Editor prefsEditor = mPrefs.edit();
prefsEditor.putString("k-text", currentSharedPreferencesAsText);
prefsEditor.apply();
// Start the animation
btn.animate()
.translationX(-btn.getWidth())
.alpha(0.0f)
.setDuration(300)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
btn.clearAnimation();
btn.setVisibility(View.GONE);
Snackbar.make(view, "Entry deleted.", Snackbar.LENGTH_LONG).setAction("Delete", null).show();
}
});
});
// Cancel
builder.setNegativeButton("No", (dialog, which) -> {
// Silence is golden
});
builder.show();
}
#Override
public void onClick() {
MainActivity mainActivity = new MainActivity();
Tts tts = new Tts(getContext(), _mediaPlayer, mainActivity.barTop, mainActivity.barBottom);
try {
tts.say(btn.getTag().toString());
} catch (Exception e) {
e.printStackTrace();
}
}
});
Well I could use
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return false;
}
Then the animation will work but onClick() wouldn't work anymore.
Another update
I had a similar problem on another view. There my static button was not having a click effect. Then I have just simply added android:foreground="?attr/selectableItemBackground" and it worked! The same way I have just tried with my dynamic button. So I have added btn.setForeground(button.getForeground()); but that doesn't do anything.
Use MaterialButton instead of Button. MaterialButton is a subtype of Button that supports additional features. The Button that is in your XML layout is actually a MaterialButton if you're using a Material Components theme. The theme automatically swaps out Buttons for MaterialButtons when your XML is inflated. So, when dynamically creating buttons in your Java code, you must use MaterialButton if you want it to match the original.
Also, when using MaterialButton, never call setBackground() because this causes undefined behavior. It likely will prevent the ripple effect from occurring as well.
Alternatively, you can define your Button in its own XML file, even with the layout params it needs for LinearLayout. Then inflate the XML each time you need another button.
for(String text : readFromSharedPreferences) {
Button btn = requireContext().getLayoutInflater()
.inflate(R.layout.my_button, layout, true); // true adds it to layout
btn.setText(text);
btn.setTag(text);
}

How to style AlertDialogs android

I need help with the dialog interface in android. i don't get it.. i' ve searched here to, i got many answers but with every code i used from here my application crashed..
So I make a notes app an you can choice a with an alert dialog which type of note you want.
The dialog window is black. So can someone show me how to chage the color maybe simple in white so that i understand how it works?
here is my code:
private void showNewNoteChoices() {
final CharSequence[] items = {
getResources().getString(R.string.text_note_type),
getResources().getString(R.string.log_note_type),
getResources().getString(R.string.important_type),
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Select type of note");
builder.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
loadNoteFragment(item, newNoteTitles, null);
}
});
AlertDialog alert = builder.create();
alert.show();
}
I know that i have to make an xml file for the specific layout and i have to make an style . Can someone show me how I can make my dialog interface in white?
I would recommend you using Dialog. You can style it the way you want.
For example, you create a custom dialog with custom layout like this;
final Dialog dialog = new Dialog(MainActivity.this);
dialog .setContentView(R.layout.custom_layout);
Then you can create views and listeners;
Button button = (Button) dialog.findViewById(R.id.button);
//Other views and listeners etc..
Finally you show it;
dialog.show();

DialogFragment not visible but selectable

I have a very strange problem on Android using DialogFragments.
I have a FrameLayout with no content and the OnClickListener set to open a FragmentDialog where the user can choose what type of content he wants to add.
If I choose an image from the gallery, this image will be loaded and an image view inside the Frame-Layout is created and the image is shown. If the user clicks again on the layout the selection dialog should open again and the user can select a new image and the old one would be replaced.
This works quite well on my device with Android 4.1. But if I test it on Android 2.3 something strange happens:
The first dialog appears and the user can choose an image from the gallery. But if the user clicks again the dialog is not shown again. But the display becomes darker as if the dialog would be there but is not shown. If I click on the position where the selection dialog should be the gallery is started again. So the dialog is definitely there, but it is simply not shown.
I have tried almost everything that came to my mind(and what I found in the internet) to fix this issue, but it does not help anything. Of course I am using the support library to import the Fragment and DialogFragment.
I start this dialog from a Fragment which is embedded in a ViewPager. So it is basically a tabbed view. What's interesting: I I run into this bug and the display is just getting darker but no dialog is visible, I can cancel the invisible dialog and just drag the ViewPager a bit to left or right(to the next fragment) and if I get back and click on the content again the dialog is shown again.
But if I am dragging the ViewPager around there are no log messages so I have no idea why the dialog is suddenly visible again if I firstly move the page(only a bit is enough).
Here is some of my code:
in the onCreateView method I do the following:
rootView = inflater.inflate(args.getInt(ARG_OBJECT_TYPE), container, false);
editorActivity = ((NoteEditorActivity) EditorSectionFragment.this.getActivity());
// ...
if( fragmentId == R.layout.fragment_note_preferences_editor ){
// the other page
else if( fragmentId == R.layout.fragment_note_editor ) {
final View addLeftElement = rootView.findViewById( R.id.addLeftElement );
final View addRightElement = rootView.findViewById( R.id.addRightElement );
final View addTopElement = rootView.findViewById( R.id.addTopElement );
final View addBottomElement = rootView.findViewById( R.id.addBottomElement );
final FrameLayout contentLayout = (FrameLayout) rootView.findViewById( R.id.contentLayout );
showNavigation(editorActivity, contentLayout, editorActivity.currentPosition.x, editorActivity.currentPosition.y);
contentLayout.setOnClickListener( new OnClickListener() {
#Override
public void onClick(View v) {
Log.i("CONTENT CREATOR", "create new element at " + editorActivity.currentPosition);
//((NoteEditorActivity) EditorSectionFragment.this.getActivity()).showContentSelectionDialog();
((NoteEditorActivity) EditorSectionFragment.this.getActivity()).showCameraChooseDialog();
}
});
}
showCameraChoose(I also did it without the FragmentTransaction, but this didn't work either)
protected void showCameraChooseDialog() {
getSupportFragmentManager().executePendingTransactions();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment prev = getSupportFragmentManager().findFragmentByTag("cameraChoose");
if( prev != null ){
Log.i("PREVIOUS", "Remove previous dialog");
ft.remove(prev);
}
(new CameraSelectionDialog()).show( ft, "cameraChoose");
}
CameraSelectionDialog:
public static class CameraSelectionDialog extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final CharSequence[] items = {"Camera", "Gallery"};
AlertDialog.Builder builder = new AlertDialog.Builder( this.getActivity() );
builder.setTitle("Choose how to get the image!");
builder.setItems(items, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if( which == 0){
((NoteEditorActivity)(getActivity())).startCamera();
CameraSelectionDialog.this.dismiss();
}
else{
((NoteEditorActivity)(getActivity())).startGallery();
CameraSelectionDialog.this.dismiss();
}
}
});
return builder.create();
}
}
The startGallery method simply starts an gallery intent:
protected void startGallery() {
Intent pickPhoto = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(pickPhoto , ActionCodes.GALLERY_ACTION_CODE);
}
This image is handled in the onActivityResult method. But it does not matter what I choose to do in the onActivityResult method. Even if I don't create the image, the problem occurs.
I have no idea what I can do to solve this problem and I hope that maybe you can think of a reason for this strange bug. I am grateful for any advice or hint what could be wrong.
Thank you in advance!

How to set font size for text of dialog buttons

I have an android app that uses some custom dialogs which are inflated from XML layouts. The contents of the dialog's view come from the XML layout, but the actual positive and negative buttons are added by calling the builder's setPositiveButton and setNegativeButton methods, so I have no control over (or at least don't know how to control) the styling of the buttons themselves.
See the onCreateDialog method below from my LoginConfirmationDialog.java file which extends DialogFragment. It basically pops a very simple dialog up that asks for confirmation of who is logging in (i.e. "Are you Joe Schmoe?", with Yes and No buttons).
The XML layout in this case has just a single TextView, and to make this easy (because the users will be construction workers with big knobby dirty fingers who need large text and large buttons), I made the font for the TextView pretty big. The two buttons though have much smaller font for their text, and since they aren't part of my layout and are added with the setPositiveButton and setNegativeButton methods, how do I control the font size?
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Bundle args = this.getArguments();
String empName = args.getString("empName");
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_login_confirmation, null);
TextView message = (TextView)view.findViewById(R.id.txtLoginConfirmationMessage);
message.setText("Are you " + empName + "?");
builder.setView(view);
builder.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mListener.onEmpConfirmPositiveClick(LoginConfirmationDialog.this);
}
});
builder.setNegativeButton("No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mListener.onEmpConfirmNegativeClick(LoginConfirmationDialog.this);
}
});
// Create the AlertDialog object and return it
return builder.create();
}
Instead of returning builder.create(), try this.-
final AlertDialog alert = builder.create();
alert.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface dialog) {
Button btnPositive = alert.getButton(Dialog.BUTTON_POSITIVE);
btnPositive.setTextSize(TEXT_SIZE);
Button btnNegative = alert.getButton(Dialog.BUTTON_NEGATIVE);
btnNegative.setTextSize(TEXT_SIZE);
}
});
return alert;
Took me a while, to integrate Asok's answer, since I used anonymous inner classes for buttons, so I needed to get a handle on the button references. This works. Make sure it goes after the messageDialog.show() line:
messageDialog.show();
messageDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextSize(TypedValue.COMPLEX_UNIT_SP, 25.0f);
messageDialog.getButton(AlertDialog.BUTTON_NEUTRAL).setTextSize(TypedValue.COMPLEX_UNIT_SP, 25.0f);
Note: It's recommended to use sp as a unit for text size. Unlike px, it is device density independent.
You can try this:
AlertDialog.Builder builder = new AlertDialog.Builder(CompQuestionsActivity.this);
builder.setMessage("Message");
builder.setPositiveButton("Yes", dialogClickListener);
builder.setNegativeButton("No", dialogClickListener);
AlertDialog alertDialog = builder.create();
alertDialog.show();
//For positive button:
Button button1 = alertDialog.findViewById(android.R.id.button1);
button1.setTextSize(25);
//For negative button:
Button button2 = alertDialog.findViewById(android.R.id.button2);
button2.setTextSize(25);
Since you are already using an xml file for the dialog why not just include the two buttons in the layout and set the onClick handlers in the dialog creation, something like this should work. I am using something similar.
Here is a quick example:
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_login_confirmation, null);
TextView message = (TextView)view.findViewById(R.id.txtLoginConfirmationMessage);
message.setText("Are you " + empName + "?");
Button positiveBtn = (Button) view.findViewById(R.id.dialogButtonPositive);
// Set size of button in relation to screen size
positiveBtn.setTextSize(TypedValue.COMPLEX_UNIT_PX, (float) 25);
positiveBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mListener.onEmpConfirmPositiveClick(LoginConfirmationDialog.this);
}
});
Button negativeBtn = (Button) view.findViewById(R.id.dialogButtonNeg);
// Set size of button in relation to screen size
negativeBtn.setTextSize(TypedValue.COMPLEX_UNIT_PX, (float) 25);
negativeBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mListener.onEmpConfirmNegativeClick(LoginConfirmationDialog.this);
}
});
builder.setView(view);
return builder.create();
I am also quite fond of using the following for setting text sizes, this allows for various screen sizes to get a different size of text (You can play with the float value to suit your needs):
.setTextSize(TypedValue.COMPLEX_UNIT_PX, (float) 25);
You should check out the following answer:
In Dialog.java (Android src) a ContextThemeWrapper is used. So you could copy the idea and do something
You just have to change the following line of code:
<item name="android:textSize">10sp</item> to your desired size.
And don't forget to check the comments of the answer also.
Best of luck.
I have tried many devices using setOnShowListener . But it did not work for all devices. In the end I come to a decision that the most easiest way is to using a Theme for your alertDialog.
Add this to the style file.
<style name="MyAlertDialogTheme" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="android:textSize">10sp</item>
</style>
Now Use this in your AlertDialog
val dialog = AlertDialog.Builder(requireActivity(),R.style.MyAlertDialogTheme)
Thats all.
My approach is to obtain the buttons in onResume() and configure them there
public class LoginConfirmationDialog extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// your code here remains unchanged
}
#Override
public void onResume() {
super.onResume();
Button positiveButton = ((AlertDialog) getDialog()).getButton(AlertDialog.BUTTON_POSITIVE);
positiveButton.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
Button negativeButton = ((AlertDialog) getDialog()).getButton(AlertDialog.BUTTON_NEGATIVE);
negativeButton.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
}
}

Android AlertDialog with dynamically changing text on every request

I want to show an AlertDialog with one option that might change on every request. So for example at one time I want to show the option "add to contacts" while another time it should be "remove from contacts".
My code does work on the first time, however Android seems to cache the AlertDialog so that onCreateDialog is not executed next time. Therefore the option doesnt change anymore. Can I prevent this caching, or is there just another way of changing the option?
I am working with SDK 1.5 but using 1.1.
#Override
protected Dialog onCreateDialog(final int id) {
...
String add_remove_contact = res.getString(R.string.profile_add_to_contacts);
if (user.getContacts().contains(profileID)) {
add_remove_contact = res.getString(R.string.profile_remove_from_contacts);
// TODO: this string is not changed when contact status changes
}
final CharSequence[] items = {res.getString(R.string.view_profile),
res.getString(R.string.profile_send_message),
add_remove_contact};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
...
return builder.create();
}
Take a look at onPrepareDialog method that will be called before dialog is shown. There You can change the required values based on request type.
Example with date picker
#Override
protected Dialog onCreateDialog(final int id) {
switch (id) {
case DIALOG_DATE_ID:
final Calendar c = Calendar.getInstance();
return new DatePickerDialog(this, this, c.get(Calendar.YEAR),
c.get(Calendar.MONTH),
c.get(Calendar.DAY_OF_MONTH));
default:
return super.onCreateDialog(id);
}
}
#Override
protected void onPrepareDialog(final int id, final Dialog dialog) {
switch (id) {
case DIALOG_DATE_ID:
//update to current time
final Calendar c = Calendar.getInstance();
((DatePickerDialog) dialog).updateDate(c.get(Calendar.YEAR),
c.get(Calendar.MONTH),
c.get(Calendar.DAY_OF_MONTH));
break;
}
}
You can also use the removeDialog(int) function of the Activity. When a dialog is dismissed, the Activity basically stores the state of the dialog (for performance reasons I would imagine). Calling removeDialog(int) on the dialog forces the activity to unload all references for the dialog and dismisses it from the screen if it's being shown.
Creating Dialogs
Activity#removeDialog(int)
This is a dup of this question:
Android: Can not change the text appears in AlertDialog
You can also do it this way:
http://andmobidev.blogspot.com/2010/03/modifying-alert-dialogs-list-items.html
Does seem to slow down the display of the longpress menu though...
I think I have a fix for the inconsistent behavior mentioned above. When initially creating the dialog (when it's still an AlertDialog.Builder), you have to set the message to an initial state (not null) or onPrepareDialog will NOT overwrite it with the intended value. So when you're creating the dialog, do something like this to always have a non-null value in the message. I struggled with this for days and found this solution by accident:
AlertDialog.Builder resultAlert = new AlertDialog.Builder(context);
if ( message == null ) {
resultAlert.setMessage("");
} else {
resultAlert.setMessage(message);
}
When you have a custom dialog you can change custom items by using dialog.getWindow().findViewById(...)
This example save the last text shown and display it again the next time you show the dialog.
// custom dialog
final Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.customized);
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialogInterface) {
EditText dialogText = (EditText)dialog.getWindow().findViewById(R.id.customText);
savedText = dialogText.getText();
}
});
dialog.show();
EditText dialogText = (EditText)dialog.getWindow().findViewById(R.id.customText);
dialogText.setText(savedText);
Customized dialog's xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/buttonOK"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="OK"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginBottom="16dp" />
<EditText
android:id="#+id/customText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="19dp"
android:hint="Message"
android:ems="10"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
I understand the performance reasons for using activity managed dialogs, but would recommend that they are not used except for simple cases. The reasons for this are:
The Bundle argument was only added in API Level 8, so can't be adopted for backwards compatibility. This effectively means that 'onPrepareDialog' needs to rely on non-local variables for state differences;
Practice indicates poor and inconsistent behaviour in response to any dialog changes made in the body of 'onPrepareDialog'.
None of these difficulties arise if Dialogs are subclassed and created as needed. 'setOwnerActivity' can be called if necessary.
And I got a idea but not so good.*This is used when the users don't use the dialog quite frequently!*The solution :first,you should declare a variable (int type) and make the default value as 0.such as private int i=0;
and before you use the showDialog methods of Activity,increase the int variable i and post the value i as the parameter as showDialog method.
the code may like this
private int i=0;
//before you show the dialog
this.i++;
this.showDialog(this.i);
exactly. for AlertDialog, that was created w/ Builder.create(), onPrepareDialog() is useless. Builder is one-way in that once the dialog is created, you can't update. i mean can't loosely, i am sure you could get a handle to the view and do it all manually, but that defeats the point of using the builder in the first place.
the only solution i found was to manually create / show / dismiss the dialog instead of using onCreateDialog(), showDialog(), etc. i tried calling removeDialog(), but that did not seem to work.

Categories