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 是错误的。
我正在开发一个 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 是错误的。