android - ListView 仅在附加 HierarchyViewer 时出现

标签 android hierarchyviewer

我有一个 ListView,它带有一个扩展 CursorAdapter 的自定义 Adapter。列表定义在这样的布局中:

<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 的内容。我已尝试为 CursorAdapter 设置内容观察器,并进行日志记录以确保为 Adapter 设置了正确的项目数>,一切都按预期工作。由于我们的自定义 MultiCoumnAdapter,我们已经在 List 上执行了一轮额外的布局,它在第一个 ListView 布局传递之后计算列数(因此需要 HookedListView).

我试过使用标准的 CursorAdapter,而不是我自己的 MultiColumnAdapter(模拟 GridView,没有它的所有限制和错误),但这并没有改变任何东西。

FragmentActivity 的唯一内容; Activity 本身基本上什么都不做,只是从用于启动它的 Intent 的额外部分获取项目 ID,并将其传递给 Fragment,在 Activity 的布局 XML 中定义为唯一元素。

Fragment 所做的只是处理使用标准 CursorLoader 从应用程序的 ContentProvider 获取数据。我们使用 DataDroid管理从网络服务获取新数据。

有没有人对这里发生的事情有丝毫线索?在我们更新底层 Cursor 之前,似乎有些东西卡在 ListView 自己的代码中......

最佳答案

您在 ListView 上使用 onLayout 的事实敲响了警钟。你为什么不使用带有 OnGlobalLayoutListener 的标准 ListView? ?

或者,如果您需要自定义 ListView,请尝试将 onLayout() 更改为:

final LayoutChangedRunnable mLayoutRunnable = new LayoutChangedRunnable()

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    super.onLayout(changed, l, t, r, b);

    if (changed) {
        post(mLayoutRunnable);
    }
}

关于android - ListView 仅在附加 HierarchyViewer 时出现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16013044/

相关文章:

android - Android 中的预加载 Activity ?

android - CSS 样式的自定义字体字样

android - listView 上的复选框阻止事件点击,kotlin

hierarchyviewer - 层次结构查看器不见了

android - hierarchyviewer 可以与 Nexus 以外的真实设备一起使用吗?

android - Hierarchyviewer 中的测量、布局和绘制时间(更好)解释

Android 布局测量时间随着层次结构的每一步增加而增加一倍

java - 从 BroadCastReceiver 启动应用程序(NEW_OUTGOING_CALL 并不总是有效)

android - 添加 Firebase 库后无法构建 Android 应用程序