Scrollbar color in RecyclerView - android

How can I change the color of my scrollbar in a recyclerView?
I have the scrollbar but I want to change its color.
My recyclerView is like this:
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/recyclerView"
android:layout_below="#id/my_toolbar"
android:layout_above="#+id/progressBar"
android:scrollbars="vertical"
/>

You can do this by including following line of code in your Recyclerview
android:scrollbarThumbVertical="#drawable/yoursdrawablefile
The drawable file in my case is:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient android:startColor="#000" android:endColor="#000"
android:angle="45"/>
<corners android:radius="6dp" />
</shape>

In case you want to further style your scrollbars, create two drawable resource file in your drawable folder as 1. scrollbar_track and 2. scrollbar_thumb
scrollbar_track.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<gradient
android:angle="0"
android:endColor="#9BA3C5"
android:startColor="#8388A4" />
<corners android:radius="6dp" />
</shape>
scrollbar_thumb.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<gradient
android:angle="0"
android:endColor="#b20111"
android:startColor="#cf1d2d" />
<corners android:radius="6dp" />
</shape>
Now, create a style named scrollbar_style in your styles.xml file as:
<style name="scrollbar_style">
<item name="android:scrollbarAlwaysDrawVerticalTrack">true</item>
<item name="android:scrollbarStyle">outsideOverlay</item>
<item name="android:scrollbars">vertical</item>
<item name="android:fadeScrollbars">true</item>
<item name="android:scrollbarThumbVertical">#drawable/scrollbar_thumb</item>
<item name="android:scrollbarTrackVertical">#drawable/scrollbar_track</item>
<item name="android:scrollbarSize">8dp</item>
<item name="android:scrollbarFadeDuration">800</item>
<item name="android:scrollbarDefaultDelayBeforeFade">500</item>
</style>
Finally, to apply this style to the scrollbar in your recyclerview, add
style="#style/scrollbar_style"
to your recyclerview.
In your case:
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/recyclerView"
style="#style/scrollbar_style"
android:layout_below="#id/my_toolbar"
android:layout_above="#+id/progressBar"
android:scrollbars="vertical"
/>

If you need to change the color in runtime, this is the way.
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorInt;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
/**
* Created on 22.3.2016.
*
* #author Bojan Kseneman
* #description A recycler view that will draw the scroll bar with a different color
*/
public class CustomScrollBarRecyclerView extends RecyclerView {
private int scrollBarColor = Color.RED;
public CustomScrollBarRecyclerView(Context context) {
super(context);
}
public CustomScrollBarRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomScrollBarRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setScrollBarColor(#ColorInt int scrollBarColor) {
this.scrollBarColor = scrollBarColor;
}
/**
* Called by Android {#link android.view.View#onDrawScrollBars(Canvas)}
**/
protected void onDrawHorizontalScrollBar(Canvas canvas, Drawable scrollBar, int l, int t, int r, int b) {
scrollBar.setColorFilter(scrollBarColor, PorterDuff.Mode.SRC_ATOP);
scrollBar.setBounds(l, t, r, b);
scrollBar.draw(canvas);
}
/**
* Called by Android {#link android.view.View#onDrawScrollBars(Canvas)}
**/
protected void onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar, int l, int t, int r, int b) {
scrollBar.setColorFilter(scrollBarColor, PorterDuff.Mode.SRC_ATOP);
scrollBar.setBounds(l, t, r, b);
scrollBar.draw(canvas);
}
}
These methods are defined in View class, so the same princible should work of other views like ScrollView and ListView.

Related

Vertical progressbar in Android [duplicate]

