Custom ProgressDialog extends Dialog or ProgressDialog? - android

I am simply trying to create a spinning progress dialog. No text, no borders, no background. Just a spinning notification that lightly is center on the screen on top of content.
I have seen two different Stack Overflow questions in creating this custom Dialog.
They both use this styling:
<style name="NewDialog" parent="#android:style/Theme.Dialog">
<item name="android:windowFrame">#null</item>
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowTitleStyle">#null</item>
<item name="android:colorBackground">#ffffff</item>
<item name="android:windowAnimationStyle">#android:style/Animation.Dialog</item>
<item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:width">600dip</item>
<item name="android:height">100dip</item>
<item name="android:textColor">#FF0000</item>
</style>
But in the Java side, one extends Dialog and contains lots of custom content, the other one is simply this:
public class MyProgressDialog extends ProgressDialog {
public MyProgressDialog(Context context) {
super(context, R.style.NewDialog);
}
}
On the first (extends Dialog), I get a blank. No dialog. Nothing. On the code sample just above, I get a shrunken small dialog spinning inside a black box that is off centered.
Which method is more correct and can I have a sample on how to implement this?
Also, how can I make that dialog transparent/borderless?

The 'right way' to do this now would be to extend DialogFragment http://developer.android.com/reference/android/app/DialogFragment.html
If you are not using the compatibility library, you are not programming in the current Android world.
If you want to extend Dialog, then I have some example code here: https://github.com/tom-dignan/nifty/tree/master/src/com/tomdignan/nifty/dialogs In this code, I implemented a kind of 'progress dialog' by extending Dialog. I extended Dialog because I wanted full control and wanted my Dialog to be full-screen.
I would recommend reading the above DialogFragment doc and using that, though.
So really, there is no right or wrong way here. Extending any of the three classes will work, but the cleanest and most current would be the DialogFragment approach.

One way of doing it is to use a custom dialog, request feature No_Title and set the background drawable resource to transparent.
You can use the following code, I just wrote and tested it out on Android 4.0.3 ICS.
The xml layout in layout folder is, say dialog_progress.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="match_parent"
android:orientation="vertical">
<ProgressBar
android:id="#+id/dialogProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
</LinearLayout>
The java code to display the dialog and make it transparent is as follows.
Dialog dialog = new Dialog (this);
dialog.requestWindowFeature (Window.FEATURE_NO_TITLE);
dialog.setContentView (R.layout.dialog_progress);
dialog.getWindow ().setBackgroundDrawableResource (android.R.color.transparent);
dialog.show ();

Something similar can be achieved very easily by using frame-by-frame animation on an ImageView instead of making custom progress dialog. For this you just need a sequence of images(can be extracted from any gif). And then you can apply frame-by-frame animation on it. It will do exactly what you want.
I have done something similar with the code below -:
// XML for frame by frame animation
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false" >
<item
android:drawable="#drawable/frame00"
android:duration="150"/>
<item
android:drawable="#drawable/frame01"
android:duration="150"/>
<item
android:drawable="#drawable/frame02"
android:duration="150"/>
<item
android:drawable="#drawable/frame03"
android:duration="150"/>
<item
android:drawable="#drawable/frame04"
android:duration="150"/>
<item
android:drawable="#drawable/frame05"
android:duration="150"/>
<item
android:drawable="#drawable/frame06"
android:duration="150"/>
Java code for starting animation :-
ImageView iv = (ImageView)findViewById(R.id.progressDialog);
iv.setBackgroundResource(R.anim.progress_dialog_icon_drawable_animation);
AnimationDrawable aniFrame = (AnimationDrawable) iv.getBackground();
aniFrame = (AnimationDrawable) iv.getBackground();
aniFrame.start();
Hope it helps !

Related

It is possible to create a button by passing parameters in the XML android?

