按钮需要点击两次

Button needs to get clicked twice

我想熟悉 Android 并开始学习一些 Udacity 课程。目前,出于语言学习的目的,我们必须让 ImageButton 在点击时播放一些音频。 我认为如果按钮也可以切换会很好,例如,在暂停状态下,它应该显示一个“播放”图标,在播放状态下,一个“暂停”图标。使用 OnClickListener 实现起来非常简单,而且它也可以正常工作,最多 1 个小细节:用户必须单击按钮两次。

经过一番搜索,我发现第一次点击用于将视图聚焦在该位置,而第二次点击是在实际处理触发的 OnClickEvent 时使用的。我试图在所有可能的地方将 focusablefocusableInTouchMode 属性更改为所有可能的组合,但它没有用。

这是我的主要Activity:

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    TextView numbersView = findViewById(R.id.numbers);
    numbersView.setOnClickListener(v -> {
        Intent numbersIntent = new Intent(MainActivity.this, NumbersActivity.class);
        startActivity(numbersIntent);
    });

    TextView familyView = findViewById(R.id.family);
    familyView.setOnClickListener(v -> {
        Intent familyIntent = new Intent(MainActivity.this, FamilyActivity.class);
        startActivity(familyIntent);
    });

    TextView colorView = findViewById(R.id.colors);
    colorView.setOnClickListener(v -> {
        Intent colorsIntent = new Intent(MainActivity.this, ColorActivity.class);
        startActivity(colorsIntent);
    });

    TextView phrasesView = findViewById(R.id.phrases);
    phrasesView.setOnClickListener(v -> {
        Intent phrasesIntent = new Intent(MainActivity.this, PhrasesActivity.class);
        startActivity(phrasesIntent);
    });
}

}

这里对应的是xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
tools:context=".MainActivity"
android:orientation="vertical"
android:divider="?android:dividerHorizontal"
android:showDividers="middle"
android:background="#212121">

<TextView
    android:id="@+id/numbers"
    style="@style/CategoryStyle"
    android:layout_height="wrap_content"
    android:text="@string/numbers"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    android:textColor="#b794f6"/>

<TextView
    android:id="@+id/family"
    style="@style/CategoryStyle"
    android:layout_height="wrap_content"
    android:text="@string/family"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    android:textColor="#90CAF9"/>

<TextView
    android:id="@+id/colors"
    style="@style/CategoryStyle"
    android:layout_height="wrap_content"
    android:text="@string/colors"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    android:textColor="#EEEEEE"/>

<TextView
    android:id="@+id/phrases"
    style="@style/CategoryStyle"
    android:layout_height="wrap_content"
    android:text="@string/phrases"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    android:textColor="#FFE082"/>

这是我的号码Activity(其他活动非常相似):

public class NumbersActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.word_list);

    ListView view = findViewById(R.id.coolList);

    List<Word> words = new ArrayList<>(Arrays.asList(
            new Word("lutti", "one", R.drawable.number_one, R.raw.test_audio),
            new Word("otiiko", "two", R.drawable.number_two, R.raw.test_audio),
            new Word("tolookosu", "three", R.drawable.number_three, R.raw.test_audio),
            new Word("oyyisa", "four", R.drawable.number_four, R.raw.test_audio),
            new Word("massokka", "five", R.drawable.number_five, R.raw.test_audio),
            new Word("temmokka", "six", R.drawable.number_six, R.raw.test_audio),
            new Word("kenekaku", "seven", R.drawable.number_seven, R.raw.test_audio),
            new Word("kawinta", "eight", R.drawable.number_eight, R.raw.test_audio),
            new Word("wo'e", "nine", R.drawable.number_nine, R.raw.test_audio),
            new Word("na'aacha", "ten", R.drawable.number_ten, R.raw.test_audio)));

    WordAdapter itemsAdapter = new WordAdapter(this, words, getColor(R.color.numbers_category));

    view.setAdapter(itemsAdapter);
}

}

//我知道这样做不是很好,我只是需要做一些事情然后 运行 并在以后担心这些变化。

这是xml:

<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/coolList"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:divider="#B0BEC5"
android:dividerHeight="2dp"
android:background="#212121"
android:focusable="false"
android:focusableInTouchMode="false"></ListView>

