我正在制作某种“卡拉OK”Android应用程序 所以,基本上,我有一些TextViews,我想在播放音频时以编程方式更改文本颜色。
TextViews具有“begin_time”和“end_time”属性,这些属性与音频文件中的位置有关
使用MediaController播放音频并收集有关信息的信息很简单
所以,现在我正在尝试动态改变颜色......我尝试了一个单独的线程和许多其他方法,但我总是坚持同样的问题
“android.view.ViewRoot $ CalledFromWrongThreadException:只有 创建视图层次结构的原始线程可以触及其视图。 “
我试图了解更多相关信息,我学到的是与UI相关的所有内容都必须在UI线程中完成。 大多数人使用处理程序在后台线程中执行GUI更新。但是我没有让这个该死的东西成功...所以关于处理程序及其工作方式的任何建议都是受欢迎的。
无论如何,为什么不使用AsyncTask? 引用“进程和线程开发指南”
“也许最好的解决方案是扩展AsyncTask类, 这简化了需要的工作线程任务的执行 与UI交互。 “
实际上,我正在使用这个AsyncTask,但它没有“简化”线程
或者也许他们是时间事件中GUI更新的另一种解决方案?
嗯,事实上,我不想制作“只是一个卡拉OK”Textview必须是可点击的,所以当用户点击一个单词时,音频会转到音频中的那个位置,而textview颜色必须改变动态
所以,我想过使用动画来平滑变色。或者也许是TransitionDrawable,但它使用图层和画布。
我也发现了这一点,使用ForegroundColorSpan:
Spannable WordtoSpan = new SpannableString("I know just how to whisper");
WordtoSpan.setSpan(new ForegroundColorSpan(Color.BLUE), 1, 13, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
TextView tv = new TextView(context).setText(WordtoSpan);
但由于计算了ForegroundColorSpan的结束,不确定它是否足够动态。
因此,考虑仅使用TextView,实现动态textview颜色更改的最佳方法是什么(使用这些解决方案或其他任何方法)?
第二次编辑
好吧,我差不多完成了这个项目...... 我现在能够随着时间的推移动态着色字,但问题是它与音频不同步。
即: 让我们来一句如“你好,我的名字是约翰,我的工作迟到” 如果音频正在播放[我],彩色文字是[作业]
所以,这只是一个同步问题,但我已经面临了几个星期。
文本被组织成链接列表 链表的元素是Object(因为我有Word和Ponctuation类),但它们都有一个开始和结束位置,对应于它们在音频中的相对位置(以毫秒为单位)。
所以...我有类似的东西: 您好:begin = 0,end = 1000 我的:开始= 1200,结束= 1400 等等...
在现在的主要活动中,我有一个处理文本着色的Runnable 我还有3个Object,previous_element,current_element和next_element
在runnable开始时,previous_element的颜色被设置回White,因此只有当前单词被着色。 然后,current_element的颜色设置为黄色,或者其他...... 然后,我检查next_element.getBegin()> =音频中的当前位置 ...如果是,那意味着当前单词现在已经结束,所以我将current_element更改为next_element,并使用Handler.post重启该进程(MyRunnableThatDoesColoration)
所以我不明白哪里出错了 如果有人有线索吗?
答案 0 :(得分:0)
“android.view.ViewRoot $ CalledFromWrongThreadException:只有 创建视图层次结构的原始线程可以触及其视图。 “
这可以通过使用runOnUIThread:
来实现runOnUiThread(new Runnable() {
public void run() {
//Your UI Changing code HERE!
}
});
如果你把卡拉OK视为基本的gui(textViews),我认为它不够动态。您应该使用Android Canvas
或gameEngine
(Andengine ..)。