我正在努力实现可以在 StickyListHeaders 上看到的这种效果的示例应用程序:
基本上,我需要在 ListView 顶部但在其滚动条下方显示一个单一、静态、固定 标题 View 。我不需要任何与章节或字母索引或类似内容相关的内容。
我无法根据 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);
}
但是不行,没有绘制表头。
最佳答案
回答我自己的问题。这个 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());
}
}
}
它没有经过严格测试,但它是一个很好的起点。
关于android - ListView:在滚动条顶部显示固定标题(或使用 dispatchDraw 在另一个顶部绘制 View ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23371208/