setNumStars and setRating does not work in custom RatingBar - java

I have a problem with seting a custom ratingBar in Java. The problem is that setNumStars and setRating are not working. I just get one star on the screen which is fully marked although I've set the rate to 0.0f.
Here's the code:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
chapter1 = new Chapter(this);
android.widget.RelativeLayout.LayoutParams layoutParam = new RelativeLayout.LayoutParams(metrics.widthPixels , metrics.heightPixels);
myLayout.addView(chapter1, layoutParam);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
RatingBar ratingBar = new RatingBar(this);
ratingBar.setProgressDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.custom_ratingbar_menu, null));
ratingBar.setNumStars(3);
ratingBar.setRating(0.0f);
layoutParam = new RelativeLayout.LayoutParams(metrics.widthPixels / 6 , metrics.heightPixels / 32);
layoutParam.setMargins(70 + chapter1.getLeft() + wSize * j, 50 + chapter1.getTop() + hSize * i + (metrics.heightPixels / 6), 0, 0);
myLayout.addView(ratingBar, layoutParam);
}
}
And we have used the accepted answer in How to create Custom Ratings bar in Android for custom_ratingarbar_menu
Here's custom_ratingbar_menu :
<?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/customm_empty_menu" />
<item android:id="#android:id/secondaryProgress"
android:drawable="#drawable/customm_empty_menu" />
<item android:id="#android:id/progress"
android:drawable="#drawable/custom_full_menu" />
</layer-list>
And it's customm_empty_menu :
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:state_window_focused="true"
android:drawable="#drawable/stars_off_menu" />
<item android:state_focused="true"
android:state_window_focused="true"
android:drawable="#drawable/stars_off_menu" />
<item android:state_selected="true"
android:state_window_focused="true"
android:drawable="#drawable/stars_off_menu" />
<item android:drawable="#drawable/stars_off_menu" />
</selector>
And this is custom_full_menu :
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:state_window_focused="true"
android:drawable="#drawable/stars_on_menu" />
<item android:state_focused="true"
android:state_window_focused="true"
android:drawable="#drawable/stars_on_menu" />
<item android:state_selected="true"
android:state_window_focused="true"
android:drawable="#drawable/stars_on_menu" />
<item android:drawable="#drawable/stars_on_menu" />
</selector>

Edit
There is some problem with setting the progress drawable in code. Your drawables work when used in XML. The problem seems to revolve around setting the appropriate attributes. If I get time, I can look into this further or maybe someone else has an idea. (Check your XML, there is a typo: "customm" instead of "custom". I have corrected it below.)
(For API level 21 and above, you could do the following:
In MainActivity.java:
RatingBar ratingBar = new RatingBar(this, null, 0, R.style.myRatingBar);
In styles.xml:
<style name="myRatingBar" parent="#android:style/Widget.RatingBar">
<item name="android:progressDrawable">#drawable/custom_ratingbar_menu</item>
</style>
But this is not a general solution, so I prefer the following.)
In the meantime, you can accomplish what you want by inflating a RatingBar from XML and adding it to your layout instead of doing new RatingBar(this). In this way, you can make use of the attributes in the XML file. This fixes your issue.
Define an XML layout file that contains just a rating bar as follows:
rating_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<RatingBar xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/modelRatingBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:progressDrawable="#drawable/custom_ratingbar_menu" />
The drawable files are much as you defined them. I use a different icon since I did not have access to yours:
custom_ratingbar_menu.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/custom_empty_menu" />
<item
android:id="#android:id/secondaryProgress"
android:drawable="#drawable/custom_empty_menu" />
<item
android:id="#android:id/progress"
android:drawable="#drawable/custom_full_menu">
</item>
</layer-list>
custom_empty_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:state_window_focused="true"
android:drawable="#android:drawable/star_off" />
<item android:state_focused="true"
android:state_window_focused="true"
android:drawable="#android:drawable/star_off" />
<item android:state_selected="true"
android:state_window_focused="true"
android:drawable="#android:drawable/star_off" />
<item android:drawable="#android:drawable/star_off" />
</selector>
custom_full_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:state_window_focused="true"
android:drawable="#android:drawable/star_on" />
<item android:state_focused="true"
android:state_window_focused="true"
android:drawable="#android:drawable/star_on" />
<item android:state_selected="true"
android:state_window_focused="true"
android:drawable="#android:drawable/star_on" />
<item android:drawable="#android:drawable/star_on" />
</selector>
Finally, the main activity's onCreate():
MainActivity#onCreate
#Override
protected void onCreate(Bundle savedInstanceState) {
RelativeLayout myLayout = new RelativeLayout(this);
super.onCreate(savedInstanceState);
setContentView(myLayout);
// Your loop would go here...
RatingBar ratingBar = (RatingBar) getLayoutInflater()
.inflate(R.layout.rating_bar, myLayout, false);
myLayout.addView(ratingBar);
ratingBar.setNumStars(5);
ratingBar.setStepSize(0.5f);
ratingBar.setRating(2.0f);
}
Old answer, but still holds.
From the documentation for RatingBar:
The number of stars set (via setNumStars(int) or in an XML layout) will be shown when the layout width is set to wrap_content (if another layout width is set, the results may be unpredictable).
You are doing the following. (The width and height are not wrap_content.)
layoutParam = new RelativeLayout.LayoutParams(metrics.widthPixels / 6 , metrics.heightPixels / 32);
myLayout.addView(ratingBar, layoutParam);
Doing the following, instead, may get you what you want, or at least, get you the number of stars you want.
layoutParam = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
myLayout.addView(ratingBar, layoutParam);
I suggest that you forego the progress drawable for the time being and get the number of stars and rating right then introduce the drawable.
If this doesn't work, can you post custom_ratingbar_menu?

