评分条的 onClick

25

我有一个ListView,它使用不同的XML文件创建视图并制作项目。其中一个XML文件包含RatingBar。一切都正常显示和外观良好。

我想将onClick处理程序附加到RatingBar上以启动新的Activity。我的RatingBar是样式为?android:attr / ratingBarStyleSmall的,因此它只是一个指示器(我希望单击小的RatingBar会将用户带到可以进行各种评分的Activity)。

我的问题是RatingBar的onClick处理程序从未执行过。更有趣的是,我已经使用相同的代码使LinearLayout可点击,并且它可以正常工作。有人能告诉我原因吗?

我的适配器的getView如下:

@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.OnClickListener() {
                            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;
}

有没有人对此有其他的意见?我仍然无法使onClick处理程序执行。正如您所看到的,我正在使用相同的代码进行LinearLayout,并且它运行良好。我的RatingBar设置为可点击。我已经在LinearLayout和RatingBar的onClick侦听器内设置了断点,只有LinearLayout处理程序被执行。注意:RatingBar不在LinearLayout内。正如您所看到的,它们位于两个不同的XML文件中。 - Andrew
6个回答

66
setOnClickListener() 无法正常工作的原因是,RatingBar 覆盖了 onTouchEvent() 方法(实际上是它的父类 AbsSeekBar),并且不会让 View 管理触摸事件。因此,View#performClick() 永远不会被调用(该方法将调用 OnClickListener)。

有两种可能的解决方法:

    继承自 RatingBar 并覆盖 onTouchEvent() 方法;
    改用 OnTouchListener,像这样:
ratingBar.setOnTouchListener(object : OnTouchListener {
    override fun onTouch(v: View, event: MotionEvent): Boolean {
        if (event.action == MotionEvent.ACTION_UP) {
            // TODO 执行你的操作
        }
        return true
    }
})

Kotlin 示例:

ratingBar.setOnTouchListener(View.OnTouchListener { v, event ->
                if (event.action == MotionEvent.ACTION_UP) {
                    // TODO perform your action here
                }
                return@OnTouchListener true
            })

谢谢,Jonas


8

Andrew,你可以尝试使用其他可用于 RatingBar 的事件,例如 OnRatingBarChangeListener。看看这个例子,对我而言它有效!

ratingBar.setOnRatingBarChangeListener(new OnRatingBarChangeListener() {

        @Override
        public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
            viewMarketDetails(mContext);
            dialog.dismiss();
        }
    });

所以您不需要使用onClickEvent,但是您可以获得相同的效果,只有当您实际更改值时才会起作用。(如果您单击实际值,则没有效果)

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

5

我通过将RatingBar包装在LinearLayout中并将onClick侦听器附加到LinearLayout来解决了这个问题。虽然我不喜欢这样做,但它可以工作。由于某种神秘的原因,RatingBar不会执行onClick。


1
这将监听点击评分,对评分的更改没有任何影响。
<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>

在 Constraint Layout 中,只需在 RatingBar 上方添加 TextView 布局,并侦听 TextView 布局的点击监听器。以下是 Java 代码:
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;
  }
}

1
在 ListView 中,通常需要决定您是否希望列表视图项可点击,或者是包含在 ListView 中的项目。r.isClickable() 是否返回 true?
您可以将 RatingBar 的 clickable 设置为 false,并使用 listView 的 onClickListener 处理 listView 行上的单击事件,这样可能会更好一些。

我不想让整个列表项可点击,但我希望列表项内的各个项目可点击。我已经使用LinearLayout项目实现了这一点。代码完全相同,onClick处理程序执行得很好。我不明白为什么RatingBar不行。我会更新我的主要帖子以反映这一点,稍等片刻。 - Andrew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接