Android RatingBar as a button when isIndicator = True

I use a rating panel with a custom style that acts as an indicator, however I want users to still be able to click on the rating panel to bring up a custom dialogue with the rating panel, which can be changed.

Is there any way to do this without using images?

To illustrate:

RatingBar Highlighed

+2
source share
2 answers

For those who have the same problems in the future, I realized this.

ratingBar = (RatingBar) findViewById(R.id.rbMyRating); ratingBar.setIsIndicator(true); ratingBar.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { myRatingDialog.show(); v.setPressed(false); } if (event.getAction() == MotionEvent.ACTION_DOWN) { v.setPressed(true); } if (event.getAction() == MotionEvent.ACTION_CANCEL) { v.setPressed(false); } return true; } }); 

The key was that you can still use setPressed for true, even if isIndicator is true. This will only show RatingBar, but not change.

You can control the state of setPressed using OnTouchListener. ACTION_UP and ACTION_DOWN control widget touch events, ACTION_CANCEL handles any event outside the widget.


The problem with the above code is that it does not support key events. This requires the following additional code:

 Float rating = 4f; ratingBar.setFocusable(true); ratingBar.setTag(rating); ratingBar.setOnKeyListener(new OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_DOWN) { if(keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER) { v.setPressed(false); myRatingDialog.show(); } else if(keyCode == KeyEvent.KEYCODE_DPAD_LEFT) { if (v.focusSearch(View.FOCUS_LEFT) != null) v.focusSearch(View.FOCUS_LEFT).requestFocus(); } else if(keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) { if (v.focusSearch(View.FOCUS_RIGHT) != null) v.focusSearch(View.FOCUS_RIGHT).requestFocus(); } } return false; } }); ratingBar.setOnRatingBarChangeListener(new OnRatingBarChangeListener() { @Override public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) { ratingBar.setRating((Float) ratingBar.getTag()); } }); 

The above code uses both OnKeyListener and setOnRatingBarChangeListener. To enable key events, you need to set setFocusable (true). You also need to manually connect key events for KEYCODE_ENTER and KEYCODE_DPAD_CENTER.

The problem with setFocusable = true is that now you can change the RatingBar rating with KEYCODE_DPAD_LEFT and KEYCODE_DPAD_RIGHT. To solve this problem, you use onRatingBarChangeListener to reset RatingBar rating. You can save the rating in the RatingBar tag. REMEMBER, you will need to change the tag value when changing the rating in the dialog box.

As a result of using onRatingBarChangeListener, you encountered one last problem. Since you automatically change the rating, the user will not be able to focus other user interface elements using KEYCODE_DPAD_LEFT and KEYCODE_DPAD_RIGHT. To solve this problem, you simply use OnKeyListener to detect left and right actions of DPad and change focus with searchFocus and requestFocus. Just remember that searchFocus returns null if the UI element is not found.

Hope this helps anyone facing this issue. :)

+3
source

You can add your RatingBar to the Relative Layout and overlay it with a transparent button.

 <RelativeLayout android:layout_width:"match_parent" android:layout_height:"wrap_content" > <RatingBar android:layout_width:"wrap_content" android:layout_height:"wrap_content" android:numStars="5" android:isIndicator="true" /> <Button android:layout_width:"match_parent" android:layout_height:"wrap_content" android:background:"@android:color/transparent" /> </RelativeLayout> 

Then you add a listener to the button.

0
source

Source: https://habr.com/ru/post/978709/


All Articles