Related

Move bitmap items in layer-list programmatically

I would need move-change position of individual bitmap items in layer-list such as this:
background.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient
android:centerX="0.5"
android:centerY="0.3"
android:endColor="#color/colorBackgroundEnd"
android:gradientRadius="300dp"
android:startColor="#color/colorBackgroundStart"
android:type="radial" />
</shape>
</item>
<item
android:id="#+id/peas"
android:left="35dp"
android:top="110dp"
>
<bitmap
android:gravity="left|start|top"
android:src="#drawable/peas"
/>
</item>
<item
android:id="#+id/orange"
android:right="-35dp"
android:bottom="110dp">
<bitmap
android:gravity="right|end|bottom"
android:src="#drawable/orange" />
</item>
<item
android:id="#+id/salad"
android:bottom="-40dp"
android:left="-40dp">
<bitmap
android:gravity="left|start|bottom"
android:src="#drawable/salad"/>
</item>
I was able to reference items in java code:
layerDrawable = (LayerDrawable) ContextCompat.getDrawable(MainActivity.this,R.drawable.background);
Drawable salad = (Drawable) layerDrawable.findDrawableByLayerId(R.id.salad);
and get-set some layer properties, such as getAlpha and setAlpha
layerDrawable.findDrawableByLayerId(R.id.salad).setAlpha(0);
down.setText( String.valueOf(layerDrawable.findDrawableByLayerId(R.id.salad).getAlpha()));
, but I need code access to <item> left and top property that would enable setting layer bitmap position, like it can be done from XML file. How do I do this?

SetBackgroundResource on listview custom adapter getting error

I'm trying to create a custom listview row color inside my adapter
Here is my xml
artists_list_backgroundcolor
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_selected="false"
android:state_pressed="false"
android:color="#6495ED" />
<item android:state_pressed="true"
android:color="#ffffff" />
<item android:state_selected="true"
android:state_pressed="false"
android:color="#E5F5FA" />
</selector>
and here is my code inside adapter
public override View GetView(int position, View convertView, ViewGroup parent)
{
View row = convertView;
if (row == null)
{
row = LayoutInflater.From(mContext).Inflate(Resource.Layout.CategoryPreview, null, false);
}
TextView txtCategoryName = row.FindViewById<TextView>(Resource.Id.txtCategoryName);
txtCategoryName.Text = mitems[position].CategoryName;
TextView txtCategoryID = row.FindViewById<TextView>(Resource.Id.txtCategoryID);
txtCategoryID.Text = mitems[position].CategoryID;
row.SetBackgroundResource(Resource.Drawable.artists_list_backgroundcolor);
return row;
}
When activity is going to start i'm getting error
Android.Content.Res.Resources+NotFoundException: Drawable WiOrderAndroid.WiOrderAndroid:drawable/artists_list_backgroundcolor with resource ID #0x7f020053
It work only if i will set my xml with this way.
<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" >
<shape>
<solid
android:color="#ef4444" />
</shape>
</item>
</selector>
But is this the right way?
try to use R.drawable.artists_list_backgroundcolor instead
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_selected="false"
android:state_pressed="false"
android:color="#6495ED" />
<item android:state_pressed="true"
android:color="#ffffff" />
<item android:state_selected="true"
android:state_pressed="false"
android:color="#E5F5FA" />
</selector>
From above codes, what you have defined is a ColorStateList, it should be in the res/color/artists_list_backgroundcolor.xml path, not res/drawable/ , and it should be referred by #color/artists_list_backgroundcolor or Resource.Color.artists_list_backgroundcolor.
What you need is a drawable selector. Please refer to this
Update:
SetBackgroundResource method:
Set the background to a given resource. The resource should refer to a Drawable object or 0 to remove the background.
The resource should be in drawable folder, but your artists_list_backgroundcolor file belongs to ColorStateList, it should be in the /res/color/ folder, not drawable folder.
If you want to use your artists_list_backgroundcolor file ,you need put it in the /res/color/ folder. But you can't use it by row.SetBackgroundResource(Resource.Drawable.artists_list_backgroundcolor);, please refer to this to use the ColorStateList.

