当isIndicator=True时,Android分级栏为按钮

当isIndicator=True时,Android分级栏为按钮,android,android-widget,Android,Android Widget,我使用的是一个带有自定义样式的分级栏,它可以作为一个指示器,但是我希望用户仍然能够单击分级栏来打开一个带有可更改分级栏的自定义对话框 在不使用图像的情况下,是否仍可以执行此操作 举例说明: 对于那些在未来遇到同样问题的人,我已经找到了答案 ratingBar = (RatingBar) findViewById(R.id.rbMyRating); ratingBar.setIsIndicator(true); ratingBar.setOnTouchListener(new OnTouchLis

我使用的是一个带有自定义样式的分级栏,它可以作为一个指示器,但是我希望用户仍然能够单击分级栏来打开一个带有可更改分级栏的自定义对话框

在不使用图像的情况下,是否仍可以执行此操作

举例说明:


对于那些在未来遇到同样问题的人,我已经找到了答案

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;
    }
});
关键是,即使isIndicator为true,您仍然可以使用setPressed设置为true。这将只允许分级栏高亮显示,但不允许更改

您可以使用OnTouchListener管理setPressed状态。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的一个问题是,您现在可以使用KEYCODE_DPAD_LEFT和KEYCODE_DPAD_RIGHT更改评级条评级。要解决此问题,请使用onRatingBarChangeListener重置RatingBar的评级。您可以将评级存储在RatingBar的标记中。请记住,在通过对话框更改分级时,需要更改标记值

由于使用onRatingBarChangeListener,您现在将面临最后一个问题。由于您正在自动更改分级,用户将无法使用左键code_DPAD_和右键code_DPAD_聚焦其他UI元素。要解决这个问题,您只需使用OnKeyListener检测左侧和右侧DPad操作,并使用searchFocus和requestFocus更改焦点。只要记住,如果找不到UI元素,searchFocus将返回null


希望这对遇到此问题的其他人有所帮助。:)

您可以在相对布局中添加分级栏,并使用透明按钮覆盖分级栏

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

然后在按钮上添加侦听器