繁体   English   中英

插入到ScrollView的头部,无需移动

[英]Insert to head of ScrollView without shifting

我正在创建一个聊天应用程序,启动时它将显示对话中的20条最新消息。 滚动到顶部时,可以按一个按钮以显示较早的消息。 很典型。 唯一的问题是,我希望UI元素在按下按钮后保持其位置。 此刻他们转移了。 我已经创建了我遇到的问题的简化版本。

按下按钮之前 按下按钮之前

按下按钮后 按下按钮后

正如您可能已经猜到的那样,我希望这样做,以便在按下按钮后,带有标签51(TextView-51)的TextView好像没有移动一样。 我最初的计划是在按下按钮之前,然后在按下按钮之后,获取TextVie-51的位置,并设置ScrollView的Y位置。 但是,该方法不起作用,因为在我检查View时还没有膨胀。

这是布局xml

<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/TestScroller">


    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:id="@+id/mainContainer" >

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/TestButton"
            android:layout_centerHorizontal="true"
            android:layout_alignParentTop="true"
            android:onClick="insertMore"
            android:text="Get Earlier Messages" />
    </RelativeLayout>
</ScrollView>

这是活动的代码。

protected void onCreate(Bundle savedInstanceState)
{
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.test);

    lastId = R.id.TestButton;
    firstId = -1;

    RelativeLayout rl = (RelativeLayout)findViewById(R.id.mainContainer);

    //1. Create fifty TextViews and put them under the button.
    for (int i = 51; i <= 100; i++)
    {
        TextView tv = new TextView(this);
        tv.setText(Integer.toString(i));
        tv.setId(i + 100);

        final int WC = RelativeLayout.LayoutParams.WRAP_CONTENT;
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(WC, WC);
        params.addRule(RelativeLayout.BELOW, lastId);

        tv.setLayoutParams(params);

        lastId = tv.getId();

        if (firstId == -1)
            firstId = tv.getId();

        rl.addView(tv);
    }
}

public void insertMore(View view)
{
    //Create fifty more TextViews and insert them between the button and
    //the already created textviews.
    RelativeLayout rl = (RelativeLayout)findViewById(R.id.mainContainer);
    lastId = R.id.TestButton;

    for (int i = 0; i <= 50; i++)
    {
        TextView tv = new TextView(this);
        tv.setText(Integer.toString(i));
        tv.setId(i + 100);

        final int WC = RelativeLayout.LayoutParams.WRAP_CONTENT;
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(WC, WC);
        params.addRule(RelativeLayout.BELOW, lastId);

        tv.setLayoutParams(params);

        lastId = tv.getId();
        rl.addView(tv);
    }

    //Now make sure the textview with the label 51 under it is underneath the last
    //view we just added.
    TextView tv = (TextView)findViewById(firstId);
    RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)tv.getLayoutParams();
    params.addRule(RelativeLayout.BELOW, lastId);
    tv.setLayoutParams(params);

    //Remove the button
    Button button = (Button)findViewById(R.id.TestButton);
    rl.removeView(button);
}

基于您的第一个想法,即在添加textviews之后滚动到列表的底部,您是否尝试调用requestLayout()来强制布局更新:

public void insertMore(View view)
{
// Create and add your 50 views
...

// force Update layout 
rl.requestLayout();

scrollView.post(new Runnable() {
     @Override
     public void run() {
         // Scroll to scrollviews bottom
         scrollView.scrollTo(0, scrollView.getBottom());
     }
});

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM