【问题标题】:including list_content into list layout to retain ListFragment functionality将 list_content 包含到列表布局中以保留 ListFragment 功能
【发布时间】:2011-10-22 22:34:46
【问题描述】:

首先,我将 Android 兼容性库 V4 rev.3 用于我的 1.6(甜甜圈)

当您第一次创建 ListFragment 时,它会显示一个不确定的进度指示器,直到您使用 setListAdabpter()。根据 ListFragment.onCreateView 的文档,如果我想使用自定义布局:

如果您使用自己的自定义内容覆盖此方法, 考虑包括标准布局 {@link android.R.layout#list_content} 在你的布局文件中,这样你 继续保留 ListFragment 的所有标准行为。在 特别是,这是目前拥有内置 显示不确定的进度状态。

问题是当我进入我的布局文件并尝试: <include layout="@android:layout/list_content" ...> it (eclipse) 告诉我

资源不公开。 (在“布局”处,值为“@android:layout/list_content”)。

我认为这意味着list_content.xml 在我的 V4 源代码中不存在。这是正确的,因为根据 API v11 中出现的文档。

我只是假设它会存在于兼容性库源中,不知道它是否存在......

我能看到的唯一其他解决方案是挖掘 android 的 API V11 源代码并复制并粘贴 list_content.xml。但是现在我想避免这种黑客行为。这是唯一的解决方案吗?

【问题讨论】:

  • 您找到解决方案了吗?我也有同样的问题。
  • @Yuyo 我最终没有使用自定义布局(真的很懒惰),但正如我和安东尼特所说,您可以将list_content.xml 复制到您的项目中。这不是骇客,事实上,如果您不想开始编写代码行来实现相同的效果,这是最好的方法。

标签: android android-fragments android-support-library


【解决方案1】:

兼容性库中包含的ListFragment 似乎不像真正的那样使用该布局(list_content)。这可能是因为它是作为 jar 提供的,并且无法打包资源。以下是其onCreateView的内容:

来自兼容性库的ListFragment:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    final Context context = getActivity();

    FrameLayout root = new FrameLayout(context);

    // ------------------------------------------------------------------

    LinearLayout pframe = new LinearLayout(context);
    pframe.setId(INTERNAL_PROGRESS_CONTAINER_ID);
    pframe.setOrientation(LinearLayout.VERTICAL);
    pframe.setVisibility(View.GONE);
    pframe.setGravity(Gravity.CENTER);

    ProgressBar progress = new ProgressBar(context, null,
            android.R.attr.progressBarStyleLarge);
    pframe.addView(progress, new FrameLayout.LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));

    root.addView(pframe, new FrameLayout.LayoutParams(
            ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));

    // ------------------------------------------------------------------

    FrameLayout lframe = new FrameLayout(context);
    lframe.setId(INTERNAL_LIST_CONTAINER_ID);

    TextView tv = new TextView(getActivity());
    tv.setId(INTERNAL_EMPTY_ID);
    tv.setGravity(Gravity.CENTER);
    lframe.addView(tv, new FrameLayout.LayoutParams(
            ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));

    ListView lv = new ListView(getActivity());
    lv.setId(android.R.id.list);
    lv.setDrawSelectorOnTop(false);
    lframe.addView(lv, new FrameLayout.LayoutParams(
            ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));

    root.addView(lframe, new FrameLayout.LayoutParams(
            ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));

    // ------------------------------------------------------------------

    root.setLayoutParams(new FrameLayout.LayoutParams(
            ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));

    return root;
}

Android 4.0 的 ListFragment:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(com.android.internal.R.layout.list_content, container, false);
}

考虑到从 APIv11 源代码复制布局文件和包含此视图初始化代码之间的选择,我认为很清楚哪一个会被视为“黑客”;)

【讨论】:

    【解决方案2】:

    看到使用支持库时 list_content 布局不可用,我感到很沮丧。我的方法只是重用 ListFragment 的默认 onCreateView 方法并将其添加为我的自定义布局的一部分:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
    
        View listContent = super.onCreateView(inflater, container,
                savedInstanceState);
    
        View v = inflater.inflate(R.layout.my_custom_layout, container,
                false);
    
        FrameLayout listContainer = (FrameLayout) v.findViewById(R.id.my_list_container);
    
        listContainer.addView(listContent);
    
        return v;
    }
    

    我添加了一个 FrameLayout,ListView 曾经在我的自定义布局中。

    【讨论】:

    • 我赞成,因为这似乎是使用 setListShown(false) 保留默认“加载/不确定进度”视图的唯一方法。不幸的是,当与空列表 (@id/android:empty) 的视图结合使用时,支持库中的 ListFragment 根本不支持该进度视图。如果未创建默认视图,则实现 here 甚至只会尝试查找自定义的空视图。
    • 我们不能只使用容器而不是调用 findViewById。这就是我们告诉 Android 已经放置 ListView 的地方。
    【解决方案3】:

    在使用兼容性库时将默认 @android.R.layout/list_content 合并到自定义布局中的一种可能解决方法是创建一个虚拟 ListFragment:

    package com.example.app;
    
    import android.support.v4.app.ListFragment;
    
    public class ListContentFragment extends ListFragment {
        @Override
        public void onViewCreated(View view, Bundle savedInstanceState) {
            //Supress default list and empty text behavior
            //super.onViewCreated(view, savedInstanceState);
        }
    }
    

    然后将 this 片段(而不是推荐的 list_content 布局)包含到您的自定义布局中:

    ...
    <fragment class="com.example.app.ListContentFragment"
        android:layout_weight   ="1" 
        android:layout_width    ="fill_parent"
        android:layout_height   ="0dip" />
    ...
    

    这样,您将获得 ListFragment 的功能齐全的默认行为,同时仍然为其自定义布局。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-04
      • 2015-02-24
      • 1970-01-01
      • 1970-01-01
      • 2012-04-08
      • 2019-08-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多