RatingBar onClick
I have a ListView that uses different XML files to create Views and make items out of. One of these XML files contains a RatingBar. Everything displays and looks excellent.
I'm trying to attach an onClick handler to the RatingBar to launch a new Activity. My RatingBar is of style ?android:attr/ratingBarStyleSmall; so it's just an indicator (I want the small RatingBar click to take the user to an Activity where they can do various ratings).
My problem is the onClick handler for the RatingBar never gets executed. What makes it more interesting is that I've used the same code to make a LinearLayout clickable and it works fine. Could anyone tell me why?
My Adapter's getView looks as such:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
int type = getItemViewType(position);
// get the View for this list item
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
switch (type) {
// ...
case TYPE_LOOKUP:
v = vi.inflate(R.layout.layout_itemlist_itemlookup, parent, false);
LinearLayout vLookup = (LinearLayout)v.findViewById(R.id.itemlist_lookup);
if (vStore != null) {
vStore.setOnClickListener(new View.OnCl开发者_如何转开发ickListener() {
public void onClick(View v) {
// THIS HANDLER WORKS FINE
Intent intentLaunchLookup = new Intent(ActivityItemList.this, ActivityLookup.class);
startActivity(intentLaunchLookup);
}
});
}
break;
case TYPE_SEPARATOR:
v = vi.inflate(R.layout.layout_itemlist_itemseparator, parent, false);
RatingBar r = (RatingBar)v.findViewById(R.id.itemlist_rating);
if (r != null) {
r.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// THIS HANDLER DOES NOT GET EXECUTED (r IS NOT NULL; SO THIS SHOULD HAVE BEEN CREATED)
Intent intentLaunchRating = new Intent(ActivityItemList.this, ActivityRating.class);
startActivity(intentLaunchRating);
}
});
}
break;
// ...
}
}
// …
// return the created view
return v;
}
The reason for setOnClickListener()
not working is that RatingBar
overrides onTouchEvent()
(actually its super class, AbsSeekBar
, does) and never let View
take care of it, so View#performClick()
is never called (which would have called the OnClickListener
).
Two possible workarounds:
- derive from
RatingBar
and override onTouchEvent()
- use
OnTouchListener
instead, like so:
ratingBar.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { // TODO perform your action here } return true; }
In Kotlin
ratingBar.setOnTouchListener(View.OnTouchListener { v, event ->
if (event.action == MotionEvent.ACTION_UP) {
// TODO perform your action here
}
return@OnTouchListener true
})
HTH, Jonas
Andrew, you can just try to use another event available for RatingBar, OnRatingBarChangeListener. See this example, it works for me!
ratingBar.setOnRatingBarChangeListener(new OnRatingBarChangeListener() {
@Override
public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
viewMarketDetails(mContext);
dialog.dismiss();
}
});
So you don't need to use the onClickEvent but you have the same effect, but only work, off course, if you change actually the value. (If you click on the actual value, if has no effect)
ratingBar1.setOnRatingBarChangeListener(new OnRatingBarChangeListener() {
@Override
public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
String rateValue = String.valueOf(ratingbar1.getRating());
System.out.println("Rate for Module is"+rateValue);
}
});
I've hacked around this problem by wrapping the RatingBar in a LinearLayout and attaching an onClick listener to the LinearLayout. I don't like doing this, but it works. For some mysterious reason onClick will not execute for a RatingBar.
In a ListView, you generally have to decide if you want the list view items to be clickable, or an item contained within the listview. Does r.isClickable() return true?
You might have better luck setting clickable to false on the RatingBar, and instead using onClickListener of the listView to deal with the click events on the listView row.
This will listen to click on rating and won't do any effect on rating change as well
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatRatingBar
android:id="@+id/rating_bar_current_rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_16"
android:maxHeight="@dimen/dp_23"
android:minHeight="@dimen/dp_23"
android:progressDrawable="@drawable/custom_rating_selector"
android:stepSize="0"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_find_provider_subheader" />
<TextView
android:id="@+id/tv_current_rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
app:layout_constraintBottom_toBottomOf="@+id/rating_bar_current_rating"
app:layout_constraintEnd_toEndOf="@+id/tv_current_rating"
app:layout_constraintStart_toStartOf="@+id/rating_bar_current_rating"
app:layout_constraintTop_toTopOf="@+id/rating_bar_current_rating" />
</androidx.constraintlayout.widget.ConstraintLayout>
Just add a textview layout on top of ratingbar and listen to click listener of textview layout. Both views inside of Constraint layout.
in java code
Textview textview = findViewById(R.id.tv_current_rating)
textview.setOnClickListener(this)
@override
public void onClick(View v) {
while (v.id) {
case R.id.tv_current_rating :
// TODO : This will show toast on click event
Toast.makeText(getApplicationContext(),
"This a toast message",
Toast.LENGTH_LONG)
.show();
break;
}
}
精彩评论