I am trying to use a ProgressBar as a metering like display. I thought it was going to be an easy task and thought that ProgressBar had a property to set to be vertical, but I'm not seeing anything.
Additionally I'd like to be able to show ruler like indicator along the side of the bar to clearly indicate the current level.
Pointers appreciated - Thanks!
I had recently come across the need for a vertical progress bar but was unable to find a solution using the existing Progress Bar widget. The solutions I came across generally required an extension of the current Progress Bar or a completely new class in it self. I wasn't convinced rolling out a new class to achieve a simple orientation change was necessary.
This article presents a simple, elegant, and most importantly, a no-hack solution to achieving a vertical progress bar.
I'm going to skip the explanation and simply provide a cookie cutter solution. If you require further details feel free to contact me or leave a comment below.
Create an xml in your drawable folder (not drawable-hdpi or drawable-mdpi -- place it in drawable). For this example I call my xml vertical_progress_bar.xml
Here's what to place in the xml file:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#android:id/background">
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ff9d9e9d"
android:centerColor="#ff5a5d5a"
android:centerY="0.75"
android:endColor="#ff747674"
android:angle="180"
/>
</shape>
</item>
<item android:id="#android:id/secondaryProgress">
<clip android:clipOrientation="vertical" android:gravity="bottom">
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#80ffd300"
android:centerColor="#80ffb600"
android:centerY="0.75"
android:endColor="#a0ffcb00"
android:angle="180"
/>
</shape>
</clip>
</item>
<item android:id="#android:id/progress">
<clip android:clipOrientation="vertical" android:gravity="bottom">
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ffffd300"
android:centerColor="#ffffb600"
android:centerY="0.75"
android:endColor="#ffffcb00"
android:angle="180"
/>
</shape>
</clip>
</item>
</layer-list>
Create an xml file called styles.xml and place it in res/values. If your project already contains styles.xml in res/values then skip this step.
Modify your styles.xml file and append the following code to the end of the file:
<style name="Widget">
</style>
<style name="Widget.ProgressBar">
<item name="android:indeterminateOnly">true</item>
<item name="android:indeterminateBehavior">repeat</item>
<item name="android:indeterminateDuration">3500</item>
<item name="android:minWidth">48dip</item>
<item name="android:maxWidth">48dip</item>
<item name="android:minHeight">48dip</item>
<item name="android:maxHeight">48dip</item>
</style>
<style name="Widget.ProgressBar.Vertical">
<item name="android:indeterminateOnly">false</item>
<item name="android:progressDrawable">#drawable/progress_bar_vertical</item>
<item name="android:indeterminateDrawable">#android:drawable/progress_indeterminate_horizontal</item>
<item name="android:minWidth">1dip</item>
<item name="android:maxWidth">12dip</item>
</style>
Add your new vertical progress bar to your layout. Here's an example:
<ProgressBar
android:id="#+id/vertical_progressbar"
android:layout_width="12dip"
android:layout_height="300dip"
style="#style/Widget.ProgressBar.Vertical"
/>
That should be all you need to do to make use of a vertical progress bar in your project. Optionally, you might have custom drawable nine-patch images that you are using for the progress bar. You should make the appropriate changes in the progress_bar_vertical.xml file.
I hope this helps you out in your project!
You have to create your own custom progressbar.
In your xml add this layout:
<com.example.component.VerticalProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:id="#+id/verticalRatingBar1"
android:layout_width="wrap_content"
android:progress="50"
android:layout_height="fill_parent" />
VerticalProgressBar.java
public class VerticalProgressBar extends ProgressBar{
private int x, y, z, w;
#Override
protected void drawableStateChanged() {
// TODO Auto-generated method stub
super.drawableStateChanged();
}
public VerticalProgressBar(Context context) {
super(context);
}
public VerticalProgressBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public VerticalProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(h, w, oldh, oldw);
this.x = w;
this.y = h;
this.z = oldw;
this.w = oldh;
}
#Override
protected synchronized void onMeasure(int widthMeasureSpec,
int heightMeasureSpec) {
super.onMeasure(heightMeasureSpec, widthMeasureSpec);
setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
}
protected void onDraw(Canvas c) {
c.rotate(-90);
c.translate(-getHeight(), 0);
super.onDraw(c);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (!isEnabled()) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
setSelected(true);
setPressed(true);
break;
case MotionEvent.ACTION_MOVE:
setProgress(getMax()
- (int) (getMax() * event.getY() / getHeight()));
onSizeChanged(getWidth(), getHeight(), 0, 0);
break;
case MotionEvent.ACTION_UP:
setSelected(false);
setPressed(false);
break;
case MotionEvent.ACTION_CANCEL:
break;
}
return true;
}
#Override
public synchronized void setProgress(int progress) {
if (progress >= 0)
super.setProgress(progress);
else
super.setProgress(0);
onSizeChanged(x, y, z, w);
}
}
Or :
Jagsaund solution is also being perfect.
I know that it´s an old post but I found a very simple solution to this problem that maybe can help somebody.
First at all create a progress_drawable_vertical.xml like this:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#android:id/background">
<color android:color="#777" />
</item>
<item android:id="#android:id/progress">
<clip
android:clipOrientation="vertical"
android:gravity="bottom">
<shape>
<gradient
android:startColor="#00FF00"
android:centerColor="#FFFF00"
android:endColor="#FF0000"
android:angle="90" />
</shape>
</clip>
</item>
</layer-list>
Then just use this in your progressBar:
<ProgressBar
android:id="#+id/progress_bar"
style="#android:style/Widget.ProgressBar.Horizontal"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:max="100"
android:progress="33"
android:progressDrawable="#drawable/progress_drawable_vertical" />
I also have created an progress_drawable_horizontal.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#android:id/background">
<color android:color="#777" />
</item>
<item android:id="#android:id/progress">
<clip
android:clipOrientation="horizontal"
android:gravity="left">
<shape>
<gradient
android:startColor="#00FF00"
android:centerColor="#FFFF00"
android:endColor="#FF0000" />
</shape>
</clip>
</item>
</layer-list>
with the objetive of mantain the same style defined in progress_drawable_vertical.xml
The key here is the correct use of android:clipOrientation and android:gravity.
I found this solution here and the core of the solution is similar to jagsaund but a little bit more simple.
I found the probably best(easiest & most versatile) solution:)
This is an old post, but it was so hard for me to find this so easy solution so I thought I should post it..
Just use a scale-drawable (or a 9-patch if you want), no need for ANY OTHER code.
Example:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#android:id/background" android:drawable="#color/transparent"/>
<item android:id="#android:id/progress">
<scale android:scaleGravity="bottom" android:scaleWidth="0%" android:scaleHeight="100%">
<shape >
<solid android:color="#color/blue"/>
<corners android:topRightRadius="1dp" android:topLeftRadius="1dp"/>
</shape>
</scale>
</item>
</layer-list>
And of course the normal code:
<ProgressBar
android:id="#+id/progress_bar"
style="#android:style/Widget.ProgressBar.Horizontal"
android:layout_width="24dp"
android:layout_height="match_parent"
android:max="1000"
android:progress="200"
android:progressDrawable="#drawable/progress_scale_drawable" />
Notice the scale-drawable's xml lines (the magic lines):
android:scaleGravity="bottom" //scale from 0 in y axis (default scales from center Y)
android:scaleWidth="0%" //don't scale width (according to 'progress')
android:scaleHeight="100%" //do scale the height of the drawable
This perfectly works
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#android:id/background">
<shape>
<gradient
android:startColor="#DDDDDD"
android:centerColor="#DDDDDD"
android:centerY="0.75"
android:endColor="#DDDDDD"
android:angle="270"
/>
</shape>
</item>
<item
android:id="#android:id/progress">
<clip
android:clipOrientation="vertical"
android:gravity="top">
<shape>
<gradient
android:angle="0"
android:startColor="#302367"
android:centerColor="#7A5667"
android:endColor="#C86D67"/>
</shape>
</clip>
</item>
</layer-list>
<ProgressBar
android:id="#+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="5dp"
android:layout_height="match_parent"`enter code here`
android:progressDrawable="#drawable/progress_dialog"/>
Creating the progress bar (I converted my code from c# to java so might not be 100% correct)
ProgressBar progBar = new ProgressBar(Context, null, Android.resource.attribute.progressDrawable);
progBar.progressDrawable = ContextCompat.getDrawable(Context, resource.drawable.vertical_progress_bar);
progBar.indeterminate = false;
vertical_progress_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#android:id/background">
<shape>
<solid android:color="#color/grey" />
<corners android:radius="20dip" />
</shape>
</item>
<item android:id="#android:id/progress">
<scale
android:drawable="#drawable/vertical_progress_bar_blue_progress"
android:scaleHeight="100%"
android:scaleGravity="bottom"/>
</item>
</layer-list>
vertical_progress_bar_blue_progress.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<corners
android:radius="20dip" />
<solid android:color="#color/ProgressBarFourth" />
</shape>
What's going to make your bar vertical is the scaleHeight and scaleGravity attributes in vertical_progress_bar.xml.
It ends up looking something like this:
Simple and Easy way:
Just add a view to a LinearLayout and scale it.
<LinearLayout
android:layout_width="4dp"
android:layout_height="300dp"
android:background="#color/md_green_50"
android:orientation="vertical">
<View
android:id="#+id/progressView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="top"
android:layout_weight="1"
android:background="#color/md_green_500"
android:scaleY="0.0" />
</LinearLayout>
Set View's pivotY to zero:
progressView.pivotY = 0F
Now you can fill the progress using scaleY between 0F and 1F:
progressView.scaleY = 0.3F
Bonus:
Animate progress using animate():
progressView.animate().scaleY(0.3F).start()
Here is a simple solution, just rotate your progress bar
android:rotation="270"
Add this to the xml code
android:rotation="90"
android:transformPivotX="0dp"
So this is how your Progress Bar xml should look
<ProgressBar
android:id="#+id/progressBar6"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:rotation="90"
android:transformPivotX="0dp"
tools:layout_editor_absoluteX="101dp"
tools:layout_editor_absoluteY="187dp" />
To utilize the ProgressBar and make it vertical, you would have to create your own custom View extending the ProgressBar view and override the onDraw() method. This will allow you to draw it in a reverse orientation. Take a look at the source code of the ProgressBar.onDraw() (located at the bottom of the link) for help on how to do this. Best case scenario, you'll just have to swap a few x and y variables.
I have the exact problem. Making a custom class (extending ProgressBar) will create code that are hard to maintain. Using a custom style will cause compatibility issue with different theme from new OS (e.g. lollipop)
Eventually, I just apply a rotation animation to an horizontal progress bar. Inspired by Pete.
Create the tag in your layout xml like normal horizontal progress bar.
Make sure that the size and position of the ProgressBar is what you want after rotation. (Perhaps setting negative margin will help). In my code I rotate the view from 0,0.
Use the method below to rotate and set new progress.
Code:
private void setProgress(final ProgressBar progressBar, int progress) {
progressBar.setWillNotDraw(true);
progressBar.setProgress(progress);
progressBar.setWillNotDraw(false);
progressBar.invalidate();
}
private void rotateView(final View v, float degree) {
Animation an = new RotateAnimation(0.0f, degree);
an.setDuration(0);
an.setRepeatCount(0);
an.setFillAfter(true); // keep rotation after animation
v.setAnimation(an);
}
Simple progrebar image view
example
viewHolder.proBarTrueImage.setMaximalValue(147);
viewHolder.proBarTrueImage.setLevel(45);
viewHolder.proBarTrueImage.setColorResource(R.color.corner_blue);
simple class
public class ProgressImageView extends ImageView {
private Context mContext;
private Paint paint;
private RectF rectf;
private int maximalValue = 1;
private int level = 0;
private int width;
private int height;
public ProgressImageView(Context context) {
super(context);
init(context, null, 0);
}
public ProgressImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public ProgressImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
private void init(Context context, AttributeSet attrs, int defStyleAttr){
mContext = context;
paint = new Paint();
rectf = new RectF();
paint.setColor(Color.GRAY);
paint.setStyle(Paint.Style.FILL);
};
#Override
protected void onDraw(Canvas canvas) {
float dif = (float) height / (float) maximalValue;
int newHeight = height - (int) (dif * level);
rectf.set(0,newHeight, width, height);
canvas.drawRect(rectf, paint);
super.onDraw(canvas);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
this.width = w;
this.height = h;
}
public void setMaximalValue(int maximalValue) {
this.maximalValue = maximalValue;
invalidate();
}
public void setLevel(int level) {
this.level = level;
invalidate();
}
public void setColorResource(int color) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
color = mContext.getResources().getColor(color,mContext.getTheme());
}else {
color = mContext.getResources().getColor(R.color.corner_blue);
}
setColor(color);
}
public void setColor(int color){
if (paint != null){
paint.setColor(color);
invalidate();
}
}
}
<ProgressBar
android:id="#+id/battery_pb"
android:rotation="270"
android:progress="100"
...
/>
Use android:rotation="270" to 100% be like bottom to top or android:rotation="90" to 100% be like top to bottom
enter link description here
**Check this link out, I was trying to use a similar thing and also you can use stepper for your requirement, few projects are available on Github about HOW TO USE STEPPER IN ANDROID STUDIO **
For making a vertical ProgressBar, The way that I solved it was first rotating it by 90 degrees, then scaling it with a value entered by hand.
scaleX = layout_height/layout_width
Here's an example of my attributes on the ProgressBar
android:layout_width="20dp"
android:layout_height="233dp"
android:rotation="-90"
android:scaleX="11.65"
This can be a little manual, but because they don't have a vertical progress bar by default, this was a pretty good workaround for me. The scaleX could be calculated automatically, but it would have to be after everything is drawn on the screen.
Vertical progress bars are not supported by default.

