19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.shapes.RectShape; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.shapes.Shape; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 2432e59d59f4362b6115593ea5c5abfb940fdf04a9Maxim Bogatovimport android.view.accessibility.AccessibilityNodeInfo; 2599441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikas 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.R; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A RatingBar is an extension of SeekBar and ProgressBar that shows a rating in 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * stars. The user can touch/drag or use arrow keys to set the rating when using 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the default size RatingBar. The smaller RatingBar style ( 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.R.attr#ratingBarStyleSmall}) and the larger indicator-only 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * style ({@link android.R.attr#ratingBarStyleIndicator}) do not support user 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * interaction and should only be used as indicators. 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * When using a RatingBar that supports user interaction, placing widgets to the 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * left or right of the RatingBar is discouraged. 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The number of stars set (via {@link #setNumStars(int)} or in an XML layout) 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will be shown when the layout width is set to wrap content (if another layout 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * width is set, the results may be unpredictable). 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The secondary progress should not be modified by the client as it is used 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * internally as the background for a fractionally filled star. 455b07143e36096168fd95d8e27988b233b2a70eceRoboErik * 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#RatingBar_numStars 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#RatingBar_rating 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#RatingBar_stepSize 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#RatingBar_isIndicator 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class RatingBar extends AbsSeekBar { 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A callback that notifies clients when the rating has been changed. This 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * includes changes that were initiated by the user through a touch gesture 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or arrow key/trackball as well as changes that were initiated 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * programmatically. 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface OnRatingBarChangeListener { 605b07143e36096168fd95d8e27988b233b2a70eceRoboErik 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notification that the rating has changed. Clients can use the 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * fromUser parameter to distinguish user-initiated changes from those 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that occurred programmatically. This will not be called continuously 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * while the user is dragging, only when the user finalizes a rating by 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * lifting the touch. 675b07143e36096168fd95d8e27988b233b2a70eceRoboErik * 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param ratingBar The RatingBar whose rating has changed. 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rating The current rating. This will be in the range 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 0..numStars. 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param fromUser True if the rating change was initiated by a user's 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * touch gesture or arrow key/horizontal trackbell movement. 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser); 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mNumStars = 5; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mProgressOnStartTracking; 815b07143e36096168fd95d8e27988b233b2a70eceRoboErik 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnRatingBarChangeListener mOnRatingBarChangeListener; 835b07143e36096168fd95d8e27988b233b2a70eceRoboErik 84617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette public RatingBar(Context context, AttributeSet attrs, int defStyleAttr) { 85617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette this(context, attrs, defStyleAttr, 0); 86617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette } 87617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette 88617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette public RatingBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 89617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette super(context, attrs, defStyleAttr, defStyleRes); 90617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette 91617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette final TypedArray a = context.obtainStyledAttributes( 92617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette attrs, R.styleable.RatingBar, defStyleAttr, defStyleRes); 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numStars = a.getInt(R.styleable.RatingBar_numStars, mNumStars); 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setIsIndicator(a.getBoolean(R.styleable.RatingBar_isIndicator, !mIsUserSeekable)); 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float rating = a.getFloat(R.styleable.RatingBar_rating, -1); 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float stepSize = a.getFloat(R.styleable.RatingBar_stepSize, -1); 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (numStars > 0 && numStars != mNumStars) { 1005b07143e36096168fd95d8e27988b233b2a70eceRoboErik setNumStars(numStars); 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1025b07143e36096168fd95d8e27988b233b2a70eceRoboErik 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (stepSize >= 0) { 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setStepSize(stepSize); 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setStepSize(0.5f); 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1085b07143e36096168fd95d8e27988b233b2a70eceRoboErik 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rating >= 0) { 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setRating(rating); 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1125b07143e36096168fd95d8e27988b233b2a70eceRoboErik 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // A touch inside a star fill up to that fractional area (slightly more 1141d33c3f3a379440f8f797c296490b07107bfe9e5Alan Viverette // than 0.5 so boundaries round up). 1151d33c3f3a379440f8f797c296490b07107bfe9e5Alan Viverette mTouchProgressOffset = 0.6f; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public RatingBar(Context context, AttributeSet attrs) { 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, attrs, com.android.internal.R.attr.ratingBarStyle); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public RatingBar(Context context) { 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, null); 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1255b07143e36096168fd95d8e27988b233b2a70eceRoboErik 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the listener to be called when the rating changes. 1285b07143e36096168fd95d8e27988b233b2a70eceRoboErik * 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param listener The listener. 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setOnRatingBarChangeListener(OnRatingBarChangeListener listener) { 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnRatingBarChangeListener = listener; 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1345b07143e36096168fd95d8e27988b233b2a70eceRoboErik 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The listener (may be null) that is listening for rating change 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * events. 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public OnRatingBarChangeListener getOnRatingBarChangeListener() { 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mOnRatingBarChangeListener; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Whether this rating bar should only be an indicator (thus non-changeable 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the user). 1465b07143e36096168fd95d8e27988b233b2a70eceRoboErik * 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param isIndicator Whether it should be an indicator. 148aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne * 149aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne * @attr ref android.R.styleable#RatingBar_isIndicator 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setIsIndicator(boolean isIndicator) { 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsUserSeekable = !isIndicator; 1534c8c963eced8e145ecf314a41c8396c7df8e0a39Evan Rosky if (isIndicator) { 1544c8c963eced8e145ecf314a41c8396c7df8e0a39Evan Rosky setFocusable(FOCUSABLE_AUTO); 1554c8c963eced8e145ecf314a41c8396c7df8e0a39Evan Rosky } else { 1564c8c963eced8e145ecf314a41c8396c7df8e0a39Evan Rosky setFocusable(FOCUSABLE); 1574c8c963eced8e145ecf314a41c8396c7df8e0a39Evan Rosky } 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1595b07143e36096168fd95d8e27988b233b2a70eceRoboErik 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Whether this rating bar is only an indicator. 162aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne * 163aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne * @attr ref android.R.styleable#RatingBar_isIndicator 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isIndicator() { 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return !mIsUserSeekable; 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1685b07143e36096168fd95d8e27988b233b2a70eceRoboErik 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the number of stars to show. In order for these to be shown 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * properly, it is recommended the layout width of this widget be wrap 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * content. 1735b07143e36096168fd95d8e27988b233b2a70eceRoboErik * 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param numStars The number of stars. 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setNumStars(final int numStars) { 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (numStars <= 0) { 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1805b07143e36096168fd95d8e27988b233b2a70eceRoboErik 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumStars = numStars; 1825b07143e36096168fd95d8e27988b233b2a70eceRoboErik 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This causes the width to change, so re-layout 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayout(); 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the number of stars shown. 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The number of stars shown. 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getNumStars() { 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mNumStars; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1945b07143e36096168fd95d8e27988b233b2a70eceRoboErik 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the rating (the number of stars filled). 1975b07143e36096168fd95d8e27988b233b2a70eceRoboErik * 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rating The rating to set. 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setRating(float rating) { 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setProgress(Math.round(rating * getProgressPerStar())); 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Gets the current rating (number of stars filled). 2065b07143e36096168fd95d8e27988b233b2a70eceRoboErik * 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The current rating. 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public float getRating() { 2105b07143e36096168fd95d8e27988b233b2a70eceRoboErik return getProgress() / getProgressPerStar(); 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the step size (granularity) of this rating bar. 2155b07143e36096168fd95d8e27988b233b2a70eceRoboErik * 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param stepSize The step size of this rating bar. For example, if 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * half-star granularity is wanted, this would be 0.5. 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setStepSize(float stepSize) { 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (stepSize <= 0) { 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2235b07143e36096168fd95d8e27988b233b2a70eceRoboErik 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float newMax = mNumStars / stepSize; 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newProgress = (int) (newMax / getMax() * getProgress()); 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setMax((int) newMax); 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setProgress(newProgress); 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Gets the step size of this rating bar. 2325b07143e36096168fd95d8e27988b233b2a70eceRoboErik * 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The step size. 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public float getStepSize() { 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (float) getNumStars() / getMax(); 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2385b07143e36096168fd95d8e27988b233b2a70eceRoboErik 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The amount of progress that fits into a star 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float getProgressPerStar() { 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNumStars > 0) { 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1f * getMax() / mNumStars; 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1; 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Shape getDrawableShape() { 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: Once ProgressBar's TODOs are fixed, this won't be needed 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new RectShape(); 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2575b07143e36096168fd95d8e27988b233b2a70eceRoboErik void onProgressRefresh(float scale, boolean fromUser, int progress) { 2585b07143e36096168fd95d8e27988b233b2a70eceRoboErik super.onProgressRefresh(scale, fromUser, progress); 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Keep secondary progress in sync with primary 2615b07143e36096168fd95d8e27988b233b2a70eceRoboErik updateSecondaryProgress(progress); 2625b07143e36096168fd95d8e27988b233b2a70eceRoboErik 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!fromUser) { 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Callback for non-user rating changes 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dispatchRatingChange(false); 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The secondary progress is used to differentiate the background of a 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * partially filled star. This method keeps the secondary progress in sync 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * with the progress. 2735b07143e36096168fd95d8e27988b233b2a70eceRoboErik * 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param progress The primary progress level. 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void updateSecondaryProgress(int progress) { 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float ratio = getProgressPerStar(); 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ratio > 0) { 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float progressInStars = progress / ratio; 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int secondaryProgress = (int) (Math.ceil(progressInStars) * ratio); 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setSecondaryProgress(secondaryProgress); 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2845b07143e36096168fd95d8e27988b233b2a70eceRoboErik 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onMeasure(widthMeasureSpec, heightMeasureSpec); 2885b07143e36096168fd95d8e27988b233b2a70eceRoboErik 2890d2a46b7336b6d255f202b878003be59ecbae52bAlan Viverette if (mSampleWidth > 0) { 2900d2a46b7336b6d255f202b878003be59ecbae52bAlan Viverette final int width = mSampleWidth * mNumStars; 291189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn setMeasuredDimension(resolveSizeAndState(width, widthMeasureSpec, 0), 292189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn getMeasuredHeight()); 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onStartTrackingTouch() { 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProgressOnStartTracking = getProgress(); 2995b07143e36096168fd95d8e27988b233b2a70eceRoboErik 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onStartTrackingTouch(); 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onStopTrackingTouch() { 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onStopTrackingTouch(); 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (getProgress() != mProgressOnStartTracking) { 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dispatchRatingChange(true); 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 311105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 312105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project @Override 313105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project void onKeyChange() { 314105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project super.onKeyChange(); 315105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project dispatchRatingChange(true); 316105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 317105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void dispatchRatingChange(boolean fromUser) { 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnRatingBarChangeListener != null) { 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnRatingBarChangeListener.onRatingChanged(this, getRating(), 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fromUser); 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public synchronized void setMax(int max) { 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Disallow max progress = 0 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (max <= 0) { 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3315b07143e36096168fd95d8e27988b233b2a70eceRoboErik 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.setMax(max); 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3348a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov 3358a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov @Override 336a7bb6fbeab933326d58aa806d8194b7b13239d34Dianne Hackborn public CharSequence getAccessibilityClassName() { 337a7bb6fbeab933326d58aa806d8194b7b13239d34Dianne Hackborn return RatingBar.class.getName(); 3388a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov } 33932e59d59f4362b6115593ea5c5abfb940fdf04a9Maxim Bogatov 34032e59d59f4362b6115593ea5c5abfb940fdf04a9Maxim Bogatov /** @hide */ 34132e59d59f4362b6115593ea5c5abfb940fdf04a9Maxim Bogatov @Override 34232e59d59f4362b6115593ea5c5abfb940fdf04a9Maxim Bogatov public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) { 34332e59d59f4362b6115593ea5c5abfb940fdf04a9Maxim Bogatov super.onInitializeAccessibilityNodeInfoInternal(info); 34432e59d59f4362b6115593ea5c5abfb940fdf04a9Maxim Bogatov 34532e59d59f4362b6115593ea5c5abfb940fdf04a9Maxim Bogatov if (canUserSetProgress()) { 34632e59d59f4362b6115593ea5c5abfb940fdf04a9Maxim Bogatov info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SET_PROGRESS); 34732e59d59f4362b6115593ea5c5abfb940fdf04a9Maxim Bogatov } 34832e59d59f4362b6115593ea5c5abfb940fdf04a9Maxim Bogatov } 34932e59d59f4362b6115593ea5c5abfb940fdf04a9Maxim Bogatov 35032e59d59f4362b6115593ea5c5abfb940fdf04a9Maxim Bogatov @Override 35132e59d59f4362b6115593ea5c5abfb940fdf04a9Maxim Bogatov boolean canUserSetProgress() { 35232e59d59f4362b6115593ea5c5abfb940fdf04a9Maxim Bogatov return super.canUserSetProgress() && !isIndicator(); 35332e59d59f4362b6115593ea5c5abfb940fdf04a9Maxim Bogatov } 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 355