如何同步Android tts与recyclerview平滑滚动
好吧,所以我有一个回收站视图,我添加了一堆文本,文本是在固定的高度和宽度的卡片,当我按下按钮时,文本被读出使用androids TTS引擎。如何同步Android tts与recyclerview平滑滚动
问题是如果文本超出视图中的空间我希望回收视图滚动到文本/回收站视图的开始位置,读出文本并滚动视图,同时保持或减慢与Android tts引擎,所以我已经在我的回收视图上设置了一个自定义的linearlayoutmanager,在here的帮助下,我可以根据浮点变量加快或减慢滚动速度,然后尝试通过几种方法完成此操作无果,我发现我需要使用UtteranceProgressListener,所以我创建了一个更新的卡的位置的方法,并试图这样传递给UtteranceProgressListener这样
public void speakWordsExclusive(String speech, final int position) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
myTTS.speak(speech, TextToSpeech.QUEUE_ADD, params, "");
}
else{
myTTS.speak(speech, TextToSpeech.QUEUE_ADD, map);
}
myTTS.setOnUtteranceProgressListener(new UtteranceProgressListener() {
@Override
public void onStart(final String utteranceId) {
}
@Override
public void onDone(final String utteranceId) {
runOnUiThread(new Runnable() {
@Override
public void run() {
//position should print 1,2,3, etc but just gives me the last number
System.out.println("position UtteranceProgress " + position);
//the line below will smooth scroll the view to the end position with
//no care for which cards is being read
SpeakGridDB.recyclerView.getLayoutManager()
.smoothScrollToPosition(SpeakGridDB.recyclerView, null, position);
}
});
}
@Override
public void onError(String utteranceId) {
}
});
}
这不工作的位置永远只是数量最多,所以如果我正期待1,2,3,4我实际上只得到4这样,
11-07 14:23:09.121 28882-28882/ss.sealstudios.com.socialstories
I/System.out: position UtteranceProgress 4
11-07 14:23:09.741 28882-
28882/ss.sealstudios.com.socialstories
I/System.out: position UtteranceProgress 4
11-07 14:23:10.353 28882-
28882/ss.sealstudios.com.socialstories
I/System.out: position UtteranceProgress 4
11-07 14:23:10.944 28882-
28882/ss.sealstudios.com.socialstories
I/System.out: position UtteranceProgress 4
我给UtteranceProgressListener从下面的方法中的位置
public void speakAndMoveExclusive() {
final ArrayList<String> list = new ArrayList<>();
list.clear();
words = list.toString();
SpeakGridDB.recyclerView.getLayoutManager().scrollToPosition(0);
for (int i = 0; i < SpeakGridDB.cardMakerList.size(); i++) {
list.add(SpeakGridDB.cardMakerList.get(i).getCardSpeech());
words = list.toString();
}
System.out.println(words);
if (words == null) {
speakWords("");
} else if (words.contains(", 's")) {
formatString = words.replaceFirst(", 's", "'s");
} else if (words.contains(", ing")) {
formatString = words.replaceFirst(", ing", "ing");
}else{
formatString = words;
}
List<String> items = Arrays.asList(formatString.split("\\s*,\\s*"));
if (items.contains("[]")){
speakWords("");
}
else{
for(int j = 0; j < items.size();j++){
speakWordsExclusive(items.get(j), j);
//the below line prints the position just fine
System.out.println("position j " + j);
params.putString
(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,"UniqueID" + j);
map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,"UniqueID" +
j);
}
}
}
在这里位置可变IVE集心不是很明显的位置却是相同的,并且打印出反映,像下面
11-07 14:23:08.452 28882-28882/ss.sealstudios.com.socialstories
I/System.out: position j 0
11-07 14:23:08.454 28882-28882/ss.sealstudios.com.socialstories
I/System.out: position j 1
11-07 14:23:08.456 28882-28882/ss.sealstudios.com.socialstories
I/System.out: position j 2
11-07 14:23:08.459 28882-28882/ss.sealstudios.com.socialstories
I/System.out: position j 3
如果我只是把这个给一个静态的int并把它给onUtteranceProgressListener然后我得到一个稍好的结果,但它仍然没有同步在一起
所以我想知道他们之间发生了什么我看过文档,似乎无法理解它我已经将我的调用移动到onStart而不是onDone希望获得更好的结果,但没有任何更改可以帮助我吗?
确定像@brandall说其设置一个UtteranceProgressListener一次,最好从onInit(int initStatus),所以我切换到这个模型,并让它工作,我的代码一般用于滚动视图,注意代码我会贴抛出onDone一个NPE在那里我设置背景色用的东西,鉴于它不是做确保你从UI线程更新视图
public void onInit(int initStatus) {
if (initStatus == TextToSpeech.SUCCESS) {
myTTS.setLanguage(Locale.UK);
//myExclusiveTTS.setLanguage(Locale.UK);
myExclusiveTTS.setOnUtteranceProgressListener(new
UtteranceProgressListener() {
@Override
public void onDone(String utteranceId) {
runOnUiThread(new Runnable() {
@Override
public void run() {
SpeakGridDB.recyclerView.getLayoutManager()
.getChildAt(cardCountPosition)
.setBackgroundResource(R.drawable.border);
cardCountPosition ++;
if(cardCountPosition ==
SpeakGridDB.cardMakerList.size()){
cardCountPosition = 0;
}
}
});
}
@Override
public void onError(String utteranceId) {
}
@Override
public void onStart(String utteranceId) {
runOnUiThread(new Runnable() {
@Override
public void run() {
moveView();
SpeakGridDB.recyclerView.getLayoutManager()
.getChildAt(cardCountPosition).setBackgroundResource
(R.drawable.selected_blue_border);
}
});
}
});
} else if (initStatus == TextToSpeech.ERROR) {
Toast.makeText(this, "Oops sorry! Text To Speech failed...
SimpleAAC cannot fix this", Toast.LENGTH_LONG).show();
}
}
public void moveView(){
runOnUiThread(new Runnable() {
@Override
public void run() {
if (cardCountPosition < SpeakGridDB.cardMakerList.size()){
SpeakGridDB.recyclerView.getLayoutManager()
.smoothScrollToPosition(SpeakGridDB.recyclerView, null,
cardCountPosition + 1);
}
else{
//this is never called
cardCountPosition = 0;
}
}
});
}
你是一个新的'UtteranceProgressListener'每次设定你的'speakWordsExclusive'方法,因此一个新的可运行。尝试子类化'UtteranceProgressListener'。同时删除将RecyclerView更新为单独的方法并对其进行同步。这应该有助于您进一步观察问题。 – brandall
非常感谢我想出了一些东西,但是如果你不介意看一看@brandall,那么它就不能工作了 –