在评级栏和样式出现许多问题后,我设法让几乎所有工作都能正常工作.
我在listview项目中使用它.由于它是如何工作的,人们必须与它的外观和行为“战斗”一点.我最终使用了我在SO上找到的解决方案,其中一个设置它作为指示器,但是在自己手动计算评分栏上的点击对应的分数时.在浏览代码时代码总是产生正确的结果,但第一次控制绘画本身是错误的.这是我在getView“第一部分”中的代码:
final RatingBar rating = (RatingBar)view.findViewById(R.id.listitem_catalog_rating); rating.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v,MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { float touchPositionX = event.getX(); float width = rating.getWidth(); float starsf = (touchPositionX / width); starsf = starsf * param_final__data.score_max; // 5 int starsint = (int) starsf + param_final__data.score_min; byte starsbyte = (byte) starsint; param_final__data.score_cur = starsbyte; starsf = starsint; rating.setRating(starsf); rating.setVisibility(View.INVISIBLE); // force repaint and set visible - how? } else if (event.getAction() == MotionEvent.ACTION_DOWN) { param_final__view.setPressed(true); } else if (event.getAction() == MotionEvent.ACTION_CANCEL) { param_final__view.setPressed(false); } return true; } });
问题是.当评级栏最初显示时,第一次单击任何位置时,它会使其自己绘制,就像总是选择最大分数一样.但是,如果一个人隐藏控件并再次显示它 – 它会正确地绘制所有内容.然而,这是“自然用户交互延迟” – 例如通过单击切换可见性状态的按钮.如果我尝试使用invalidate或setvisibility指令强制重新编写代码,则不会发生任何事情.
这是代码“第2部分”,我在getView中初始化ratingbar时显示:
rating.setIsIndicator(true); rating.setVisibility(View.VISIBLE); rating.setStepSize(1); //rating.setMax(data.score_max); rating.setNumStars(data.score_max); rating.setRating(data.score_cur);
这是它的XML:
<RatingBar android:id="@+id/listitem_catalog_rating" android:layout_height="wrap_content" android:layout_width="wrap_content" android:numStars="1" android:stepSize="1.0" android:rating="1.0" style="@style/MicRatingBar" android:visibility="gone" android:layout_marginTop="10dip" android:layout_marginBottom="10dip" />
…
<style name="MicRatingBar" parent="@android:style/Widget.RatingBar"> <item name="android:progressDrawable">@drawable/micratingstars</item> <item name="android:minHeight">34dip</item> <item name="android:maxHeight">34dip</item> </style>
…
<?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_background" /> <item android:id="@+android:id/secondaryProgress" android:drawable="@drawable/star_secondaryprogress" /> <item android:id="@+android:id/progress" android:drawable="@drawable/star_progress" /> </layer-list>
作为参考,这些是我得到的一些stackoverflow:
> Capture RatingBar Click
> Android RatingBar as Button when isIndicator = True
> How to make a smaller RatingBar?
(但遗憾的是并没有解决我的具体问题.)
我尝试了很多不同的组合,在我的例子中,这里发布的代码是最接近所需行为和外观的代码.只是在问题上,得分在“首秀”中被错误地绘制.
我曾尝试使用例如无效,但我相信它的内部标志使它忽略了使请求无效.
解决方法
// Fine rating.setIsIndicator(true); // Fine rating.setVisibility(View.VISIBLE); // Problem - Although not documented,I think this should be // called after `setNumStars(int)` rating.setStepSize(1); // Switch with the statement above rating.setNumStars(data.score_max); // Fine rating.setRating(data.score_cur);
所以,试试这个顺序:
rating.setIsIndicator(true); rating.setVisibility(View.VISIBLE); rating.setNumStars(data.score_max); rating.setStepSize(1); rating.setRating(data.score_cur);
至于//强制重绘并设置可见 – 如何?,这不应该是必需的. setRating(float)应该强制更新.只需删除rating.setVisibility(View.INVISIBLE);来自ACTION_UP部分代码.如果RatingBar仍未更新,请尝试rating.requestLayout().但是,请进一步阅读更清洁的解决方案.
你说int starsint =(int)starsf param_final__data.score_min;正在获得正确的价值.我猜这个param_final__data.score_cur = starsbyte;更新ListView数据.那么为什么不调用notifyDataSetChanged(),让适配器使用正确的值更新视图?但是,需要更改语句顺序.