ImageView with rotation in Android

I need to make an imageview with rotation feature. So I looked at the android developers site. And used their codes. But somehow I get an error.
Error:java.lang.ClassCastException: android.graphics.drawable.StateListDrawable cannot be cast to android.graphics.drawable.AnimationDrawable
I have these codes:
ImageView refresh = (ImageView)findViewById(R.id.refresh_devices_button);
refresh.setBackgroundResource(R.drawable.spin_animation); // The IDE says that it may produce null pointer exception
AnimationDrawable frameAnimation = (AnimationDrawable) refresh.getBackground();
frameAnimation.start();
In spin_animation.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<animation-list android:id="#+id/selected" android:oneshot="false">
<item android:drawable="#drawable/scan_1" android:duration="50" />
<item android:drawable="#drawable/scan_2" android:duration="50" />
<item android:drawable="#drawable/scan_3" android:duration="50" />
<item android:drawable="#drawable/scan_4" android:duration="50" />
<item android:drawable="#drawable/scan_5" android:duration="50" />
</animation-list>
</selector>
Please help me. From android's site I get the codes but their codes does not work. Maybe the problem is with my spin_animation.xml file.
refresh.getBackground returns StateListDrawableI think.
You can use something like this
ImageView splash = (ImageView) view.findViewById(R.id.imageView);
RotateAnimation anim = new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
anim.setInterpolator(new LinearInterpolator());
anim.setRepeatCount(Animation.INFINITE);
anim.setDuration(500);
// Start animating the image
splash.startAnimation(anim);
I have a rotation animation for my ImageView. You can try with this code:
First create your xml for rotation animation in anim directory :
rotation_animation.xml :
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:duration="400"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="0"
android:toDegrees="360" />
</set>
After that in your Java class (activity or fragment) add this :
Animation rotationAnimation = AnimationUtils.loadAnimation(this, R.anim.rotation_animation);
yourImageView.startAnimation(rotationAnimation);
Now you are ready. Happy codding :)
Use below code and import below class as well.
import android.graphics.drawable.AnimationDrawable;
private AnimationDrawable mAnimation;
private ImageView mAnimLogo;
mAnimLogo = (ImageView) findViewById(R.id.loading_image);
mAnimation = (AnimationDrawable) mAnimLogo.getDrawable();
mAnimation.start();
With this line :
AnimationDrawable frameAnimation = (AnimationDrawable) refresh.getBackground();
you are trying to cast a StateListDrawable to an AnimationDrawable which throws the exception.
Nice and simple :
refresh.animate().rotation(360).setDuration(...);
rotates your view to 360 Degrees clockwise in ... ms.
Or
refresh.animate().rotationBy(360).setDuration(...);
rotates the view BY 360 degrees.
Check out ViewPropertyAnimator for different kinds of animations you can code in one line.
Rotation Animation to imageview
`RotateAnimation anim = new RotateAnimation(0f, 350f, 15f, 15f);
anim.setInterpolator(new LinearInterpolator());
anim.setRepeatCount(Animation.INFINITE);
anim.setDuration(700);
// Start animating the image
final ImageView splash = (ImageView) findViewById(R.id.splash);
splash.startAnimation(anim);
// Later.. stop the animation
splash.setAnimation(null);`
I found that android site is okay. The problem was with my xml file.
I had this code
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<animation-list android:id="#+id/selected" android:oneshot="false">
<item android:drawable="#drawable/scan_1" android:duration="50" />
<item android:drawable="#drawable/scan_2" android:duration="50" />
<item android:drawable="#drawable/scan_3" android:duration="50" />
<item android:drawable="#drawable/scan_4" android:duration="50" />
<item android:drawable="#drawable/scan_5" android:duration="50" />
</animation-list>
</selector>
Instead of the above code I used the following code. I had to remove the<selector> tags.
<?xml version="1.0" encoding="utf-8"?>
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/selected" android:oneshot="false">
<item android:drawable="#drawable/scan_1" android:duration="50" />
<item android:drawable="#drawable/scan_2" android:duration="50" />
<item android:drawable="#drawable/scan_3" android:duration="50" />
<item android:drawable="#drawable/scan_4" android:duration="50" />
<item android:drawable="#drawable/scan_5" android:duration="50" />
</animation-list>