这是单词 Class:

public class Word {

private String miwokTranslation;
private String defaultTranslation;
private int ressourceID = -1;  //just init, in order to check for it later
private int audioID;

public Word(String miwokTranslation, String defaultTranslation, int ressourceID, int audioID) {
    this.miwokTranslation = miwokTranslation;
    this.defaultTranslation = defaultTranslation;
    this.ressourceID = ressourceID;
    this.audioID = audioID;
}

public Word(String miwokTranslation, String defaultTranslation, int audioID) {
    this.miwokTranslation = miwokTranslation;
    this.defaultTranslation = defaultTranslation;
    this.audioID = audioID;
}

public String getMiwokTranslation() {
    return miwokTranslation;
}

public String getDefaultTranslation() {
    return defaultTranslation;
}

public int getResourceID() {
    return ressourceID;
}

public int getAudioID() {
    return audioID;
}

@Override
public String toString() {
    return miwokTranslation + "\n" + defaultTranslation;
}
}

这里是对应的适配器:

public class WordAdapter extends ArrayAdapter<Word> {

private final int color;
Context context;

public WordAdapter(@NonNull Context context, @NonNull List<Word> objects, int color) {
    super(context, 0, objects);
    this.color = color;
    this.context = context;
}

@RequiresApi(api = Build.VERSION_CODES.O)
@SuppressLint("ClickableViewAccessibility")
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {

    if (convertView == null) {
        convertView = LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent, false);
    }

    Word item = getItem(position);

    ImageView image = convertView.findViewById(R.id.list_item_icon);

    if(item.getResourceID() == -1) {
        image.setVisibility(View.GONE);
    } else {
        image.setImageResource(item.getResourceID());
    }

    TextView miwokWord = convertView.findViewById(R.id.miwok_word);
    miwokWord.setText(item.getMiwokTranslation());
    miwokWord.setTextColor(color);

    TextView defaultWord = convertView.findViewById(R.id.default_word);
    defaultWord.setText(item.getDefaultTranslation());
    defaultWord.setTextColor(color);

    ImageButton button = convertView.findViewById(R.id.imageButton);
    MediaPlayer mediaPlayer = MediaPlayer.create(context, item.getAudioID());

    button.setOnClickListener(v -> {
        if (!mediaPlayer.isPlaying()) {
            button.setImageResource(R.drawable.play_icon);
            mediaPlayer.start();
        } else {
            button.setImageResource(R.drawable.pause_icon);
            mediaPlayer.pause();
        }
    });
    return convertView;
}
}

这些注释是由于之前的努力而产生的,我没有删除它们,以防我再次需要它们。

最后但同样重要的是,这里是适配器的 xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:minHeight="?android:attr/listPreferredItemHeight"
android:padding="16dp"
android:focusable="true"
android:focusableInTouchMode="false">

<ImageView
    android:id="@+id/list_item_icon"
    android:layout_width="88dp"
    android:layout_height="88dp"
    android:contentDescription="@string/magic"
    android:background="#424242"/>

<LinearLayout
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:orientation="vertical"
    android:paddingStart="16dp"
    tools:ignore="RtlSymmetry">

    <TextView
        android:id="@+id/miwok_word"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:textStyle="bold"/>

    <TextView
        android:id="@+id/default_word"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>

</LinearLayout>

<ImageButton
    android:id="@+id/imageButton"
    android:layout_width="73dp"
    android:layout_height="match_parent"
    android:contentDescription="@string/playsound"
    android:src="@drawable/play_icon"/></LinearLayout>

到目前为止,我已经坐了好几个小时了,但没有任何重大进展,此时我对下一步该做什么一无所知。 任何帮助将不胜感激。

提前致谢

不确定为什么您得出结论说专注与您的问题有关。

如果图标的默认开始状态是 android:src="@drawable/play_icon" 而 mediaPlayer 的默认开始状态是“未播放”,那么第一次点击不会导致 button.setImageResource(R.drawable.play_icon); 只是.. .再次设置播放图标?因此,第一次单击将图标从播放更改为播放,第二次单击将其从播放设置为暂停。

您是否尝试过使用 breakpoint 调试您的代码?在您的点击侦听器中设置一个,看看会发生什么。