ListView:在滚动条顶部显示固定标题(或使用dispatchDraw在另一个顶部绘制视图)

时间:2014-04-29 17:18:28

标签: android android-layout listview android-listview

我正试图在StickyListHeaders的示例应用上看到这种效果:

基本上我需要在ListView的顶部显示单个,静态,固定标题视图,但是它的滚动条如下。我不需要任何与部分或字母索引或类似内容相关的内容。

我无法根据StickyListHeaders的源代码弄清楚如何执行此操作。我尝试了对ListView进行子类化并覆盖dispatchDraw(),如下所示:

protected void dispatchDraw(Canvas canvas)
{
    View view = LayoutInflater.from(getContext()).inflate(R.layout.header, this, false);
    drawChild(canvas, view, getDrawingTime());
    super.dispatchDraw(canvas);
}

但它不起作用,没有绘制标题。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

回答我自己的问题。这个ListView子类能够做我想要的。列表的第一个元素可以固定调用showFixedHeader()

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ListAdapter;
import android.widget.ListView;

public class FixedHeaderListView extends ListView
{
    private View fixedHeader = null;
    private boolean fixedHeaderLayoutDone = false;
    private boolean showFixedHeader = true;

    @SuppressWarnings("unused")
    public FixedHeaderListView(Context context)
    {
        super(context);
    }

    @SuppressWarnings("unused")
    public FixedHeaderListView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }

    @SuppressWarnings("unused")
    public FixedHeaderListView(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }

    public void showFixedHeader(boolean show)
    {
        this.showFixedHeader = show;
        requestLayout(); // Will cause layoutChildren() and dispatchDraw() to be called
    }

    @Override
    protected void layoutChildren()
    {
        super.layoutChildren();

        if (!fixedHeaderLayoutDone)
        {
            ListAdapter adapter = getAdapter();
            if (adapter != null && adapter.getCount() > 0)
            {
                // Layout the first item in the adapter's data set as the fixed header
                fixedHeader = adapter.getView(0, null, this);
                if (fixedHeader != null)
                {
                    // Measure and layout

                    LayoutParams layoutParams = (LayoutParams)fixedHeader.getLayoutParams();
                    if (layoutParams == null)
                    {
                        layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
                    }

                    int heightMode = MeasureSpec.getMode(layoutParams.height);
                    if (heightMode == MeasureSpec.UNSPECIFIED)
                    {
                        heightMode = MeasureSpec.EXACTLY;
                    }

                    int heightSize = MeasureSpec.getSize(layoutParams.height);
                    int maxHeight = getHeight() - getListPaddingTop() - getListPaddingBottom();
                    if (heightSize > maxHeight)
                    {
                        heightSize = maxHeight;
                    }

                    int widthSpec = MeasureSpec.makeMeasureSpec(getWidth() - getListPaddingLeft() - getListPaddingRight(), MeasureSpec.EXACTLY);
                    int heightSpec = MeasureSpec.makeMeasureSpec(heightSize, heightMode);
                    fixedHeader.measure(widthSpec, heightSpec);
                    fixedHeader.layout(0, 0, fixedHeader.getMeasuredWidth(), fixedHeader.getMeasuredHeight());

                    // Flag as layout done
                    fixedHeaderLayoutDone = true;
                }
            }
        }
    }


    @Override @SuppressWarnings("NullableProblems")
    protected void dispatchDraw(Canvas canvas)
    {
        super.dispatchDraw(canvas);

        if (fixedHeader != null && showFixedHeader)
        {
            drawChild(canvas, fixedHeader, getDrawingTime());
        }
    }

}

它没有经过严格测试,但它是一个很好的起点。