Loop animation drawable

I'm trying to animate some png and i would loop the animation. This is my code:
wave.setBackgroundResource(R.drawable.wave_animation);
frameAnimation = (AnimationDrawable)wave.getBackground();
frameAnimation.setCallback(wave);
frameAnimation.setVisible(true, true);
frameAnimation.start();
and here the xml with the png
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true">
<item android:drawable="#drawable/wave_01" android:duration="200" />
<item android:drawable="#drawable/wave_02" android:duration="200" />
<item android:drawable="#drawable/wave_03" android:duration="200" />
<item android:drawable="#drawable/wave_04" android:duration="200" />
</animation-list>
I added also the android:oneshot=false but doesn't work.
just change android:oneshot="false" to be like this
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
<item android:drawable="#drawable/wave_01" android:duration="200" />
<item android:drawable="#drawable/wave_02" android:duration="200" />
<item android:drawable="#drawable/wave_03" android:duration="200" />
<item android:drawable="#drawable/wave_04" android:duration="200" />
</animation-list>
Your code above shows
android:oneshot="true"
Which will make your animation run Once and only Once.
You say you tried android:oneshot="false".
That will be essential for running through the animation-list more than once. So put it back.
Keep in mind that running animation is a 'background' task which will terminate when the primary/foreground task completes regardless of its own settings.
If you want something else you might need to take a different approach.
This is running an animation on image. Before starting the animation you need to make sure its not already running. Add a check before starting animation, if its running then stop it and then start it.
private void startAnimation(){
imageView.setImageResource(R.drawable.img_animation);
AnimationDrawable imgAnimation = (AnimationDrawable) imageView.getDrawable();
if (imgAnimation .isRunning()) {
imgAnimation .stop();
}
imgAnimation .start();
}
img_animation.xml // Check for comments in below
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true" >
<!-- 24 frame per sec | 1000ms/24 i.e. 41ms per image -->
<item
android:drawable="#drawable/ball01" android:duration="41"/>
<item
android:drawable="#drawable/ball02" android:duration="41"/>
..........so on ..........
<item
android:drawable="#drawable/ball24" android:duration="41"/>
<!-- Reset to first when animation stops-->
<item
android:drawable="#drawable/ball01"
android:duration="10"/>
</animation-list>

Android Frame by Frame Animation problem on elements in a CursorAdapter

I am having trouble applying an animation to a View. I am trying to load the animation from inside the constructor of a CursorAdapter, so I can set it later assign it to certain children in the list.
In the constructor I have :
shineAnimation = AnimationUtils.loadAnimation(ctx, R.anim.news_list_item_shine);
the animation is in my res/anim dir
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true">
<item android:drawable="#drawable/shine1" android:duration="200" />
<item android:drawable="#drawable/shine2" android:duration="200" />
<item android:drawable="#drawable/shine3" android:duration="200" />
<item android:drawable="#drawable/shine4" android:duration="200" />
<item android:drawable="#drawable/shine5" android:duration="200" />
</animation-list>
I'm getting an exception :
Unknown animation name: animation-list
Help would be much appreciated
Thanks
S
I don't think you load AnimationDrawables via AnimationUtils. AnimationDrawable is a Drawable more than it is an Animation. Try this sample code from the SDK guide.
ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
rocketImage.setBackgroundResource(R.anim.rocket_thrust);
rocketAnimation = (AnimationDrawable) rocketImage.getBackground();

Categories

Resources