我想在RecylerView中的每一项显示给用户后对其进行检测。
基本上,我试图在每个项目加载到屏幕上后播放声音。
但是每当屏幕上加载了每个项目时,我都无法检测到!我必须调用任何方法来检测渲染的每个项目
E.g 1st RecyclerView item displayed -> play sound
2st RecyclerView item displayed -> play sound...
我的适配器类看起来像这样-
public class AdapterListAnimation extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<Multiples> items = new ArrayList<>();
private Context ctx;
private OnItemClickListener mOnItemClickListener;
private int animation_type = 0;
.........
.........
我正在从initComponent()
方法中调用此onCreated()
方法。您能为我如何实现上述目标提供建议吗?
private void initComponent() {
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
items = DataGenerator.getPeopleData(this,of,value);
setAdapter();
/* MediaPlayer mp=MediaPlayer.create(this, R.raw.sword);
if (mp.isPlaying()) {
mp.stop();
mp.release();
mp = MediaPlayer.create(this, R.raw.sword);
} mp.start();*/
}
private void setAdapter() {
// Set data and list adapter
mAdapter = new AdapterListAnimation(this, items, animation_type);
recyclerView.setAdapter(mAdapter);
// on item list clicked
mAdapter.setOnItemClickListener(new AdapterListAnimation.OnItemClickListener() {
@Override
public void onItemClick(View view, com.math.multiplication.model.Multiples obj, int position) {
Snackbar.make(parent_view, "Item " + obj.first + " clicked", Snackbar.LENGTH_SHORT).show();
}
});
}
答案 0 :(得分:2)
您需要覆盖onViewAttachedToWindow
和onViewDetachedFromWindow
。但是要检测破洞类型,您需要getItemViewType()
就像这样:
public class PostAdapter extends RecyclerView.Adapter {
@Override
public int getItemViewType(int position) {
switch (types.get(position)){
case 1:
return 1;
case 2:
return 2;
default:
return position;
}
}
@Override
public void onViewAttachedToWindow(@NonNull RecyclerView.ViewHolder holder) {
super.onViewAttachedToWindow(holder);
if (holder.getItemViewType() == 1){
//play song
}
}
@Override
public void onViewDetachedFromWindow(@NonNull RecyclerView.ViewHolder holder) {
super.onViewDetachedFromWindow(holder);
if (holder.getItemViewType() == 1){
//pause song
}
}
答案 1 :(得分:0)
您只需在适配器中使用onViewAttachedToWindow(VH)。 参见https://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter.html#onViewAttachedToWindow(VH)
更新:
您知道,RecyclerView
对于每个项目仅被调用一次OnBindViewHolder
。
如果项目的位置在数据集中发生更改,RecyclerView将不会再次调用此方法,除非该项目本身无效或无法确定新位置。
因此您可以使用onViewAttachedToWindow
(onViewAttachedToWindow)在此适配器创建的视图附加到窗口时调用。
这可以用作合理的信号,表明用户将看到 视图。 。如果适配器先前释放了onViewDetachedFromWindow中的任何资源,则应将这些资源在这里恢复。
您可以像这样使用它:
public class Adapter extends RecyclerView.Adapter<MyViewHolder> {
// rest of your code
@Override
public void onViewAttachedToWindow(MyViewHolder holder) {
super.onViewAttachedToWindow(holder);
// play your sound
}
}
希望有帮助!
答案 2 :(得分:0)
您需要为TTS添加侦听器。然后更新您的RecyclerView
以在语音开始和结束时显示正确的图像。
我已经创建了一个测试项目来展示如何实现它。 Here,您会看到它是如何工作的。 Here是我的github存储库。
这是我的MainActivity
类的主要部分。
private void initTts() {
tts = new TextToSpeech(this, this);
tts.setLanguage(Locale.US);
tts.setOnUtteranceProgressListener(new MyListener());
}
@Override
public void onInit(int status) {
playSound(0);
}
private void playSound(int index) {
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, String.valueOf(index));
tts.speak(data.get(index), TextToSpeech.QUEUE_ADD, hashMap);
}
class MyListener extends UtteranceProgressListener {
@Override
public void onStart(String utteranceId) {
int currentIndex = Integer.parseInt(utteranceId);
mMainAdapter.setCurrentPosition(currentIndex);
handler.post(new Runnable() {
@Override
public void run() {
mMainAdapter.notifyDataSetChanged();
}
});
}
@Override
public void onDone(String utteranceId) {
int currentIndex = Integer.parseInt(utteranceId);
mMainAdapter.setCurrentPosition(-1);
handler.post(new Runnable() {
@Override
public void run() {
mMainAdapter.notifyDataSetChanged();
}
});
if (currentIndex < data.size() - 1) {
playSound(currentIndex + 1);
}
}
@Override
public void onError(String utteranceId) {
}
}
答案 3 :(得分:0)
如果我正确理解了您的问题,则想在装入RecyclerView
中的项目时播放声音。
因此,我想在这里考虑一种解决方法。您可以考虑在播放上一个项目的声音之后添加一个项目。
我想为我要解释的内容提供一个伪代码。如果您的声音已停止播放,则可以考虑使用documentation进行监听,然后将下一项添加到RecyclerView
,然后在适配器上调用notifyDataSetChanged
以将下一项加载到{ {1}}。
因此,您可能首先需要在适配器中进行以下修改。
RecyclerView
现在在设置// Declare a function in your adapter which adds new item in the RecyclerView
public void addItem(Multiples item) {
items.add(item);
notifyItemInserted(items.size());
}
的{{1}}中,您需要具有以下数组。
Activity
如下修改功能。
RecyclerView
随着ArrayList<Multiples> allItems = new ArrayList<Multiples>(); // This list will contain all the data
int soundToBePlayed = -1; // Initialize the value with -1
ArrayList<Integer> soundList = getAllSoundsInAList();
从构造函数中删除,您还需要修改适配器的构造函数。只需删除采用private void initComponent() {
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
allItems = DataGenerator.getPeopleData(this,of,value);
setAdapter();
}
private void setAdapter() {
mAdapter = new AdapterListAnimation(this, animation_type); // Do not pass the items list
recyclerView.setAdapter(mAdapter);
// .. Your item click listener goes here
}
的变量即可。因为稍后我们将向items
添加元素。
然后,您需要编写另一个函数,在调用items
函数之后,需要在活动的items
函数中调用该函数。该函数应如下所示。
onCreate
我尚未测试代码,但是,我认为您已经明白了。也可以在适配器内部使用initComponent
来实现。输精管技巧是您的选择。