How to set Material design style to disabled EditText (android)?

I'm trying to make my disabled EditText's style like in guidelines:
https://www.google.com/design/spec/components/text-fields.html#text-fields-labels
<EditText
android:id="#+id/account_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/test_account"
android:enabled="false" />
I've already implemented material design styles, so all my widgets look material.
The question is: Is there any way to get this dotted underline using styles, without putting additional views?
My styles.xml:
<style name="Theme.Main" parent="#style/Theme.AppCompat.Light.NoActionBar">
<item name="android:editTextStyle">#style/android:Widget.Material.EditText</item>
</style>
Finally I managed to do as you've shown, It looks like
Create dotted.xml inside drawable folder and paste these
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:bottom="1dp"
android:left="-2dp"
android:right="-2dp"
android:top="-2dp">
<shape android:shape="rectangle">
<stroke
android:width="0.5dp"
android:color="#android:color/black" />
<solid android:color="#ffffff" />
<stroke
android:width="1dp"
android:color="#030310"
android:dashGap="5dp"
android:dashWidth="5dp" />
<padding
android:bottom="5dp"
android:left="5dp"
android:right="5dp"
android:top="5dp" />
</shape>
</item>
</layer-list>
Then simply set the android:background attribute to dotted.xml we just created. Your EditText looks like this.
<EditText
android:id="#+id/account_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="test account"
android:background="#drawable/dotted"
style="#style/Theme.Main" <!--Its your custom style-->
android:enabled="false" />
AFAIK, there is no "stock" way. Take the material design guidelines as it is, a guideline ;)
Finally I ended up with a custom view. It might be not the most elegant solution but it solves my task.
Hope it will be helpful for someone.
DisabledTextField.java:
package com.kabunov.example.ui.common;
import android.content.Context;
import android.content.res.TypedArray;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.TextView;
import com.kabunov.example.R;
public final class DisabledTextField extends FrameLayout {
private TextView tvCaption;
private TextView tvText;
private View divider;
public DisabledTextField(final Context context) {
this(context, null);
}
public DisabledTextField(final Context context, final AttributeSet attrs) {
this(context, attrs, 0);
}
public DisabledTextField(final Context context, final AttributeSet attrs, final int defStyleAttr) {
super(context, attrs, defStyleAttr);
View.inflate(getContext(), R.layout.component_disabled_text_field, this);
tvCaption = (TextView) findViewById(R.id.caption);
tvText = (TextView) findViewById(R.id.value);
final TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.DisabledTextField);
if (null != typedArray) {
final String captionText = typedArray.getString(R.styleable.DisabledTextField_caption);
if (TextUtils.isEmpty(captionText)) {
tvCaption.setVisibility(GONE);
} else {
tvCaption.setText(captionText);
tvCaption.setVisibility(VISIBLE);
}
final String text = typedArray.getString(R.styleable.DisabledTextField_disabledText);
tvText.setText(text);
typedArray.recycle();
}
}
public final void setCaption(final CharSequence caption) {
this.tvCaption.setText(caption);
this.tvCaption.setVisibility(VISIBLE);
}
public final void setDisabledText(final CharSequence value) {
this.tvText.setText(value);
}
}
/layout/component_disabled_text.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">
<TextView
android:id="#+id/caption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="#style/DisabledTextFieldCaption"/>
<TextView
android:id="#+id/value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="#style/DisabledTextFieldValue"/>
<View
android:id="#+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#drawable/disabled_text_field_background"
android:layerType="software"/>
</LinearLayout>
/values/attributes_disabled_text_field.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="DisabledTextField">
<attr name="caption" format="string"/>
<attr name="disabledText" format="string"/>
</declare-styleable>
</resources>
/drawable/disabled_text_field_background.xml:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:bottom="-1dp"
android:left="-1dp"
android:right="-1dp"
android:top="0dp">
<shape android:shape="rectangle">
<stroke
android:width="1dp"
android:color="#color/text_color_disabled_text_view"
android:dashGap="2dp"
android:dashWidth="1dp" />
<solid android:color="#android:color/transparent" />
</shape>
</item>
</layer-list>
/values/styles.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="text_color_disabled_text_view">#61000000</color>
<style name="DisabledTextFieldCaption">
<item name="android:textSize">12sp</item>
<item name="android:textColor">#color/text_color_disabled_text_view</item>
</style>
<style name="DisabledTextFieldValue">
<item name="android:layout_marginTop">3dp</item>
<item name="android:layout_marginBottom">8dp</item>
<item name="android:textSize">16sp</item>
<item name="android:textColor">#color/text_color_disabled_text_view</item>
</style>
</resources>
Example of usage:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.kabunov.example.ui.common.DisabledTextField
android:id="#+id/example"
android:layout_width="match_parent"
android:layout_height="wrap_content"
custom:caption="Some caption"
custom:disabledText="Disabled text"/>
</LinearLayout>
And the result:

