java - ScrollView 不会在线程中以编程方式滚动

标签 java android

所以我想做的基本上是在客户端应用程序发送命令时滚动 ScrollView 。方法handleScrolling()在onCreate()中工作,但是每当我从线程调用它时,它就不会滚动。我认为从线程调用它是问题所在。

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);
            }
        }
    });
}

关于java - ScrollView 不会在线程中以编程方式滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59325477/

相关文章:

java - 返回元素集合的 Java 方法的正确命名约定是什么?

java - 避免使用instanceof,但将函数参数限制为父类(super class)的一组子类

android - 包管理器找不到已知的包名称

使用Charles的Android手机无法连接互联网

android - 使用 Firebase 应用分发服务导致应用未安装错误

Android 熄灯模式不起作用

java - 使用Java发送POST数据

java - 创建 onItemClickListener 时出现问题

java - Spring REST - 创建 ZIP 文件并将其发送到客户端

java - IllegalStateException: <MyFragment> 当前不在 FragmentManager 中