java - ScrollView 不在线程中以编程方式滚动
问题描述
所以我想做的基本上是在客户端应用程序发送命令时滚动滚动视图。方法 handleScrolling() 在 onCreate() 中工作,但每当我从线程调用它时,它不会滚动。我认为从 Thread 调用它是问题所在。
public class TeleprompterActivity extends Activity {
static ScrollView mScrollView;
TextView teleprompterTextView;
String message;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_teleprompter);
teleprompterTextView = findViewById(R.id.teleprompter_text_view);
teleprompterTextView.setText(MainActivity.contents);
mScrollView = findViewById(R.id.scroll);
Thread mThread = new Thread(new ServerClass());
mThread.start();
handleScrolling(3, true);
Log.e("TELE", "handleScrolling at start onCrete");
}
void handleScrolling(final int numLines, final boolean next) {
mScrollView.post(new Runnable() {
public void run() {
int currPosition = mScrollView.getScrollY();
int textSize = (int) teleprompterTextView.getTextSize();
if (next) {
int newPos = currPosition + (textSize * numLines);
mScrollView.smoothScrollTo(0, newPos);
}
if (!next) {
int newPos = currPosition - (textSize * numLines);
if (newPos < 0) {
newPos = 0;
}
mScrollView.scrollTo(0, newPos);
}
}
});
}
void handleMessage(String message) {
if (message.contains("NEXT:")) {
try {
int numLine = Integer.parseInt(message.substring(5));
handleScrolling(numLine, true);
return;
} catch (NumberFormatException nFE) {
nFE.printStackTrace();
Toast.makeText(TeleprompterActivity.this, "Number Format Exception", Toast.LENGTH_SHORT).show();
}
}
if (message.contains("BACK:")) {
try {
int numLine = Integer.parseInt(message.substring(5));
handleScrolling(numLine, false);
} catch (NumberFormatException nFE) {
nFE.printStackTrace();
Toast.makeText(TeleprompterActivity.this, "Number Format Exception", Toast.LENGTH_SHORT).show();
}
}
}
public class ServerClass implements Runnable {
ServerSocket serverSocket;
Socket socket;
DataInputStream dataInputStream;
String receivedData;
Handler handler = new Handler();
@Override
public void run() {
try {
serverSocket = new ServerSocket(8080);
Log.e("TELE", "WAITIN FOR CLIENT");
while (true) {
socket = serverSocket.accept();
dataInputStream = new DataInputStream(socket.getInputStream());
receivedData = dataInputStream.readUTF();
handler.post(new Runnable() {
@Override
public void run() {
message = receivedData;
handleMessage(message);
}
});
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
handleScrolling() 方法在线程外调用时可以完美运行。是参考问题还是类似的问题。谢谢..
解决方案
永远不要直接从线程更新 UI 组件,调用 Activity 的 runOnUiThread 以便您可以使用如下代码构造:
public class TeleprompterActivity extends Activity {
static ScrollView mScrollView;
TextView teleprompterTextView;
String message;
Activity thisActivity;//<--- used for saving reference to this Activity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_teleprompter);
teleprompterTextView = findViewById(R.id.teleprompter_text_view);
teleprompterTextView.setText(MainActivity.contents);
mScrollView = findViewById(R.id.scroll);
thisActivity = this;//<---- saving a reference to this activity
Thread mThread = new Thread(new ServerClass());
mThread.start();
handleScrolling(3, true);
Log.e("TELE", "handleScrolling at start onCrete");
}
void handleScrolling(final int numLines, final boolean next) {
thisActivity.runOnUiThread(new Runnable()//<--used thisActivity.runOnUiThread here
{
public void run() {
int currPosition = mScrollView.getScrollY();
int textSize = (int) teleprompterTextView.getTextSize();
if (next) {
int newPos = currPosition + (textSize * numLines);
mScrollView.smoothScrollTo(0, newPos);
}
if (!next) {
int newPos = currPosition - (textSize * numLines);
if (newPos < 0) {
newPos = 0;
}
mScrollView.scrollTo(0, newPos);
}
}
});
}
推荐阅读
- python - 在我的 If 语句中,变量不会重置为 0
- python - 在 Python 中改进饼图图形
- html - 导航栏颜色不是全宽
- bootstrap-4 - 带有非流体容器的 Bootstrap 侧边栏
- http - CORS:简单请求的目的是什么?
- html - 为什么 PowerShell 将包含 # 的 HTML 视为注释?
- bash - 进入目录时如何确保使用了同名的自定义工具?
- docker - Docker - Golang 找不到包
- r - 如何将每个数据框放入列表中的每个对应子列表中
- java - 下载 adview 后,Android Studio 中的 Manifest Merger 失败