Unable to set Background in Imagebutton

Here i have a ImageButton:
<com.defcomdevs.invento16.SquareImageView
android:id="#+id/picture"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal|top"
android:background="#drawable/custom_button"
android:layout_margin="1dp"
android:scaleType="fitCenter" />
SquareImageView is a class that extends the Imagebutton to basically set the width and height automatically according to the Screen size.
custom_button.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false">
<shape android:shape="rectangle">
<stroke android:width="5dp" android:color="#885599"/>
</shape>
</item>
<item android:state_pressed="true">
<shape android:shape="rectangle">
<stroke android:width="8dp" android:color="#802196f3"/>
<gradient android:startColor="#802196f3" android:endColor="#802196f3"/>
</shape>
</item>
My Problem is that when i set the background as custom_button the image that i set programmatically overlaps the entire area of the button.not showing the background.Otherwise the image perfectly sets inside the button.
Some thing like this:
As you can see this is the case with background=custom_button.
this is the case otherwise.
Now i don't want any of these.
What i want is that the custom_button is set as the background of the ImageButton and the src as that image as shown.How to da that??Please help.Thanks.
SquareImageView.class:
package com.defcomdevs.invento16;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.Button;
import android.widget.ImageButton;
public class SquareImageView extends ImageButton {
public SquareImageView(Context context) {
super(context);
}
public SquareImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth()); //Snap to width
}
}

