Android OnTouchListener 改变被触摸的项目

Android OnTouchListener change touched item

我正在开发一个 Android 应用程序,我在其中使用 GridView 绘制多个项目。为了绘制项目,我编写了一个适配器 - ImageAdapter。每张图片都是一个整数,是应该绘制在特定位置的图片的资源。

我有自己的按钮图片(一张图片用于 "button up",一张图片用于 "button down")。我想在触摸按钮时将图像 "button up" 更新为 "button down"。因此我使用了 OnTouchListener

然而,当我更新 ImageAdapter 中的图像并调用方法 notifyDataSetChanged(这是 class BaseAdapter 的方法)时,侦听器不会当不再触摸按钮时给我事件。那是因为设置 OnTouchListener 的资源已更改为新图像 "button down"。

但是,如果我不调用 notifyDataSetChanged(),一切都很好,但是按钮图像不会更新。

我的代码:

private void setTouchListenerForButtons(
  Project project, final ImageAdapter imgadapt, 
  IConnection currentConnection, boolean editmode
  ) {
    for(int i = 0; i < imgadapt.getCount(); i++) {
        View v = project.getGui().getGridView().getChildAt(i);

        try {
            Object tag = v.getTag();

            int p = 0;

            if (tag != null) { // Button
                p = (Integer) tag;

                final int btnPosition = p;
                project.getGui().getGridView().getChildAt(btnPosition).setOnTouchListener(new OnTouchListener() {
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        Toast.makeText(getContext(), event.getAction() + "", Toast.LENGTH_SHORT).show();
                        switch (event.getAction()) {

                            case MotionEvent.ACTION_DOWN:
                                Log.d(LOG_TAG, "Button down");
                                imgadapt.update(R.drawable.button_on, btnPosition);
                                imgadapt.notifyDataSetChanged(); // that's the PROBLEM
                                break;

                            case MotionEvent.ACTION_UP:
                                Log.d(LOG_TAG, "Button up");
                                imgadapt.update(R.drawable.button_off, btnPosition);
                                imgadapt.notifyDataSetChanged();
                                break;
                        }

                        return true;
                    }
                });
            }
        } catch (NullPointerException e) {
        }

    }
}

我该如何解决这个问题?

在这种情况下不要使用 setOnTouchListener。创建一个选择器:

drawable/selector_btn_default.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/btn_default_pressed"
        android:state_pressed="true"/>
    <item android:drawable="@drawable/btn_default"/>
</selector>

并将其设置为特定图像的android:src

<ImageView android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/selector_btn_default"/>

顺便说一下,这种用途调用notifyDataSetChanged是完全不好的。仅仅为了改变单个项目上的图像而刷新整个 GridView 是错误的。