It turned out to be a really simple procedure:
First of all to make it customizable (colors-wise)
Create progress_bar_states.xml in your res/drawable folder:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/background"> <shape> <gradient android:angle="270" android:centercolor="#0b131e" android:centery="0.75" android:endcolor="#0d1522" android:startcolor="#000001"> </gradient> </shape> <item android:id="@android:id/secondaryProgress"> <clip> <shape> <gradient android:angle="270" android:centercolor="#234" android:centery="0.75" android:endcolor="#a24" android:startcolor="#234"> </gradient> </shape> </clip> <item android:id="@android:id/progress"> <clip> <shape> <gradient android:angle="270" android:centercolor="#0b1f3c" android:centery="0.75" android:endcolor="#06101d" android:startcolor="#144281"> </gradient> </shape> </clip> </item> </item></item></layer-list>
You don't need to worry about the 'secondaryProgress'.
Keep in mind that 'progress' is the color of the selected part and background is the color behind the whole progressbar.
Now Download this `progresstip.png` picture and add it to your res/drawable folder:
<
Now We have the drawables we need.
To create the progress bar, we need a small layout xml
I called it progress.xml:
<?xml version="1.0" encoding="utf-8"?> <merge xmlns:android="http://schemas.android.com/apk/res/android"> <LinearLayout android:id="@+id/linearLayout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingTop="8dip" android:paddingBottom="8dip"> <ProgressBar android:id="@+id/progressBar" android:progressDrawable="@drawable/progress_bar_states" android:layout_width="fill_parent" android:layout_height="8dip" style="?android:attr/progressBarStyleHorizontal" android:indeterminateOnly="false" android:max="100" /> </LinearLayout> <LinearLayout android:id="@+id/LL" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ImageView android:layout_width="24dip" android:src="@drawable/progresstip" android:layout_height="24dip" android:id="@+id/imageView" /> </LinearLayout> </merge>
This has <merge> It will simply merge the progress bar with the image so that they appear above each other.
Now We are ready to include this progressBar in our Activity.
Remember that
layout/main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/frameLayout1"> <include layout="@layout/progress"/> </FrameLayout> </LinearLayout>
Now if we create an Activity and set its content to main.xml
MainActivity.java
public class MainActivity extends Activity { ProgressBar progressBar; ImageView imageView; LinearLayout LL; Context mContext = this; @Override public void onCreate(Bundle bundle){ super.onCreate(bundle); setContentView(R.layout.main); } }
Nothing will move! To make it move we will set the OnTouchListener of the progress bar.
So final: MainActivity.java
public class MainActivity extends Activity { ProgressBar progressBar; ImageView imageView; LinearLayout LL; @Override public void onCreate(Bundle bundle){ super.onCreate(bundle); setContentView(R.layout.main); progressBar = (ProgressBar) findViewById(R.id.progressBar); imageView = (ImageView) findViewById(R.id.imageView); LL = (LinearLayout) findViewById(R.id.LL); progressBar.setOnTouchListener(new OnTouchListener(){ @Override public boolean onTouch(View arg0, MotionEvent arg1) { progressBar.setProgress((int)(((double)arg1.getX()/(double)arg0.getWidth())*((int)((ProgressBar)arg0).getMax()))); LL.removeAllViews(); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(imageView.getLayoutParams()); params.setMargins((int)((double)arg1.getX())-imageView.getWidth()/2, 0, 0, 0); LL.addView(imageView,params); return true; } }); } }
Now if you run the activity, everything work great, the circle follows the progress selected. However at the start of it, it is not possible to set a progress , an initial progress.
How can this be acheived?
Using one boolean and overriding of a function
Inside MainActivity.java
boolean firstTime = true; @Override public void onWindowFocusChanged(boolean hasFocus){ super.onContentChanged(); if(hasFocus&&firstTime){ firstTime=false; int initialProgress = 50; progressBar.setProgress(initialProgress); double loc = ((double)initialProgress/(double)progressBar.getMax())*(double)progressBar.getWidth(); LL.removeAllViews(); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(imageView.getLayoutParams()); params.setMargins((int)(loc)-imageView.getWidth()/2, 0, 0, 0); LL.addView(imageView,params); } }
Click here for Sample Project + Source Code (download)
Thanks for this tutorial! I am looking to apply this to a seekbar. I am not really sure why you adjust the progress the way you do. Cant you just set the progress rather than delete/create/append the thumb each time?
ReplyDeleteSetting the progress here is actually done using the seekbar setprogress (to set the seekbar progress) and using the LayoutParams setMargin (to set the tip location)
ReplyDeleteIf you could setMargin without removeView and addView with new LayoutParams, it would really be a very small constant improvement in the performance
ReplyDeleteThis type of message always inspiring and I prefer to read quality contentrebranding business
Thanks For Sharing Your Valuable Information On This Blog
ReplyDeletedigital marketing course in sivakasi
Thanks for valuable information
ReplyDeleteAdventure Mountain Treks
This comment has been removed by the author.
ReplyDelete