ListView Item Selected State not working

So I have a ListView and I want to change the color of each items background and text. This ListView is inside a ListFragment. My code inflates the layout in the onCreateView and inflates the layout of each item in the newView.
The android:state_pressed="true" is working fine, whenever I press in one item the background changes to that color. But when selecting an item neither the bg color or text color changes, even though I've defined an item with android:state_selected="true" in the selector.
Edit: I'm using SDK level 11 (Android 3.0) and a Motorola Xoom.
The list fragment layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
The list item 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:padding="25dp"
android:background="#drawable/list_item_bg_selector">
<TextView android:id="#+id/form_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="#dimen/text_size_xlarge"
android:textStyle="bold"
android:textColor="#drawable/list_item_text_selector" />
<TextView android:id="#+id/form_subtitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="#dimen/text_size_medium"
android:textStyle="normal"
android:layout_marginTop="5dp"
android:textColor="#drawable/list_item_text_selector" />
</LinearLayout>
The background selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true"
android:drawable="#color/white" />
<item
android:state_selected="true"
android:drawable="#drawable/list_item_bg_selected" />
<item
android:drawable="#color/list_bg" />
</selector>
The text selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_selected="true"
android:drawable="#color/white" />
<item
android:drawable="#color/list_text_blue" />
</selector>
The answer is to use the android:state_activated="true" state, instead of the "selected" state. More on this here: ListFragment Item Selected Background
The best solution with support of all API levels is to implement Checkable feature for list item View which means that the top view of your list item layout has to implement Checkable interface (in my case it was TextView, but the same can be applied on ViewGroup classes like LinearLayout). When you click on a list item, the ListView call setChecked method and there we change the state of View to use android:state_checked="true" selector. Together with list view android:choiceMode="singleChoice" it will select only one item.
The trick is to override onCreateDrawableState method and set the checked state here for drawables. See example of SelectableTextView bellow. After the setChecked is called, the checked state is stored and called refreshDrawableState.
Example of SelectableTextView:
package com.example.widget.SelectableTextView;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.Checkable;
import android.widget.TextView;
public class SelectableTextView extends TextView implements Checkable {
private static final int[] CHECKED_STATE_SET = {
android.R.attr.state_checked
};
private boolean mChecked;
public SelectableTextView(Context context) {
super(context);
}
public SelectableTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SelectableTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public SelectableTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
#Override
public void setChecked(boolean checked) {
if (mChecked != checked) {
mChecked = checked;
refreshDrawableState();
}
}
#Override
public boolean isChecked() {
return mChecked;
}
#Override
public void toggle() {
setSelected(!mChecked);
}
#Override
protected int[] onCreateDrawableState(int extraSpace) {
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
if (isChecked()) {
mergeDrawableStates(drawableState, CHECKED_STATE_SET);
}
return drawableState;
}
}
Example of selectable_list_item.xml layout:
<?xml version="1.0" encoding="utf-8"?>
<com.example.widget.SelectableTextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#android:id/text1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="#color/list_item_selector_foreground"
android:background="#drawable/list_item_selector_background"
tools:text="Item 1"/>
Example of list_item_selector_foreground.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- checked -->
<item android:color="#color/list_item_text_active" android:state_checked="true"/>
<item android:color="#color/list_item_text"/>
</selector>
Example of list_item_selector_background.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/list_item_background_selected" android:state_pressed="true"/>
<item android:drawable="#color/list_item_background_selected" android:state_focused="true"/>
<item android:drawable="#color/list_item_background_active" android:state_checked="true"/>
<item android:drawable="#color/list_item_background"/>
</selector>
Do not forget to set clickable="true" for the layout. This solved my problem.
List item layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/list_item_bg_selector"
android:clickable="true" >
<TextView
android:id="#+id/tvNewsPreviewTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="3"
android:ellipsize="end"
android:textSize="#dimen/news_preview_title_textsize"
android:textStyle="bold" />
</RelativeLayout>
Background selector:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" >
<shape android:shape="rectangle">
<stroke android:width="1dp" android:color="#color/black" />
<gradient android:startColor="#color/white" android:endColor="#color/white" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<stroke android:width="1dp" android:color="#color/holo_gray_darker" />
<gradient android:startColor="#color/holo_gray_bright" android:endColor="#color/holo_gray_bright" />
</shape>
</item>
</selector>
#Andrew S: Along with using activated state in selector , activated state must be set to false for default case as shown in below selector code.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false"
android:state_activated="false"
android:color="#color/dark_text_blue"/>
<item android:state_pressed="true"
android:color="#color/red"/>
<item android:state_activated="true"
android:color="#color/red"/>
</selector>

