I am having a bit of a problem when setting a custom rating bar in android. I have followed this tutorial:
How to create Custom Ratings bar in Android
However I am experiencing an issue when changing/selecting more than 4 stars. The selected star image is misplaced a bit. Here is an image to show you what it looks like.
Here is my XML for creating the custom rating bar.
Main xml where the rating bar view is defined:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:gravity="center" >
<RatingBar
android:id="#+id/ratingBar"
android:layout_width="wrap_content"
android:layout_height="19dp"
android:numStars="50"
android:stepSize="1.0"
style="#style/AppCustomRatingBar"/>
Custom style for the RatingBar
<style name="AppCustomRatingBar"
parent="#android:style/Widget.RatingBar">
<item name="android:progressDrawable">#drawable/rating_stars_custom</item>
<item name="android:minHeight">19dp</item>
<item name="android:maxHeight">19dp</item>
</style>
rating_stars_custom.xml
<item
android:id="#android:id/background"
android:drawable="#drawable/rating_stars_yellow_empty" />
<item android:id="#android:id/secondaryProgress"
android:drawable="#drawable/rating_stars_yellow_empty" />
<item
android:id="#android:id/progress"
android:drawable="#drawable/rating_stars_yellow_full" />
rating_stars_yellow_empty.xml
<?xml version="1.0" encoding="utf-8"?>
<item
android:id="#android:id/background"
android:drawable="#drawable/rating_stars_yellow_empty" />
<item android:id="#android:id/secondaryProgress"
android:drawable="#drawable/rating_stars_yellow_empty" />
<item
android:id="#android:id/progress"
android:drawable="#drawable/rating_stars_yellow_full" />
rating_stars_yellow_full.xml
<item android:state_pressed="true"
android:state_window_focused="true"
android:drawable="#drawable/home_icon_star_fill_selected" />
<item android:state_focused="true"
android:state_window_focused="true"
android:drawable="#drawable/home_icon_star_fill_selected" />
<item android:state_selected="true"
android:state_window_focused="true"
android:drawable="#drawable/home_icon_star_fill_selected" />
<item android:drawable="#drawable/home_icon_star_fill_selected" />
What am I doing wrong to misplace the stars? The image sizes of the stars (both yellow and white) are the same.
I managed to fix it. If you look at the picture I provided in my post above the yellow stars are like off with 1pix compared to empty stars. So I took a look at my pictures I use and their sizes. After that it appeared that the yellow star was 1pix shorter (in width) compared to the image with the empty star. So this was my problem I got new pictures of stars and I made sure they are the same size. Now I have 2 pictures 30x30 and all is OK! This fixed my problem! So my advice for people who are facing the same issue is to take a vary careful look at the size of the pictures they are using (empty/full) and make sure they are the same size. This way you save time and unnecessary coding. GL&HF :)
well I had the same problem with the rating bar. after doing some research I've found a way to overcome the above issue.
first, you need 2 stars, one empty star and one colored star. and size should be the same. (in my case both are 25x25)
then put this code in styles xml
<style name="redbar" parent="#android:style/Widget.RatingBar">
<item name="android:progressDrawable">#drawable/ratingbar_red</item>
<item name="android:minHeight">25dip</item>
<item name="android:maxHeight">25dip</item>
</style>
create another xml file called ratingbar_red.xml inside the drawable folder.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#+android:id/background"
android:drawable="#drawable/star_empty" />
<item android:id="#+android:id/secondaryProgress"
android:drawable="#drawable/star_empty" />
<item android:id="#+android:id/progress"
android:drawable="#drawable/star" />
</layer-list>
Finally crate your RatingBar like this.
<RatingBar
android:id="#+id/RatingBar05"
style="#style/redbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:isIndicator="false"
android:numStars="5"/>
this error || problem is actually related to the sizes of your images, Both have to be in the same size, the way I fixed this err is that I didn't remove the stoke or the border of the filled image, both images must have the same width and height
Related
So I have created a rating bar with new icons, however, when I implement it, the stars look like they are bleeding, see attached:
Here are the style, rating xml, and how they are implemented in the layout:
style:
<style name="GoldRatingBar" parent="#android:style/Widget.RatingBar">
<item name="android:indeterminateOnly">false</item>
<item name="android:progressDrawable">#drawable/gold_ratingbar</item>
<item name="android:indeterminateDrawable">#drawable/gold_ratingbar</item>
<item name="android:thumb">#null</item>
<item name="android:isIndicator">true</item>
</style>
rating 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" android:drawable="#drawable/rating_star_icon_off" />
<item android:id="#+android:id/secondaryProgress" android:drawable="#drawable/rating_star_icon_half" />
<item android:id="#+android:id/progress" android:drawable="#drawable/rating_star_icon" />
</layer-list>
Layout:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="Overall rating"
android:textSize="16sp"
android:textStyle="bold" />
<RatingBar
android:id="#+id/review_overall_rating"
style="#style/GoldRatingBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="6dp"
android:layout_marginLeft="6dp"
android:rating="3" />
<TextView
android:id="#+id/review_rating_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text=""
android:textStyle="bold" />
Can anyone see where I have gone wrong?
i had a similar case
and the accepted answer will not resolve it on all screen sizes
in fact the solution is very simple,
you just need to add padding to the .png image that you are using
"2 transparent pixels on each side "
the bleeding ocures because android is repeating the last row of your star image so just make this row transparent
For all who are still looking for an answer and don't want to crop the image: android:minHeight="0dp" helped me
Update.
Why is it working? Well, most of all view components have a default min size to follow accessibility/usability google guidelines. And as was mentioned, seems like RatingBar tries to fill the empty space (diff between your own resource and minHeight) by repeating the last 1-2 pixels (personally I don't understand the reason of such desicion). So by setting the android:minHeight="0dp", RatingBar will wrap content by the height of your resource.
I had facing same problem.
In my case blank_star.png height is 17dp so i put android:layout_height="17dp" on RatingBar and my problem is resolve.Try below code:-
<RatingBar
android:id="#+id/rating"
style="#style/rating_bar"
android:layout_width="wrap_content"
android:layout_height="17dp"
android:layout_marginRight="5dp"
android:isIndicator="true"
android:numStars="5"
android:stepSize="1.0" />
style/rating_bar.xml
<style name="rating_bar" parent="#android:style/Widget.RatingBar">
<item name="android:progressDrawable">#drawable/rating_bar_full</item>
<item name="android:minHeight">18dip</item>
<item name="android:maxHeight">18dip</item>
</style>
drawable/rating_bar_full
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+android:id/background"
android:drawable="#drawable/ratingbar_full_empty"/>
<item
android:id="#+android:id/secondaryProgress"
android:drawable="#drawable/ratingbar_full_empty"/>
<item
android:id="#+android:id/progress"
android:drawable="#drawable/ratingbar_full_filled"/>
</layer-list>
drawable/ratingbar_full_empty
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/blank_star" android:state_pressed="true" android:state_window_focused="true"/>
<item android:drawable="#drawable/blank_star" android:state_focused="true" android:state_window_focused="true"/>
<item android:drawable="#drawable/blank_star" android:state_selected="true" android:state_window_focused="true"/>
<item android:drawable="#drawable/blank_star"/>
</selector>
drawable/ratingbar_full_filled.xml
<item android:drawable="#drawable/filled_star" android:state_pressed="true" android:state_window_focused="true"/>
<item android:drawable="#drawable/filled_star" android:state_focused="true" android:state_window_focused="true"/>
<item android:drawable="#drawable/filled_star" android:state_selected="true" android:state_window_focused="true"/>
<item android:drawable="#drawable/filled_star"/>
The bleeding occurs because the last row of your star image is being repeated. You could fix this by setting the size of the RatingBar to perfectly match the underlying drawable.
The RatingBar never inspects the size of the underlying drawable. So you have to do this yourself. It can be difficult to do this using xml, since your assets may have different sizes for different screen densities. Plus your UX people may change the assets without updating the xml dimensions.
Solution: create a RatingBar that checks the size of its drawables. See below
public class RatingBar extends android.widget.RatingBar {
private Drawable starDrawable;
public RatingBar(Context context) {
this(context, null);
}
public RatingBar(Context context, AttributeSet attrs) {
super(context, attrs);
starDrawable = getResources().getDrawable(
R.drawable.your_drawable, context.getTheme());
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Make sure to account for padding and margin, if you care.
// I only cared about left padding.
setMeasuredDimension(starDrawable.getIntrinsicWidth() * 5
+ getPaddingLeft(), starDrawable.getIntrinsicHeight());
}
}
I have the following style in my styles.xml that a toggle button is using. However, i want the toggle button to fill_parent but not stretch the image. How can i tell it to center this background image and not stretch it? I'm trying to increase the area the user can click on.
Toggle:
<ToggleButton
android:id="#+id/OtherToggle"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
style="#style/OtherToggle" />
Style:
<style name="OtherToggle">
<item name="android:textOn">""</item>
<item name="android:textOff">""</item>
<item name="android:disabledAlpha">?android:attr/disabledAlpha</item>
<item name="android:background">#drawable/other_toggle_bg</item>
</style>
I assume you mean that you do want to stretch the image, but you want to keep the aspect ratio unchanged?
If so, try adding this to your style:
<item name="android:scaleType">centerInside</item>
See here for the other possibilities if centerInside does not do what you want.
Maybe you can use layer-list as a background drawable for ToggleButton? Create the following xml file and use it in android:background attribute:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+android:id/background"
android:drawable="#android:color/transparent" />
<item>
<bitmap android:src="#drawable/other_toggle_bg"
android:gravity="center" />
</item>
</layer-list>
I'm trying to create a custom RatingBar for one of my apps. I've followed this tutorial: http://kozyr.zydako.net/2010/05/23/pretty-ratingbar/
The problem is that my RatingBar has always the same size and it's always filled. I try to show different ratings (0,1,2,3,4...) but the rating bar it's the same in all the cases...
I have the ratingBar:
<RatingBar
android:id="#+id/ratingBar"
style="#style/MyRatingBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:layout_marginRight="20dp"/>
My Style:
<style name="MyRatingBar" parent="#android:style/Widget.RatingBar">
<item name="android:progressDrawable">#drawable/rating_list</item>
<item name="android:minHeight">57dip</item>
<item name="android:maxHeight">57dip</item>
</style>
The layer-list:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#android:id/background"
android:drawable="#color/white_text" />
<item android:id="#android:id/secondaryProgress"
android:drawable="#color/white_text" />
<item android:id="#android:id/progress"
android:drawable="#color/red_circle" />
Thank you.
In your <RatingBar> use:
android:numStars to define how many red_circle are used for the full scale of the bar.
android:rating to set the default rating level.
android:stepSize to define the step size of your RatingBar.
<Edit>
I don't believe RatingBar is designed to work using a straight fill color as the progress drawable, which is what you have currently. A color has no dimensions, so drawing 2, 3 or 4 of them has no meaning.
It is designed to work with an image file like the default star png files.
Change your layer-list so the progress drawable points to a Bitmap, or 9Patch, and it works fine. <RatingBar> extends ProgressBar, which uses 9Patchs for the progress drawable.
I'm trying to give a custom background to my spinner. I've downloaded the HTC sense spinner design (Cf. following pictures) with the 9 patch format.
I've created a new XML file with the following code inside:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_focused="true"
android:state_pressed="false"
android:drawable="#drawable/spinner_pressed" />
<item
android:state_focused="true"
android:state_pressed="true"
android:drawable="#drawable/spinner_pressed" />
<item
android:state_focused="false"
android:state_pressed="true"
android:drawable="#drawable/spinner_pressed" />
<item
android:drawable="#drawable/spinner_normal" />
</selector>
And I've added a spinner to my layout with this code:
<Spinner
android:id="#+id/my_spinner"
android:layout_width="180dp"
android:layout_height="50dp"
android:layout_marginLeft="20dp"
android:background="#drawable/custom_spinner" />
But whereas being correctly displayed, I got the following format:
Did I make something wrong?
I hope you'll can help me.
Regards.
V.
The stretchable areas defined on your 9-patch seem wrong, and that is why your 9-patch are stretched like this. Have a look at Nine-patch docs and notice that the left-border defines what area should be stretched. I think you should also define a stretchable area below the "arrow" if you want the "arrow" to be centered.
If you do not know how to edit 9-patch you should use draw9patch it is included in the AndroidSDK/tools.
I have a 30px x 30px png file that i would like to use as an android:src rather than an android:background. By using it as the background, and mentioning "wrap_content" for both the height and the width, the final result looks more like a 45px x 45 px.
Ideally, what i need is a mix of ImageButton and ToggleButton. I would like to have the feature of setting an android:src of ImageButton and the feature of toggling where states are saved automatically for me.
Any solution or workaround?
TIA.
Hi, It does not seem to help creating another style. The src still appears much bigger that it's original 30px x 30px.
In main.xml:
<ToggleButton android:id="#+id/blah"
style="#style/myToggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ToggleButton>
In Styles.xml
<style name="myToggle">
<item name="android:textOn">""</item>
<item name="android:textOff">""</item>
<item name="android:disabledAlpha">?android:attr/disabledAlpha</item>
<item name="android:background">#drawable/my_btn_toggle_bg</item>
</style>
In my_btn_toggle_bg.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/myBackground" android:drawable="#android:drawable/btn_default_small" />
<item android:id="#+id/myToggle" android:drawable="#drawable/my_btn_toggle" />
</layer-list>
In my_btn_toggle.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="false" android:drawable="#drawable/pausebutton" />
<item android:state_checked="true" android:drawable="#drawable/playbutton" />
</selector>
playbutton.png and pausebutton.png are 30px x 30px each. But they appear much bigger when i see it laid out on the device
You can make the toggle button look like whatever you want. You just need to create a style. Have a look in the /platforms//data/res/values/styles.xml and search for Widget.Button.ToggleButton It looks like this:
<style name="Widget.Button.Toggle">
<item name="android:background">#android:drawable/btn_toggle_bg</item>
<item name="android:textOn">#android:string/capital_on</item>
<item name="android:textOff">#android:string/capital_off</item>
<item name="android:disabledAlpha">?android:attr/disabledAlpha</item>
</style>
So if you go find the btn_toggle_bg drawable you find this:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+android:id/background" android:drawable="#android:drawable/btn_default_small" />
<item android:id="#+android:id/toggle" android:drawable="#android:drawable/btn_toggle" />
</layer-list>
Which shows you that it uses the standard Button background and a drawable called btn_toggle for the src. btn_src.xml looks like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="false" android:drawable="#drawable/btn_toggle_off" />
<item android:state_checked="true" android:drawable="#drawable/btn_toggle_on" />
</selector>
Which are the two drawables that are used to show the state of the button. They are actually called btn_toggle_{on/off}.9.png since they are 9 Patch images so they stretch to match the button size.
I figured out how to do this (centering a smaller background image inside a large ToggleButton) using ScaleDrawable:
Set your ToggleButton to use a selector Drawable, as normal:
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:variablePadding="true">
<item android:drawable="#drawable/ic_star_selected_centered"
android:state_checked="true" />
<item android:drawable="#drawable/ic_star_default_white_centered"
android:state_pressed="true" />
<item android:drawable="#drawable/ic_star_default_black_centered" />
</selector>
Then, make a ScaledDrawable for each of the items' drawables above, which points to your ACTUAL image file. e.g. ic_star_selected_centered.xml:
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="#drawable/ic_star_selected"
android:scaleGravity="center"
android:scaleHeight="100%"
android:scaleWidth="100%"
/>
Finally, there is a bug in Android that makes any ScaledDrawables invisible at first, until you set their level. So when inflating your view, call setLevel() from 1-10000 (1 is smallest scale, 10000 is full-sized):
StateListDrawable star = (StateListDrawable) myToggleButton.getBackground();
star.setLevel(5000); // centers the image at half size. shame on Android for using magic numbers!
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true">
<inset android:insetLeft="15dp" android:insetRight="15dp" android:insetTop="15dp" android:insetBottom="15dp">
<bitmap android:src="#drawable/ic_star_selected_centered" />
</inset>
</item>
<item android:state_pressed="true" >
<inset android:insetLeft="15dp" android:insetRight="15dp" android:insetTop="15dp" android:insetBottom="15dp">
<bitmap android:src=" android:src="#drawable/ic_star_default_white_centered" />
</inset>
</item>
<item >
<inset android:insetLeft="15dp" android:insetRight="15dp" android:insetTop="15dp" android:insetBottom="15dp">
<bitmap android:src="#drawable/ic_star_default_black_centered" />
</inset>
</item>
</selector>
In addition to what #caseyB had to say (look at the comments), i had to change the theme of the activity to achieve the intended effect. I think this is an issue on HoneyComb Xoom and may not be seen on phones.
Thanks for everyone for looking at my question and helping.
"Quick and dirty" way of achieving this is to use relative layout and place your ImageView on top of the ToggleButton. Set android:layout_centerInParent="true" and set your onClick listener on the toggle
Said that - the other solution by CaseyB (customizing background files) is the right approach