我有一个扩展ListView
的自定义。该列表是在这样的布局中定义的:Adapter
CursorAdapter
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<ProgressBar
android:id="@android:id/empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/ProgressBar.Itasa.Indeterminate.Large"/>
<net.italiansubs.droitasa.widget.HookedListView
android:id="@android:id/list"
style="@style/NewsList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"/>
</RelativeLayout>
HookedListView
看起来像这样:
package net.italiansubs.droitasa.widget;
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.widget.ListView;
import net.italiansubs.droitasa.util.OnLayoutChangedListener;
/**
* An extended ListView that has an hook for getting layout changes.
*
* @author Sebastiano Poggi, Francesco Pontillo
*/
public class HookedListView extends ListView {
private OnLayoutChangedListener mLayoutListener;
private final Handler mHandler;
private boolean mFirstLayout = true;
public HookedListView(Context context) {
super(context);
mHandler = new Handler(context.getMainLooper());
}
public HookedListView(Context context, AttributeSet attrs) {
super(context, attrs);
mHandler = new Handler(context.getMainLooper());
}
public HookedListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mHandler = new Handler(context.getMainLooper());
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (mFirstLayout) {
// In this case we want to avoid posting, because this could
// have the two layout passes happen one after the other with
// a pause between each other, with the effects, for example,
// of having the number of columns change
mFirstLayout = false;
new LayoutChangedRunnable().run();
}
else if (changed) {
mHandler.postAtFrontOfQueue(new LayoutChangedRunnable());
}
}
/**
* Sets the OnLayoutChangedListener for this instance, that will
* receive callbacks after layout changes for the View.
*
* @param l The new OnLayoutChangedListener, or null to remove
* the current listener.
*/
public void setOnLayoutChangedListener(OnLayoutChangedListener l) {
mLayoutListener = l;
}
/**
* Gets the OnLayoutChangedListener set for this instance.
*
* @return Returns the instance's OnLayoutChangedListener, if any.
*/
public OnLayoutChangedListener getOnLayoutChangedListener() {
return mLayoutListener;
}
private class LayoutChangedRunnable implements Runnable {
@Override
public void run() {
// We don't need to synchronize on the listener because the handler
// is hooked up to the main thread's looper so we shouldn't be
// called from other threads.
if (mLayoutListener != null) {
mLayoutListener.onLayoutChanged(HookedListView.this);
}
}
}
}
我遇到的问题是ListView
内容没有出现在设备上,即使Cursor
有项目,Adapter
有项目,ListView
本身也有项目。将HierarchyViewer附加到窗口确实可以使ListView
项目在没有任何进一步干预的情况下出现,并且请求从 web 服务更新数据也是如此,这反过来会更新ContentProvider
. Cursor
我已经尝试为和设置内容观察器Adapter
,并记录以确保将正确数量的项目设置为Adapter
,并且一切都按预期工作。由于我们的自定义,我们已经在 List 上执行了一轮额外的布局MultiCoumnAdapter
,计算第一轮之后的列数ListView
布局传递(因此需要 a HookedListView
)。
我尝试过使用标准CursorAdapter
,而不是我自己的MultiColumnAdapter
(模拟 a GridView
,没有所有限制和错误),但这并没有改变任何东西。
Fragment
是Activity
;的唯一内容 本身基本上什么也不做,只是从用于启动它Activity
的附加组件中获取项目 ID ,并将其传递给,它在的布局 XML 中定义为唯一的元素。Intent
Fragment
Activity
所做的Fragment
只是处理ContentProvider
使用标准从应用程序获取数据CursorLoader
。我们使用DataDroid来管理从 web 服务获取新数据。
有没有人对这里发生的事情有丝毫线索?似乎有些东西卡在ListView
自己的代码中,直到我们更新底层Cursor
......