Is it possible to create a button by passing parameters in XML ?
doing it that way ?
<Button
button:typeParameter="primary"
button:size="md"/>
And after passing these 2 parameters the button is created as it should be, is it possible to do this?
I already have a button on which I created new attributes, now I want to know if it is possible to pass parameters and this button be called, without the need for the developer to have to code all these lines.
<customButton
android:fontFamily="#font/mondrian_family_font"
app:fontFamily="#font/mondrian_family_font"
android:id="#+id/mdnButtonPrimary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:text="Button primary"
android:paddingLeft="40dp"
android:paddingRight="40dp"
android:textColor="#color/color_neutral_lightest"
android:layout_marginTop="10dp"
android:textSize="#dimen/font_size_XXS"
mdnbutton:radius="#dimen/border_radius_pill"
mdnbutton:defaultColor="#color/color_brand_primary_medium"
mdnbutton:focusColor="#color/color_brand_primary_darkest"
style="?android:attr/borderlessButtonStyle"/>
It is possible that he will use these attributes after he installs my library.
Now I want that when the developer is going to create his layout, instead of creating a button from scratch, he just passes parameters in the XML and the button is rendered.
I suggest for you to make it as a style. But having it depend on two attributes is a bit hard, so I suggest to make a style for every combination of the two, so you have a style called primaryMd for example.
Your button would be like this:
<Button
style="#style/primaryMd" />
you can define this style in you res folder in styles.xml like this for example then:
<resources>
<style name="primaryMd" parent="#style/Widget.AppCompat.Button.Borderless">
<item name="android:fontFamily">#font/mondrian_family_font</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textAllCaps">false</item>
<item name="android:text">Button primary</item>
<item name="android:paddingLeft">40dp</item>
<item name="android:paddingRight">40dp</item>
<item name="android:textColor">#color/color_neutral_lightest</item>
<item name="android:layout_marginTop">10dp</item>
<item name="android:textSize">#dimen/font_size_XXS</item>
<item name="mdnbutton:radius">#dimen/border_radius_pill</item>
<item name="mdnbutton:defaultColor">#color/color_brand_primary_medium</item>
<item name="mdnbutton:focusColor">#color/color_brand_primary_darkest</item>
</style>
</resources>
I'm not entirely sure if it works with these custom mdnbutton attributes, but you could try it out maybe

Android change button style resource on click

I haven't been able to find quite what I am trying to do on SO, but I feel like it should be such a common interface need that there must be a straightforward way of accomplishing this that I'm missing.
In my style.xml I have two button styles, a standard "active" button and an "inactive" button.
<style name="ButtonStandard">
<item name="android:background">#color/colorGreen</item>
<item name="android:textColor">#android:color/white</item>
<item name="android:padding">#dimen/element_padding</item>
</style>
<style name="ButtonInactive">
<item name="android:background">#color/colorLight</item>
<item name="android:textColor">#android:color/black</item>
<item name="android:padding">#dimen/element_padding</item>
</style>
I am setting one button to ButtonStandard and the other to ButtonInactive. When I click the inactive button, I want to change it to use the ButtonStandard type and vice versa. I don't want to programmatically set the styles individually in case I decide to later change the button styles and it would be unreliable to have to change it in every location.
activeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
activeButton.[somehowsetstyle](R.style.ButtonInactive);
inactiveButton.[somehowsetstyle](R.style.ButtonStandard);
}
});
How can I change between these styles when users click on buttons? The most important is to not have to set specific styles within the code which is just a last resort imho.
Thanks!
Solution Notes
Generally I followed the solution below but instead I created the selector as a drawable and used android:drawable instead because it seems the button background needs that, even if just specifying a color. I also used state_activated rather than enabled so that it is only changing the look of the button and doesn't prevent clicks.
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="false"
android:drawable="#color/colorPrimaryDark" />
<item android:state_activated="true"
android:drawable="#color/colorGreen" />
<item android:drawable="#color/colorGreen" />
In XML
android:background="#drawable/selector_btn_bkg"
android:state_activated="false"
In Java
myButton.setActivated(true);
What you are looking for is ColorStateList
drawable/my_selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:color="#color/enabled_color"/>
<item android:color="#color/enabled_color"
android:state_enabled = "true"/>
<item android:color="#color/disbaled_color"
android:state_enabled = "false"/>
</selector>
my_view.xml
...
<Button
android:id="#+id/my_button"
android:enabled="false"
android:background="#drawable/my_selector"/>
Java code
onClick(View v){
myButton.setEnabled(true);
}

Disabled seekBar without dimming

