Android RatingBar как кнопка, когда isIndicator = True - PullRequest
2 голосов
/ 12 февраля 2012

Я использую рейтинговую панель с пользовательским стилем, который действует как индикатор, однако я хочу, чтобы пользователи по-прежнему могли щелкать рейтинговую панель, чтобы вызвать пользовательский диалог с рейтинговой панелью, которую можно изменить.

Есть ли способ сделать это без использования изображений?

Для иллюстрации:

RatingBar Highlighed

Ответы [ 2 ]

3 голосов
/ 13 февраля 2012

Для тех, кто испытывает те же проблемы в будущем, я понял это.

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;
    }
});

Ключ был в том, что вы все еще можете использовать setPressed в true, хотя isIndicator имеет значение true. Это позволит только подсвечивать RatingBar, но не изменять его.

Вы можете управлять состоянием setPressed с помощью OnTouchListener. ACTION_UP и ACTION_DOWN управляют событиями касания в виджете, ACTION_CANCEL обрабатывает любое событие вне виджета.


Проблема с приведенным выше кодом заключается в том, что он не поддерживает ключевые события. Для этого необходим следующий дополнительный код:

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());
    }
});

Приведенный выше код использует как OnKeyListener, так и setOnRatingBarChangeListener. Чтобы включить ключевые события, вам нужно установить setFocusable (true). Вам также необходимо вручную подключить ключевые события для KEYCODE_ENTER и KEYCODE_DPAD_CENTER.

Проблема с setFocusable = true заключается в том, что теперь вы можете изменять рейтинг RatingBar, используя KEYCODE_DPAD_LEFT и KEYCODE_DPAD_RIGHT. Чтобы решить эту проблему, вы используете onRatingBarChangeListener для сброса рейтинга RatingBar. Вы можете сохранить рейтинг в тэге RatingBar. ПОМНИТЕ, вам нужно будет изменить значение тега при изменении рейтинга в диалоговом окне.

В результате использования onRatingBarChangeListener вы столкнетесь с одной последней проблемой. Поскольку вы автоматически изменяете рейтинг, пользователь не сможет фокусировать другие элементы пользовательского интерфейса с помощью KEYCODE_DPAD_LEFT и KEYCODE_DPAD_RIGHT. Чтобы решить эту проблему, вы просто используете OnKeyListener, чтобы обнаружить левое и правое действия DPad и изменить фокус, используя searchFocus и requestFocus. Просто помните, что searchFocus возвращает ноль, если элемент пользовательского интерфейса не найден.

Надеюсь, это поможет любому, кто столкнется с этой проблемой. :)

0 голосов
/ 13 ноября 2014

Вы можете добавить свой RatingBar в относительный макет и наложить его на прозрачную кнопку

<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>

Затем вы добавляете своего слушателя на кнопку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...