ScrollView中的ListView - 小错误

时间:2013-10-31 12:54:56

标签: android android-layout listview android-listview android-scrollview

我希望在scrollview中有一个列表视图。这种方法几乎是完美的:https://stackoverflow.com/a/3495908/2811653

当我输入更多文本而不是一行时,会出现错误:

1:http://abload.de/img/screenshot_2013-10-311jq5t.jpg

2:http://abload.de/img/screenshot_2013-10-31lvrad.jpg

向下滚动到按钮工作正常,但在第二个屏幕截图中看到P未正确显示: - (

在Utility类中,当我填充listview的第一行时,高度计算不正确。

有谁知道如何修复它?

(提示:主要是我要滚动到列表视图下方的按钮。我不想总是显示按钮(所以没有重量= 1))

代码:

package com.example.tmpapplication;

import android.app.ListActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;

public class MainActivity extends ListActivity {

static final String[] data=new String[]
{
        "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
        "B",
        "C",
        "D",
        "E",
        "F",
        "G",
        "H",
        "I",
        "J",
        "K",
        "L",
        "M",
        "N",
        "O",
        "P"
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    setListAdapter(new ArrayAdapter<String>(this, R.layout.list, data));

    ListView listView=(ListView) findViewById(android.R.id.list);
    Utility.setListViewHeightBasedOnChildren(listView);
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}
}

class Utility {
public static void setListViewHeightBasedOnChildren(ListView listView) {
    ListAdapter listAdapter = listView.getAdapter();
    if (listAdapter == null) {
        // pre-condition
        return;
    }

    int totalHeight = 0;
    for (int i = 0; i < listAdapter.getCount(); i++) {
        View listItem = listAdapter.getView(i, null, listView);
        listItem.measure(0, 0);
        totalHeight += listItem.getMeasuredHeight();
    }

    ViewGroup.LayoutParams params = listView.getLayoutParams();
    params.height = totalHeight + (listView.getDividerHeight() *  (listAdapter.getCount() - 1));
    listView.setLayoutParams(params);
    }
}

XML: activity_main.xml中

<ScrollView  xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity"
android:orientation="vertical"
>

<ListView
    android:id="@android:id/list"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" >
</ListView>

<Button
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button"
    >
</Button>

list.xml:

<?xml version="1.0" encoding="utf-8"?>

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:hint="text"
    android:padding="10dp"
    android:textSize="20sp"
/>

2 个答案:

答案 0 :(得分:0)

将列表视图放在相对布局中,将按钮放在另一个布局中。 listview本身是可滚动的,因此您无需将列表视图放在滚动视图中。这没用。

通过将按钮放在另一个布局中,您将能够轻松滚动列表视图,并且您的按钮将在布局下方显示

答案 1 :(得分:0)

尝试我发布here

的解决方案

如果您不希望ListView本身滚动并且只希望ListView的高度显示所有元素,那么您可以创建ListView的子类来完成此任务。

public class ListViewForEmbeddingInScrollView extends ListView {
    public ListViewForEmbeddingInScrollView(Context context) {
        super(context);
    }

    public ListViewForEmbeddingInScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ListViewForEmbeddingInScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 4, MeasureSpec.AT_MOST));
    }
}

使用非常大的大小(Integer.MAX_VALUE&gt;&gt; 4)操作heightMeasureSpec为AT_MOST会导致ListView测量其所有子节点,直到给定(非常大)的高度并相应地设置其高度。

关于这个问题here有很多讨论,包括很多关于是否适合这样做的讨论。我没有足够的声誉在那里发布我的答案,但这比该链接中的任何解决方案都要好。也许拥有更多声誉的人会遇到这种情况并在另一个问题上发布一个解决方案,该问题可以链接到这个问题。