I need to prevent seekbar from user inputs in special cases. If I use setEnabled(false) it becomes gray instead of white.
Is there any method to disable seekbar without dimming or set another drawable for progress in disabled seekbar ?
Yes. It is possible! But you need to override SeekBar's drawableStateChanged function, with something like this:
#Override
protected void drawableStateChanged() {
super.drawableStateChanged();
final Drawable progressDrawable = getProgressDrawable();
if(isEnabled() == false && progressDrawable != null) progressDrawable.setAlpha(255);
}
Actually I was very angry, when I saw hardcoded alpha value in AbsSeekBar:
mDisabledAlpha = a.getFloat(com.android.internal.R.styleable.Theme_disabledAlpha, 0.5f);
Because there is no function, which will turn off, or even change disabled alpha value for SeekBar. Just take a look at those lines of code in drawableStateChanged function:
if (progressDrawable != null) {
progressDrawable.setAlpha(isEnabled() ? NO_ALPHA : (int) (NO_ALPHA * mDisabledAlpha));
}
I'm not sure why you'd want to change this, and I don't believe it's good practice to override the visual queue for a user that something is disabled. If it looks active, but doesn't interact, I'm going to be mad at your app.
Regardless, to answer your question, you should look at StateListDrawable this question outlines it specifically for seek bars.
Better solution here....
seekBar.setOnTouchListener(new OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
You can use setEnabled(false) and set the Theme_disabledAlpha attribute as #Ilya Pikin mentioned above like this:
<item name="android:disabledAlpha">1.0</item>
Android changes alpha value of color to 127 from 255 in disabled state. Just make sure you set it back to 255 after disabling seekbar.
seekBar.post(new Runnable(){
#Override
public void run()
{
seekBar.getProgressDrawable().setAlpha(255);
}
});
view.post is required only if you are unsure that seekbar is rendered yet or not, otherwise just
seekBar.getProgressDrawable().setAlpha(255);
is enough.
I´m a bit late to the party, but here is a solution to solve your question.
First of all I recommand to use com.google.android.material.slider.Slider nowadays. It is much more flexible than the old seekbar was. To do so, use the following import in your gradle file
implementation 'com.google.android.material:material:1.6.0' //1.4.0 or newer
Now create your layout file, let´s it call layout_slider
e.g.:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white">
<com.google.android.material.slider.Slider
android:id="#+id/sbSize"
style="#style/sliderTheme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:value="25"
android:valueFrom="0.0"
android:valueTo="100.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Now open your styles.xml file and create the sliderTheme. It should look like this:
<style name="sliderTheme" parent="Widget.MaterialComponents.Slider">
<item name="trackColorInactive">#color/slider_track_inactive</item>
<item name="thumbColor">#color/slider_thumb_color</item>
<item name="trackColorActive">#color/slider_track_active</item>
</style>
The next step we need to do is create a new Resource Directory named color inside the res folder. (Resource type is color)
Now create a file to change the trackColor for active and inactive state. Let´s name it slider_track_inactive.xml
Copy the following content inside that file:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:alpha="0.24" android:color="?attr/colorPrimary" android:state_enabled="true"/>
<item android:alpha="0.12" android:color="?attr/colorOnSurface"/>
</selector>
the first value is for the active and the second is for the inactive color. Change alpha and color to a value to want. All my sample values are the Google default values.
Now create a file called slider_thumb_color.xml inside the color folder. It should look like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorPrimary" android:state_enabled="true"/>
<item android:alpha="0.38" android:color="?attr/colorOnSurface"/>
</selector>
Again, change these values as you want.
Last, create a file called slider_track_active.xml inside the color folder. It should look like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorPrimary" android:state_enabled="true"/>
<item android:alpha="0.32" android:color="?attr/colorOnSurface"/>
</selector>
Now you have customized all colors for the disabled slider. There are much more values you can customize with the same technique. All default keys you can customize inside your styles.xml file are:
<item name="haloColor">#color/material_slider_halo_color</item>
<item name="haloRadius">#dimen/mtrl_slider_halo_radius</item>
<item name="labelStyle">#style/Widget.MaterialComponents.Tooltip</item>
<item name="thumbColor">#color/material_slider_thumb_color</item>
<item name="thumbElevation">#dimen/mtrl_slider_thumb_elevation</item>
<item name="thumbRadius">#dimen/mtrl_slider_thumb_radius</item>
<item name="tickColorActive">#color/material_slider_active_tick_marks_color</item>
<item name="tickColorInactive">#color/material_slider_inactive_tick_marks_color</item>
<item name="trackColorActive">#color/material_slider_active_track_color</item>
<item name="trackColorInactive">#color/material_slider_inactive_track_color</item>
<item name="trackHeight">#dimen/mtrl_slider_track_height</item>
<item name="minSeparation">0dp</item>

Open activity using a expand animation

I need to open a activity at the right part of the screen but still view the old activity at the left part of the screen.
It can be something like a dialog but i need to specify the position of the new activity and also remove the overlay look and feel.
how can i make this?
I have already achieve my first step. putting the activity at a specific position and see the main at the left of screen.
I have used the following style:
<style name="Theme.Transparent" parent="android:Theme">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">false</item>
<item name="android:backgroundDimEnabled">false</item>
</style>
in my layout file i have setted my linear layout like this
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="200dp"
android:layout_height="200dp"
android:orientation="vertical"
android:background="#drawable/background_login"
android:layout_gravity="top|right">
this way the activity goes to where i want. now i just need to open the activity with an expand animation and close it with an collapse animation.
Can someone tell me how?
Seems like you're looking for Fragments. Multiple fragments can be shown next to each other, so one fragment can be your left part of the screen and another one be opened on the right side.
Please refer to the Android Dev Guide for more information.

Android Borderless Dialog

I have created an AlertDialog using AlertDialog.Builder, but the Dialog border takes up too much space on the screen. How do I remove the border? I have tried using another Activity to emulate the dialog with a transparent background, but the dialog is used repeatedly, and creating a new Activity every time introduces a significant amount of lag.
The answer from here mentions that it can be found in the ApiDemos, but i can't seem to find it.
Alright, I'll answer my own question. Basically, instead of using AlertDialog.Builder, create a regular Dialog using it's constructor, and use a suitable theme instead of the default Dialog theme.
So your code would look something like this:
Dialog dialog = new Dialog(this, android.R.style.Theme_Translucent_NoTitleBar);
Hope this helps someone else.
Here is my solution, to get a dialog that shows only your content.
Dialog dialog = new Dialog(this,R.style.ThemeDialogCustom);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
//you can move the dialog, so that is not centered
// dialog.getWindow().getAttributes().y = 50; //50 should be based on density
dialog.setContentView(yourLinearLayout);
dialog.setCancelable(true);
//dialog.setOnCancelListener(cancelListener);
dialog.show();
themes.xml // located in project /res/values
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="ThemeDialogCustom">
<item name="android:windowFrame">#null</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowAnimationStyle">#android:style/Animation.Dialog</item>
<item name="android:windowBackground">#color/transparent_color</item>
<item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
<item name="android:colorBackgroundCacheHint">#null</item>
</style>
</resources>
colors.xml // also located there
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="transparent_color">#00000000</color>
</resource>
Using android.R.style.Theme_Translucent_NoTitleBar works if you want the dialog to be full screen. An alternative is to create your own style, like so:
<style
name="Theme_Dialog_Translucent"
parent="android:Theme.Dialog">
<item
name="android:windowBackground">#null</item>
</style>
try this :D
Dialog popUpView= new Dialog(this);
popUpView.getWindow().setBackgroundDrawable(new ColorDrawable(0));
I added a transparent pixel to drawable and used the following code :
dialog.getWindow().setBackgroundDrawableResource(R.drawable.transpix);
if you have 2 border you need to use a ContextThemeWrapper, which it will show only one border as you would like :)
ContextThemeWrapper wrapper = new ContextThemeWrapper(this, android.R.style.Theme_Holo);
final LayoutInflater inflater = (LayoutInflater) wrapper.getSystemService(LAYOUT_INFLATER_SERVICE);
AlertDialog.Builder builder = new AlertDialog.Builder(wrapper);
You can ask the builder to enforce inverse background. Worked for me to display a borderless splash screen with a png source.
In your resources file create a xml file named for e.g. null_image.xml, with the following content:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="#0000" />
<size
android:height="1dp"
android:width="1dp" />
</shape>
In your java code, fetch the dialog window and set the xml file as the drawable resource, like this:
Depending on your context:
Dialog dialog = new Dialog(getContext());
Window window = dialog.getWindow();
window.setBackgroundDrawableResource(R.drawable.null_image);
That's it, enjoy.

Categories

Resources