I want to create a dynamic intermittent progress bar (as illustrated in the image below), that will change its intervals depending on the user's choice, in Android Studio.
The idea is that the user will choose how many times he wishes to do a behavior, and then the bar will fragment accordingly. Then each time they do the behavior, the bar will color a step increment, as shown in the image below.
Intermittent Progress Bar
I am looking for some general guidance on how to do it, since I am new to this.
I have thought of 3 ways to do this:
Have a ton of png. drawables or vectors for each case, and use one accordingly in an Image View. (seems kind of stupid to me)
Create as many views as are the intervals, and then change the view colors accordingly (in this case there will be a problem with the dynamic part of it i.e. interval variability)
Customize somehow a horizontal ProgressBar to do this automatically.
I have searched the internet for the third way which is the most elegant to me, but cant find an answer.
Thank you for your time.
This is actually trivial to obtain using the current ProgressBar APIs.
Depending on the number of tasks required and number of tasks done, you can update a ProgressBar using setMax and setProgress
progressBar.setMax(totalTasks);
progressBar.setProgress(tasksDone);
This will cover a fraction tasksDone / totalTasks in the progressBar.
Edit: Based on the scenario highlighted in the comments, you can simply use multiple views in a LinearLayout.
You can use a LinearLayout with the background of the partition color you want.
<LinearLayout
....
android:orientation="horizontal"
android:background="#color/partition"
....
/>
And then simply add the child views programmatically with equal weights (and a horizontal margin):-
for(task in tasks) {
val progressBar = View(this)
progressBar.marginEnd = gapRequired
// customize your view here: Set background, shape etc.
// Set the width to 0 and weight to 1f
val params = LinearLayout.LayoutParams(0, height, 1f)
linearLayout.addView(view, index, params)
}
Later to modify an individual view (fragment of progress bar):-
val view = linearLayout.getChildAt(index)
// Modify the view as needed
To remove a view from the layout:-
linearLayout.removeViewAt(index)
Or if you have the view referenced:-
linearLayout.removeView(view)
You can also remove all views (if you need to reset the entire progress bar for some reason) using linearLayout.removeAllViews()
You might want to use RecyclerView with an adapter if you are expecting a lot of these fragments in your progressBar.
Related
I am attempting move a Button around in an Android app I'm making (Java). Under certain circumstances in onResume(), I get margin information about the button, then attempt to place the button at the left edge of the screen with that margin as a slight gap so it looks nice. See below.
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) button.getLayoutParams(); button.setX(lp.leftMargin);
However, apparently the information in my xml layout file gets read AFTER I programmatically set the button position. So, my button is getting placed exactly in the middle of the screen (as stated in xml file) PLUS 8 dp to the right. I need a way to reorder these positioning commands -- Anyone know how to queue up a dynamic view placement in onResume so it delays just enough to occur immediately after the button is done being placed by my layout file?
Found it!! I guess it was a duplicate question, I couldn't find it searching before:
https://stackoverflow.com/a/24035591/14116101
I'm using MapActivity and I would like to put a progress bar in the marker popup that appears by clicking on it. I would like to put it under the marker title, in the area where the snippet would have been.
the marker I use is declared as it follows
new MarkerOptions().position(infoLocal.getUserLocation()).title("Your Location").snippet("This is you!").icon(BitmapDescriptorFactory.fromResource(R.drawable.player3)).anchor(0.5f, 0.5f)
As per the Android docs:
'An info window is not a live View. Instead, the view is rendered as an image on the map. As a result, any listeners you set on the view are disregarded and you cannot distinguish between click events on various parts of the view. You are advised not to place interactive components — such as buttons, checkboxes, or text inputs — within your custom info window.'
Hence you can not put live components (like progress bar) in a info window, As it converts the whole view to an image.
If you still want to achieve this, this library may help:
https://github.com/Appolica/InteractiveInfoWindowAndroid
So I have a question about best practice for dynamically creating and sizing buttons within a ViewPager, based on a changing external state.
Essentially, I have a scrolling view and I want my ViewPager to contain a number of buttons of a specific size and count depending on what part of the scrolling view is currently visible.
My question is about deciding the best implementation of this feature, I see two options: would it be simpler to
Constantly create and scale new buttons whenever the scrolling view moves
Make the viewpager itself contain a scrollview and fill it with all of the pre-scaled buttons on app startup. Then, whenever the user scrolls the main scrollview the viewpager's scrollview (which contains the buttons) will scale programatically
Any ideas on which would be the simpler and more robust system?
Not much of an answer but I will leave a comment for ya! Basically you can do it either way, both aren't to difficult to accomplish, however I would probably go the dynamic route because it will always scale correctly. Doing a set amount will only work until devices become larger, or if you are targeting tablets or tvs then it will start to become extremely messy in the xml file for the layout. Dynamically adding also gives you far more control and saves time later on, you can simply change a number and have 100 more then going through and manually adding even 10. Hope this helps!
I want to develop an Android app, where start page of the app GUI, will contain 4 vertical layouts in the main layout. Now, in each layout, I want to add buttons/slider dynamically from the app (instead of adding buttons/slider dynamically in the source code). That means, initially all these 4 layouts will be blank and when user will select any button or slider in another layout, to add it in any of this 4 layouts, the button or slider will be added in that layout. User will be able to add max 10 views in any vertical layout and the views can be either button, slider or custom view.
My attempt:
First I tried to create 4 vertical layout under the main layout for startup page and I got succeed.
I also find after searching that its possible to add views dynamically in layouts in android.
dynamically adding a view to activity layout
But most examples, add views dynamically in android by running loops, instantiating the desired view class and then add it in the main layout. Although, in this way, views are added dynamically in the layout, it is done by modifying the source code.
Is it possible to write the source code in a way, so that it can be done directly from the app? So that when user will click on Add a slider in "layout 1", a slider will be added in layout 1 and then again, when the user will click on "Add a button" in layout 1, a button will be added at the end of the slider. User will be able to customize button or slider properties. Also, if the user change the value of the slider, the app will remember its value.
Now, next time, when the app will be opened, those views will be there in the layouts, they will not be deleted and the values will remain unchanged (for example, a ticked check box will remain ticked), so I think I also need some kind of storage or properties manager.
My question is, is it possible to do this in android (because I never seen such apps in android) and if possible, any idea, how can I implement it?
I am totally new to android, so my knowledge is limited but I completed the basic tutorials on android app development and I have plugin development experience in eclipse.
Thanks a lot in. I will highly appreciate your help.
Of course it is possible:
Every layout (like LinearLayout, RelativeLayout etc.) extends the ViewGroup-class, which offers the addView-method.
To add a new view (like a Slider) to one of your layouts, just instantiate it programmatically (via new) in your activity and assign the appropriate LayoutParams to it
To store the state of user added content, it is the easiest to use SharedPreferences - a simple key-value-store which holds data over the application's lifecycle
Yes. This is possible. To create the Views dynamically, you simply have to either extend the class of the View or just say new Button(Context, AttributeSet); (Not only for Button's every View has a constructor that takes an attribute set and a context).
Using Layout.addView() you can add any View to the Layout.
Using SharedPreferences you can indicate what View belongs in what Layout.
If you decide to extend the View's class, make sure not to do too much in it. I tried that once and it just gave me an OOM (OutOfMemory Error) because I had a ton a Views trying to do stuff at the same time.
I am building an Android application and I want to create a progress bar very much like what is seen at the bottom of the MIUI File Explorer
There is no completely obvious solution as far as I can tell.
So far what I can think of is
Layering many progress bars with transparent backgrounds on top of one another
Extend the Progress bar class to take multiple values and rewrite the onDraw method
I think the first option would be far too slow and inefficient but the second option might be overly complex but is definitely the better solution.
Is there any better way of going about this?
you should make a custom view for it. Example:
final Paint blue = new Paint();
blue.setColor(Color.BLUE);
View progressBar = new View(getActivity()){
protected void onDraw(android.graphics.Canvas canvas) {
canvas.drawRect(0,0,getWidth()*progressPecentFirst,getHeight(),blue);
blue.setColor(Color.RED);
canvas.drawRect(0,0,getWidth()*progressPecentSecond,getHeight(),blue);
//Repeat this
};
};
parentLayout.addView(progressBar);
One option would be to not make it a traditional progress bar at all. In one of my personal apps I needed a display similar to a circular progress bar that had segments of varying colours.
Might I suggest you start by drawing a filled rectangle from 0B to 14.9GB in the colour for music, from 939MB to 14.9GB in the colour for Videos, from 3.52GB to 14.9GB in the colour for pictures, and so on.
You can then just draw the rounded ends in the background colour as a mask.
This would be pretty quick since you're only drawing graphics primitives and you can extend it as much as you want.
The only slight drawback would be that you'd have to implement much of the logic yourself, but that's a small price to pay in my opinion.
For someone else who can help, I leave an example on my github based on #Zelleriation answer. The progress bar.
This adapts to what I needed, feel free to modify it to yours.
<io.ekrlaz.segmentedprogressbar.view.SegmentProgressBar
android:id="#+id/progress"
android:layout_width="match_parent"
android:layout_height="10dp"
app:cornerRadius="16dp"
/>
And in your activity.
val binding = ActivityMainBinding.inflate(layoutInflater)
binding.progress.setMax(100F)
binding.progress.setPrimaryProgress(40F)
binding.progress.setSecondaryProgress(10F)
binding.progress.setThirdProgress(40F)
Link: https://github.com/EKRLAZ/segmented-progressbar
Here is the segmented progress bar based on the #Zelleriation answer. The progress bar.
SegmentedProgressBar progressBar = (SegmentedProgressBar) findViewById(R.id.segmentedProgressBar);
progressBar.setProgressColor(Color.BLACK);
progressBar.publishProgress(0.5f);
<com.muneikh.SegmentedProgressBar
android:id="#+id/segmentedProgressBar"
android:layout_width="match_parent" />
https://github.com/muneikh/SegmentedProgressBar
Dear Please see the build in example API Demo of android SKD 2.2 in api demo go to view -> progress bar -> incremental then you see the solution of you problem.