为什么 ImageButton (Android - Java) 没有在实际图像上实现 onClick
Why is ImageButton (Android - Java) not implementing onClick on actual image
我还没有找到明确的答案,所以我想我会写一篇 post 看看是否有人能指出我正确的方向。
基本上我正在创建一个语音笔记应用程序,我为本地保存的文件设置了一个 'delete' 按钮作为 ImageButton 的垃圾桶图像。鉴于用户将能够根据需要保存尽可能多的音频文件,我实现了一个循环,其中创建了按钮,通过 setID 设置了 ID,然后根据生成的 ID 使用了点击监听器。
我的问题是点击侦听器在图像的两侧起作用,但在实际图像上不起作用,这意味着如果我单击 ImageButton 的右侧或左侧,文件将被删除,但是,当我实际单击时ImageButton 中的垃圾桶图像,没有任何反应。我也有在单击按钮时随时注册的日志,当我单击实际图像时它们也不起作用,所以我确定问题是在单击 ImageButton 时以某种方式未使用侦听器。 - 请记住,我说的是点击注册在图像的右侧和左侧。
相关代码如下:
try{
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
//Button button = new Button(getApplicationContext());
TextView fileButton = new TextView(getApplicationContext());
fileButton.setTextColor(Color.parseColor("#ffffff"));
fileButton.setBackgroundResource(R.drawable.textview_button_colors);
fileButton.setTypeface(fileButton.getTypeface(), Typeface.BOLD);
fileButton.setText((i+1)+") "+listOfFiles[i].getName());
fileButton.setId(i);
fileButton.setPadding(10,10,10,10);//LTRB
fileButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
RelativeLayout deleteButton = (RelativeLayout) inflater.inflate(R.layout.image_buttons, null);
deleteButton.setId(i+i);
Log.d(LOG_TAG, String.valueOf(deleteButton.getId()) );//WORKS AS EXPECTED
deleteButton.setGravity(Gravity.CENTER_HORIZONTAL);
TableRow horizontalButtonTableRow= new TableRow(getApplicationContext());
TableLayout.LayoutParams tableRowParams = new TableLayout.LayoutParams
(TableLayout.LayoutParams.MATCH_PARENT,TableLayout.LayoutParams.WRAP_CONTENT);
int leftMargin=0;int topMargin=15;int rightMargin=0;int bottomMargin=0;
tableRowParams.setMargins(leftMargin, topMargin, rightMargin, bottomMargin);
horizontalButtonTableRow.setLayoutParams(tableRowParams);
horizontalButtonTableRow.addView(fileButton);
horizontalButtonTableRow.addView(deleteButton);
final String fileName = saveDirectory.toString() + File.separator +
listOfFiles[i].getName();
fileButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Log.d(LOG_TAG, "should be playing audio");
MediaPlayer mediaPlayer = new MediaPlayer();
try {
Vibrator vib = (Vibrator) getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE);
vib.vibrate(25);
FileInputStream fis = new FileInputStream(fileName);
mediaPlayer.setDataSource(fis.getFD());
Log.d(LOG_TAG, fileName);
mediaPlayer.prepare();
} catch (Exception e) {
Log.d(LOG_TAG, String.valueOf(e));
}
mediaPlayer.start();
}
});
deleteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
Vibrator vib = (Vibrator) getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE);
vib.vibrate(25);
File deleteFile = new File(fileName);
deleteFile.delete();
savedFileLoader();
Log.d(LOG_TAG, fileName+": WAS DELETED");
} catch (Exception e) {
Log.d(LOG_TAG, String.valueOf(e));
}
}
});
verticalButtonContainerLayout.addView(horizontalButtonTableRow);
}//END IF
}//END FOR
}catch(Exception e){
Log.d(LOG_TAG,e.toString());
}
更多信息(但未在最终解决方案中使用):如果我更改充气器的代码使其像这样工作,则 imageButton 不再添加到我的视图中。我认为发生这种情况是因为我被迫从原始相对视图中删除图像按钮。
LayoutInflater inflater =
(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
RelativeLayout deleteButtonLayout = (RelativeLayout)
inflater.inflate(R.layout.image_buttons, null);
ImageButton deleteButton =
deleteButtonLayout.findViewById(R.id.imageButton);
deleteButtonLayout.removeView(deleteButton);
deleteButton.setId(i+i);
如果我选择不使用 removeView,我会得到这个异常:
java.lang.IllegalStateException: 指定的 child 已经有一个 parent。您必须先在 child 的 parent 上调用 removeView()。
这是相对布局中 imageButton 的XML:
更新:我已经根据@John Tribe 提供的批准答案更正了我的代码。 "fix" 是将 RelativeLayout 设置为可点击,同时将 ImageButton 设置为不可点击。这样做可以让我的整个膨胀布局都可以点击,这正是我解决这个问题所需要的,因为我膨胀的 RelativeLayout 中只有 1 个元素。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:clickable="true"
android:layout_height="match_parent">
<ImageButton
style="?android:attr/buttonBarStyle"
android:id="@+id/imageButton"
android:layout_width="30dp"
android:layout_height="30dp"
android:adjustViewBounds="true"
android:clickable="false"
android:scaleType="center"
android:background="@drawable/trash"/>
</RelativeLayout>
您使用了 RelativeLayout ,您应该使用 Image 或 ImageButton,但如果您真的想使用 RelativeLayout ,则在 xml 中添加 android:clickable="true"
.
另一种方法是找到 ImageButton 并设置侦听器。
ImageButton deleteButton = deleteButtonLayout.findViewById(R.id.imageButton);
deleteButton.setOnClickListener( new On...);
我还没有找到明确的答案,所以我想我会写一篇 post 看看是否有人能指出我正确的方向。
基本上我正在创建一个语音笔记应用程序,我为本地保存的文件设置了一个 'delete' 按钮作为 ImageButton 的垃圾桶图像。鉴于用户将能够根据需要保存尽可能多的音频文件,我实现了一个循环,其中创建了按钮,通过 setID 设置了 ID,然后根据生成的 ID 使用了点击监听器。
我的问题是点击侦听器在图像的两侧起作用,但在实际图像上不起作用,这意味着如果我单击 ImageButton 的右侧或左侧,文件将被删除,但是,当我实际单击时ImageButton 中的垃圾桶图像,没有任何反应。我也有在单击按钮时随时注册的日志,当我单击实际图像时它们也不起作用,所以我确定问题是在单击 ImageButton 时以某种方式未使用侦听器。 - 请记住,我说的是点击注册在图像的右侧和左侧。
相关代码如下:
try{
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
//Button button = new Button(getApplicationContext());
TextView fileButton = new TextView(getApplicationContext());
fileButton.setTextColor(Color.parseColor("#ffffff"));
fileButton.setBackgroundResource(R.drawable.textview_button_colors);
fileButton.setTypeface(fileButton.getTypeface(), Typeface.BOLD);
fileButton.setText((i+1)+") "+listOfFiles[i].getName());
fileButton.setId(i);
fileButton.setPadding(10,10,10,10);//LTRB
fileButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
RelativeLayout deleteButton = (RelativeLayout) inflater.inflate(R.layout.image_buttons, null);
deleteButton.setId(i+i);
Log.d(LOG_TAG, String.valueOf(deleteButton.getId()) );//WORKS AS EXPECTED
deleteButton.setGravity(Gravity.CENTER_HORIZONTAL);
TableRow horizontalButtonTableRow= new TableRow(getApplicationContext());
TableLayout.LayoutParams tableRowParams = new TableLayout.LayoutParams
(TableLayout.LayoutParams.MATCH_PARENT,TableLayout.LayoutParams.WRAP_CONTENT);
int leftMargin=0;int topMargin=15;int rightMargin=0;int bottomMargin=0;
tableRowParams.setMargins(leftMargin, topMargin, rightMargin, bottomMargin);
horizontalButtonTableRow.setLayoutParams(tableRowParams);
horizontalButtonTableRow.addView(fileButton);
horizontalButtonTableRow.addView(deleteButton);
final String fileName = saveDirectory.toString() + File.separator +
listOfFiles[i].getName();
fileButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Log.d(LOG_TAG, "should be playing audio");
MediaPlayer mediaPlayer = new MediaPlayer();
try {
Vibrator vib = (Vibrator) getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE);
vib.vibrate(25);
FileInputStream fis = new FileInputStream(fileName);
mediaPlayer.setDataSource(fis.getFD());
Log.d(LOG_TAG, fileName);
mediaPlayer.prepare();
} catch (Exception e) {
Log.d(LOG_TAG, String.valueOf(e));
}
mediaPlayer.start();
}
});
deleteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
Vibrator vib = (Vibrator) getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE);
vib.vibrate(25);
File deleteFile = new File(fileName);
deleteFile.delete();
savedFileLoader();
Log.d(LOG_TAG, fileName+": WAS DELETED");
} catch (Exception e) {
Log.d(LOG_TAG, String.valueOf(e));
}
}
});
verticalButtonContainerLayout.addView(horizontalButtonTableRow);
}//END IF
}//END FOR
}catch(Exception e){
Log.d(LOG_TAG,e.toString());
}
更多信息(但未在最终解决方案中使用):如果我更改充气器的代码使其像这样工作,则 imageButton 不再添加到我的视图中。我认为发生这种情况是因为我被迫从原始相对视图中删除图像按钮。
LayoutInflater inflater =
(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
RelativeLayout deleteButtonLayout = (RelativeLayout)
inflater.inflate(R.layout.image_buttons, null);
ImageButton deleteButton =
deleteButtonLayout.findViewById(R.id.imageButton);
deleteButtonLayout.removeView(deleteButton);
deleteButton.setId(i+i);
如果我选择不使用 removeView,我会得到这个异常: java.lang.IllegalStateException: 指定的 child 已经有一个 parent。您必须先在 child 的 parent 上调用 removeView()。
这是相对布局中 imageButton 的XML:
更新:我已经根据@John Tribe 提供的批准答案更正了我的代码。 "fix" 是将 RelativeLayout 设置为可点击,同时将 ImageButton 设置为不可点击。这样做可以让我的整个膨胀布局都可以点击,这正是我解决这个问题所需要的,因为我膨胀的 RelativeLayout 中只有 1 个元素。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:clickable="true"
android:layout_height="match_parent">
<ImageButton
style="?android:attr/buttonBarStyle"
android:id="@+id/imageButton"
android:layout_width="30dp"
android:layout_height="30dp"
android:adjustViewBounds="true"
android:clickable="false"
android:scaleType="center"
android:background="@drawable/trash"/>
</RelativeLayout>
您使用了 RelativeLayout ,您应该使用 Image 或 ImageButton,但如果您真的想使用 RelativeLayout ,则在 xml 中添加 android:clickable="true"
.
另一种方法是找到 ImageButton 并设置侦听器。
ImageButton deleteButton = deleteButtonLayout.findViewById(R.id.imageButton);
deleteButton.setOnClickListener( new On...);