Android - set a ProgressBar to be a vertical bar instead of horizontal?

I am trying to use a ProgressBar as a metering like display. I thought it was going to be an easy task and thought that ProgressBar had a property to set to be vertical, but I'm not seeing anything.
Additionally I'd like to be able to show ruler like indicator along the side of the bar to clearly indicate the current level.
Pointers appreciated - Thanks!
I had recently come across the need for a vertical progress bar but was unable to find a solution using the existing Progress Bar widget. The solutions I came across generally required an extension of the current Progress Bar or a completely new class in it self. I wasn't convinced rolling out a new class to achieve a simple orientation change was necessary.
This article presents a simple, elegant, and most importantly, a no-hack solution to achieving a vertical progress bar.
I'm going to skip the explanation and simply provide a cookie cutter solution. If you require further details feel free to contact me or leave a comment below.
Create an xml in your drawable folder (not drawable-hdpi or drawable-mdpi -- place it in drawable). For this example I call my xml vertical_progress_bar.xml
Here's what to place in the xml file:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#android:id/background">
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ff9d9e9d"
android:centerColor="#ff5a5d5a"
android:centerY="0.75"
android:endColor="#ff747674"
android:angle="180"
/>
</shape>
</item>
<item android:id="#android:id/secondaryProgress">
<clip android:clipOrientation="vertical" android:gravity="bottom">
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#80ffd300"
android:centerColor="#80ffb600"
android:centerY="0.75"
android:endColor="#a0ffcb00"
android:angle="180"
/>
</shape>
</clip>
</item>
<item android:id="#android:id/progress">
<clip android:clipOrientation="vertical" android:gravity="bottom">
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ffffd300"
android:centerColor="#ffffb600"
android:centerY="0.75"
android:endColor="#ffffcb00"
android:angle="180"
/>
</shape>
</clip>
</item>
</layer-list>
Create an xml file called styles.xml and place it in res/values. If your project already contains styles.xml in res/values then skip this step.
Modify your styles.xml file and append the following code to the end of the file:
<style name="Widget">
</style>
<style name="Widget.ProgressBar">
<item name="android:indeterminateOnly">true</item>
<item name="android:indeterminateBehavior">repeat</item>
<item name="android:indeterminateDuration">3500</item>
<item name="android:minWidth">48dip</item>
<item name="android:maxWidth">48dip</item>
<item name="android:minHeight">48dip</item>
<item name="android:maxHeight">48dip</item>
</style>
<style name="Widget.ProgressBar.Vertical">
<item name="android:indeterminateOnly">false</item>
<item name="android:progressDrawable">#drawable/progress_bar_vertical</item>
<item name="android:indeterminateDrawable">#android:drawable/progress_indeterminate_horizontal</item>
<item name="android:minWidth">1dip</item>
<item name="android:maxWidth">12dip</item>
</style>
Add your new vertical progress bar to your layout. Here's an example:
<ProgressBar
android:id="#+id/vertical_progressbar"
android:layout_width="12dip"
android:layout_height="300dip"
style="#style/Widget.ProgressBar.Vertical"
/>
That should be all you need to do to make use of a vertical progress bar in your project. Optionally, you might have custom drawable nine-patch images that you are using for the progress bar. You should make the appropriate changes in the progress_bar_vertical.xml file.
I hope this helps you out in your project!
You have to create your own custom progressbar.
In your xml add this layout:
<com.example.component.VerticalProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:id="#+id/verticalRatingBar1"
android:layout_width="wrap_content"
android:progress="50"
android:layout_height="fill_parent" />
VerticalProgressBar.java
public class VerticalProgressBar extends ProgressBar{
private int x, y, z, w;
#Override
protected void drawableStateChanged() {
// TODO Auto-generated method stub
super.drawableStateChanged();
}
public VerticalProgressBar(Context context) {
super(context);
}
public VerticalProgressBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public VerticalProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(h, w, oldh, oldw);
this.x = w;
this.y = h;
this.z = oldw;
this.w = oldh;
}
#Override
protected synchronized void onMeasure(int widthMeasureSpec,
int heightMeasureSpec) {
super.onMeasure(heightMeasureSpec, widthMeasureSpec);
setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
}
protected void onDraw(Canvas c) {
c.rotate(-90);
c.translate(-getHeight(), 0);
super.onDraw(c);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (!isEnabled()) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
setSelected(true);
setPressed(true);
break;
case MotionEvent.ACTION_MOVE:
setProgress(getMax()
- (int) (getMax() * event.getY() / getHeight()));
onSizeChanged(getWidth(), getHeight(), 0, 0);
break;
case MotionEvent.ACTION_UP:
setSelected(false);
setPressed(false);
break;
case MotionEvent.ACTION_CANCEL:
break;
}
return true;
}
#Override
public synchronized void setProgress(int progress) {
if (progress >= 0)
super.setProgress(progress);
else
super.setProgress(0);
onSizeChanged(x, y, z, w);
}
}
Or :
Jagsaund solution is also being perfect.
I know that it´s an old post but I found a very simple solution to this problem that maybe can help somebody.
First at all create a progress_drawable_vertical.xml like this:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#android:id/background">
<color android:color="#777" />
</item>
<item android:id="#android:id/progress">
<clip
android:clipOrientation="vertical"
android:gravity="bottom">
<shape>
<gradient
android:startColor="#00FF00"
android:centerColor="#FFFF00"
android:endColor="#FF0000"
android:angle="90" />
</shape>
</clip>
</item>
</layer-list>
Then just use this in your progressBar:
<ProgressBar
android:id="#+id/progress_bar"
style="#android:style/Widget.ProgressBar.Horizontal"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:max="100"
android:progress="33"
android:progressDrawable="#drawable/progress_drawable_vertical" />
I also have created an progress_drawable_horizontal.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#android:id/background">
<color android:color="#777" />
</item>
<item android:id="#android:id/progress">
<clip
android:clipOrientation="horizontal"
android:gravity="left">
<shape>
<gradient
android:startColor="#00FF00"
android:centerColor="#FFFF00"
android:endColor="#FF0000" />
</shape>
</clip>
</item>
</layer-list>
with the objetive of mantain the same style defined in progress_drawable_vertical.xml
The key here is the correct use of android:clipOrientation and android:gravity.
I found this solution here and the core of the solution is similar to jagsaund but a little bit more simple.
I found the probably best(easiest & most versatile) solution:)
This is an old post, but it was so hard for me to find this so easy solution so I thought I should post it..
Just use a scale-drawable (or a 9-patch if you want), no need for ANY OTHER code.
Example:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#android:id/background" android:drawable="#color/transparent"/>
<item android:id="#android:id/progress">
<scale android:scaleGravity="bottom" android:scaleWidth="0%" android:scaleHeight="100%">
<shape >
<solid android:color="#color/blue"/>
<corners android:topRightRadius="1dp" android:topLeftRadius="1dp"/>
</shape>
</scale>
</item>
</layer-list>
And of course the normal code:
<ProgressBar
android:id="#+id/progress_bar"
style="#android:style/Widget.ProgressBar.Horizontal"
android:layout_width="24dp"
android:layout_height="match_parent"
android:max="1000"
android:progress="200"
android:progressDrawable="#drawable/progress_scale_drawable" />
Notice the scale-drawable's xml lines (the magic lines):
android:scaleGravity="bottom" //scale from 0 in y axis (default scales from center Y)
android:scaleWidth="0%" //don't scale width (according to 'progress')
android:scaleHeight="100%" //do scale the height of the drawable
This perfectly works
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#android:id/background">
<shape>
<gradient
android:startColor="#DDDDDD"
android:centerColor="#DDDDDD"
android:centerY="0.75"
android:endColor="#DDDDDD"
android:angle="270"
/>
</shape>
</item>
<item
android:id="#android:id/progress">
<clip
android:clipOrientation="vertical"
android:gravity="top">
<shape>
<gradient
android:angle="0"
android:startColor="#302367"
android:centerColor="#7A5667"
android:endColor="#C86D67"/>
</shape>
</clip>
</item>
</layer-list>
<ProgressBar
android:id="#+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="5dp"
android:layout_height="match_parent"`enter code here`
android:progressDrawable="#drawable/progress_dialog"/>
Creating the progress bar (I converted my code from c# to java so might not be 100% correct)
ProgressBar progBar = new ProgressBar(Context, null, Android.resource.attribute.progressDrawable);
progBar.progressDrawable = ContextCompat.getDrawable(Context, resource.drawable.vertical_progress_bar);
progBar.indeterminate = false;
vertical_progress_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#android:id/background">
<shape>
<solid android:color="#color/grey" />
<corners android:radius="20dip" />
</shape>
</item>
<item android:id="#android:id/progress">
<scale
android:drawable="#drawable/vertical_progress_bar_blue_progress"
android:scaleHeight="100%"
android:scaleGravity="bottom"/>
</item>
</layer-list>
vertical_progress_bar_blue_progress.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<corners
android:radius="20dip" />
<solid android:color="#color/ProgressBarFourth" />
</shape>
What's going to make your bar vertical is the scaleHeight and scaleGravity attributes in vertical_progress_bar.xml.
It ends up looking something like this:
Simple and Easy way:
Just add a view to a LinearLayout and scale it.
<LinearLayout
android:layout_width="4dp"
android:layout_height="300dp"
android:background="#color/md_green_50"
android:orientation="vertical">
<View
android:id="#+id/progressView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="top"
android:layout_weight="1"
android:background="#color/md_green_500"
android:scaleY="0.0" />
</LinearLayout>
Set View's pivotY to zero:
progressView.pivotY = 0F
Now you can fill the progress using scaleY between 0F and 1F:
progressView.scaleY = 0.3F
Bonus:
Animate progress using animate():
progressView.animate().scaleY(0.3F).start()
Here is a simple solution, just rotate your progress bar
android:rotation="270"
Add this to the xml code
android:rotation="90"
android:transformPivotX="0dp"
So this is how your Progress Bar xml should look
<ProgressBar
android:id="#+id/progressBar6"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:rotation="90"
android:transformPivotX="0dp"
tools:layout_editor_absoluteX="101dp"
tools:layout_editor_absoluteY="187dp" />
To utilize the ProgressBar and make it vertical, you would have to create your own custom View extending the ProgressBar view and override the onDraw() method. This will allow you to draw it in a reverse orientation. Take a look at the source code of the ProgressBar.onDraw() (located at the bottom of the link) for help on how to do this. Best case scenario, you'll just have to swap a few x and y variables.
I have the exact problem. Making a custom class (extending ProgressBar) will create code that are hard to maintain. Using a custom style will cause compatibility issue with different theme from new OS (e.g. lollipop)
Eventually, I just apply a rotation animation to an horizontal progress bar. Inspired by Pete.
Create the tag in your layout xml like normal horizontal progress bar.
Make sure that the size and position of the ProgressBar is what you want after rotation. (Perhaps setting negative margin will help). In my code I rotate the view from 0,0.
Use the method below to rotate and set new progress.
Code:
private void setProgress(final ProgressBar progressBar, int progress) {
progressBar.setWillNotDraw(true);
progressBar.setProgress(progress);
progressBar.setWillNotDraw(false);
progressBar.invalidate();
}
private void rotateView(final View v, float degree) {
Animation an = new RotateAnimation(0.0f, degree);
an.setDuration(0);
an.setRepeatCount(0);
an.setFillAfter(true); // keep rotation after animation
v.setAnimation(an);
}
Simple progrebar image view
example
viewHolder.proBarTrueImage.setMaximalValue(147);
viewHolder.proBarTrueImage.setLevel(45);
viewHolder.proBarTrueImage.setColorResource(R.color.corner_blue);
simple class
public class ProgressImageView extends ImageView {
private Context mContext;
private Paint paint;
private RectF rectf;
private int maximalValue = 1;
private int level = 0;
private int width;
private int height;
public ProgressImageView(Context context) {
super(context);
init(context, null, 0);
}
public ProgressImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public ProgressImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
private void init(Context context, AttributeSet attrs, int defStyleAttr){
mContext = context;
paint = new Paint();
rectf = new RectF();
paint.setColor(Color.GRAY);
paint.setStyle(Paint.Style.FILL);
};
#Override
protected void onDraw(Canvas canvas) {
float dif = (float) height / (float) maximalValue;
int newHeight = height - (int) (dif * level);
rectf.set(0,newHeight, width, height);
canvas.drawRect(rectf, paint);
super.onDraw(canvas);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
this.width = w;
this.height = h;
}
public void setMaximalValue(int maximalValue) {
this.maximalValue = maximalValue;
invalidate();
}
public void setLevel(int level) {
this.level = level;
invalidate();
}
public void setColorResource(int color) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
color = mContext.getResources().getColor(color,mContext.getTheme());
}else {
color = mContext.getResources().getColor(R.color.corner_blue);
}
setColor(color);
}
public void setColor(int color){
if (paint != null){
paint.setColor(color);
invalidate();
}
}
}
<ProgressBar
android:id="#+id/battery_pb"
android:rotation="270"
android:progress="100"
...
/>
Use android:rotation="270" to 100% be like bottom to top or android:rotation="90" to 100% be like top to bottom
enter link description here
**Check this link out, I was trying to use a similar thing and also you can use stepper for your requirement, few projects are available on Github about HOW TO USE STEPPER IN ANDROID STUDIO **
For making a vertical ProgressBar, The way that I solved it was first rotating it by 90 degrees, then scaling it with a value entered by hand.
scaleX = layout_height/layout_width
Here's an example of my attributes on the ProgressBar
android:layout_width="20dp"
android:layout_height="233dp"
android:rotation="-90"
android:scaleX="11.65"
This can be a little manual, but because they don't have a vertical progress bar by default, this was a pretty good workaround for me. The scaleX could be calculated automatically, but it would have to be after everything is drawn on the screen.
Vertical progress bars are not supported by default.

Categories

Resources