1

我正在开发一个包含聊天功能的应用程序,当输入新消息时,它会将其存储到内部存储器中的文件中。此外,当我输入新消息时,它会自动滚动到 editText 的底部(消息所在的位置),并且在第一次尝试时工作正常,但是当我再次打开应用程序并从文件中加载历史记录时,自动滚动不再正常工作,因为虽然也滚动到底部,但它隐藏了最后一行文本。

这是 .java 文件:

public class ChatActivity extends Activity {

private static EditText messageHistory;
//
private EditText messageInput;
//
private Button sendButton;
//
private ScrollView scroller;

@Override
public void onCreate (Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.chat);

    //Prevents the keyboard from appearing when not rquested
    getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

    ProjectData.chatLogFile = new FileHandler(getApplicationContext(), ProjectData.CHAT_LOG_FILE);
    ProjectData.chatLogFile.create();

    getViews();

    getChatLog();

    addListennerOnButton();
}

/**
 * Finds all the views in this activity and stores them in global variables
 */
private void getViews ()
{
    messageHistory = (EditText) findViewById(R.id.messageHistory);
    messageInput = (EditText) findViewById(R.id.messageInput);
    sendButton = (Button) findViewById(R.id.sendButton);
    scroller = (ScrollView) findViewById(R.id.historyScroller);
}

private void getChatLog ()
{
    messageHistory.setText(ProjectData.chatLogFile.getData());
    scroller.scrollTo(0, messageHistory.getBottom());
}

private void addListennerOnButton ()
{
    sendButton.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            if (!messageInput.getText().toString().equals(""))
            {
                newMessage(messageInput.getText().toString(), 0);
                scroller.scrollTo(0, messageHistory.getBottom());
                messageInput.setText("");
            }
        }
    });
}

public static void newMessage (final String msg, int id)
{
    StringBuilder strBuilder = new StringBuilder();
    switch (id) {
        case 0: strBuilder.append("User:\n");break;
        case 1: strBuilder.append("PC Medic:\n");
        default: break;
    }

    strBuilder.append(msg + "\n");
    messageHistory.append(strBuilder.toString());
    messageHistory.refreshDrawableState();
    ProjectData.chatLogFile.addData(strBuilder.toString());
}

@Override
public boolean onCreateOptionsMenu (Menu menu)
{
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.options_menu, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) 
{
    Intent intent;
    switch (item.getItemId()) {
        case R.id.menuFAQ:
            intent = new Intent();
            intent.setClass(getApplicationContext(), FAQActivity.class);
            startActivity(intent);
            return true;
        case R.id.menuConfig:
            intent = new Intent();
            intent.setClass(getApplicationContext(), PrefActivity.class);
            startActivity(intent);
            return true;
        case R.id.menuAbout:
            intent = new Intent();
            intent.setClass(getApplicationContext(), AboutActivity.class);
            startActivity(intent);
            return true;
        case R.id.menuExit:
            intent = new Intent();
            intent.setClass(getApplicationContext(), BackgroundService.class);
            stopService(intent);
            setResult(ProjectData.EXIT_CODE);
            finish();
            return true;
        default:
            return false;
    }
}
}

和 .xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
android:id="@+id/chatMainLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<ImageView
    android:id="@+id/logoChat"
    android:layout_width="match_parent"
    android:layout_height="90dp"
    android:scaleType="fitStart"
    android:adjustViewBounds="true"
    android:src="@drawable/logo_top"
    android:contentDescription="@string/logo" />


<ScrollView
    android:id="@+id/historyScroller"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:fillViewport="true"
    android:layout_weight="1" >

    <EditText
        android:id="@+id/messageHistory"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:background="@color/black"
        android:clickable="true"
        android:editable="false"
        android:focusable="false"
        android:gravity="top"
        android:inputType="textMultiLine"
        android:textColor="@color/white" />
</ScrollView>

<EditText 
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:inputType="none"
    android:focusable="true" />


<LinearLayout
    android:id="@+id/chatBottomLayout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >


    <EditText
        android:id="@+id/messageInput"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:maxHeight="60dp"
        android:nextFocusLeft="@id/messageInput"
        android:nextFocusUp="@id/messageInput"
        android:hint="@string/message_input"
        android:layout_weight="1"
        android:textColor="@color/gray"
        style="@style/textInput" />
    <Button 
        android:id="@+id/sendButton"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="3"
        android:text="@string/send" />

</LinearLayout>

任何人都可以看到甚至理解这个问题吗?

提前致谢,

里卡多·阿门多埃拉

4

2 回答 2

2

Sana 的回答让我解决了自己的问题。我认为您需要允许 TextView 重新计算窗口边界,因此请尝试将您的 scrollTo() 方法包装在 post Handler中。

请参阅下面的代码:

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    scrollView.post(new Runnable() {
        @Override
        public void run () {
            scrollView.scrollTo(0, 500);
        }
    });
}
于 2013-01-07T13:54:46.850 回答
0

这里的问题是展示你的观点。当您在 onCreate 方法中布局视图时,它还没有完全膨胀,并且在滚动到第一行时可以正常工作,因此您可能希望将您的方法getChatLog();放入

@Override
 public void onWindowFocusChanged(boolean hasFocus) {
  // TODO Auto-generated method stub
  super.onWindowFocusChanged(hasFocus);
  getChatLog();
 }

让我知道它是否有效。

这是一个非常有趣的问题。

于 2012-06-05T18:00:01.177 回答