ListView可以包含片段

use*_*018 39 android listview fragment android-arrayadapter

如在,ListView的ELEMENTS可以是片段.我知道您可以将TextView XML分配给ListView以更改其外观,但是您可以将片段添加到ListView中.

例如:我有一个片段.所述片段的XML包含一个ImageView,一些大型TextView和一个小型TextView.Fragment类代码接收Bundle,然后根据内容相应地填充TextViews和ImageView.Fragment XML和Fragment代码都可以正常工作(我可以很好地显示单个Fragment).我有一个FragmentActivity,我想在其中显示上面提到的碎片列表.这是我用来尝试填充FragmentActivity视图中的ListView的代码:

    ArrayList<Fragment> fragList = new ArrayList<Fragment>();
    Fragment fragment = Fragment.instantiate(this, TileItem.class.getName());
    Bundle bundle = new Bundle();
    bundle.putInt("key", 0);
    fragment.setArguments(bundle);
    fragList.add(fragment);

    ArrayAdapter<Fragment> adapter = new ArrayAdapter<Fragment>(this, R.layout.tile_item, fragList);
    listItems.setAdapter(adapter);
Run Code Online (Sandbox Code Playgroud)

这是我对此的思考方式.我创建了一个Fragments的ArrayList来保存我所有实例化的视图.然后创建一个片段,创建一个包,将数据添加到包(这样的片段可以正确地封送数据到它的意见),加上捆绑的片段,然后最后片段添加到ArrayList.之后,我创建一个ArrayAdapter,添加我想要使用的元素布局,以及我制作的片段列表; 然后将ListView设置为从我的适配器读取.

任何运行此代码的人都可能会获得NPE @实例化ArrayAdapter.是什么赋予了?这甚至可能吗?在我继续绞尽脑汁之前,有人可以告诉我,如果我只是在浪费时间吗?有没有更好的办法?我一直在想用滚动型的,但这么多的ListView的功能将需要重新实现,我讨厌恨,恨重复发明轮子时,它不是必需的.

感谢所有人的阅读,特别感谢您的决定,如果您决定离开他们.我试图寻找一个既定的答案,但我似乎找到的是关于使用片段的Lis​​tView INSIDE的问题/网页; 不使用碎片作为ListView的元素

编辑:我接受了以下建议,并开始调查更多.从事情出现,我应该能够使用该膨胀片段,而不是从XML只是平了建筑的自定义接口的方式(因为缺乏一个更好的方式来描述这一过程),但我目前的实现正试图设置时抛出NPE适配器.

这是我的自定义适配器代码(为简洁起见缩短):

public class AdapterItem extends ArrayAdapter<Fragment> {

Context c;
List<Fragment> f;

public AdapterItem(Context c, List<Fragment> f) {
    super(c, R.layout.tile_item, f);
    this.c = c;
    this.f = f;
}

@Override
public View getView(int pos, View v, ViewGroup vg) {
    LayoutInflater i = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    return i.inflate(R.layout.tile_item, vg, false);
}
Run Code Online (Sandbox Code Playgroud)

}

以下是我如何实现它:

ArrayList<Fragment> fragList = new ArrayList<Fragment>();
    Fragment fragment = Fragment.instantiate(this, TileItem.class.getName());
    Bundle bundle = new Bundle();
    bundle.putInt("key", 0);
    fragment.setArguments(bundle);
    fragList.add(fragment);

    AdapterItem adapter = new AdapterItem(this, fragList);
    adapter.add(fragment);
    listItems.setAdapter(adapter);
Run Code Online (Sandbox Code Playgroud)

所以这已经过了几天,我很确定这个帖子已被埋葬了.但是,我想我会添加一个最后更新,以防万一有人想尝试这个,谷歌搜索将他们带到这里.所以在我的实现中,当ListView被赋予适配器时,我得到一个NPE.它不需要火箭外科医生弄清楚它肯定是适配器而不是ListView抛出错误.对于我的生活,我无法弄清楚为什么......

无论如何,我想我有一些想法.首先,一个小故事:前一阵子我试图在FragmentDialog中制作FragmentTransactions.每次我试图这样做,我都会得到一份NPE.最后,通过大量研究,我发现原因与片段实例的方式有关.当调用Fragment时,它需要来自它父级的上下文.由于Dialog的父级是启动它的Activity,因此Dialog本身不符合必要的标准.我相信,当尝试将片段添加到ListView时,情况也是如此.由于ListView不符合与片段实例化的协议,因此它会抛出NPE,从而让我停下来并回到惯例.D @ mn ......我真的希望能够做到这一点.使用片段而不是简单的XML会使组织/搜索列表变得更加容易.哦,好吧......如果有人想知道的话,不能这样做.

din*_*eth 8

我说这是不可能做到的,因为在ListView中放置片段意味着片段可以在多个容器中相乘.当您使用FragmentManager创建片段时,它会使用标识符进行标记,从而可以轻松地重新加载和重新排列方向和其他配置更改.它还鼓励跨多个设备配置使用.

片段实际上是活动的子集.你有没有活动作为列表的一部分?绝对不是(应该是答案!)!!!

而且,当它们进出视图(细胞被回收)时,连续地()和分离()连续片段并不是非常有用.这些都是ListView不应该处理的昂贵操作.列表应快速滚动.

从评论的对话中,我可以看到你希望通过在Activity中很好地分离视图设置代码和适配器来实现漂亮的代码.这样做可以:

  1. 覆盖View该类并在那里进行自定义绘图和设置.
  2. 创建一个新类,在其中提供它所需的上下文和数据集,以使您返回列表需要显示的视图 - 这就是我通常所做的.
  3. 有一个Utils类可以在其他地方构建你的视频(愚蠢).

只是不要在列表中使用碎片.不是他们的目标用例.HTH.


Joh*_*ada 7

事实证明,您可以创建ListViewlistView中的每个项目所在的位置Fragment.诀窍是将片段包装成一个FrameLayout.

更新9/16/2014

即使可以创建一个ListView包含Fragments它,但它看起来不是一个好主意.这似乎绝对是Android世界的一个极端情况,并且有龙.对于像下面示例中的一个简单片段,一切都运行得很漂亮,但如果你有一个复杂的项目,其中有很多进展,那么这可能不是你要走的路.我的新方法是将所有与GUI相关的代码拉入View到扩展中FrameLayout,然后将其插入到ListView- 这样可以更好地工作,并且更符合Android预期的使用方式.如果您需要Fragment代码的其他部分的功能,您也可以View在那里使用这个新功能.

回到原来的答案......

我已经ManyFragments为我的AnDevCon 14 Fragments示例应用添加了一个新示例,如果您想尝试一下.基本上它来自于BaseAdapter,在我的示例中看起来像这样:

    BaseAdapter adapter = new BaseAdapter() {
        @Override public int getCount() { return 10000; }
        @Override public Object getItem(int i) { return new Integer(i); }
        @Override public long getItemId(int i) { return i; }

        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {

            if (view!=null){
                ManyListItemFragment fragment = (ManyListItemFragment) view.getTag();
                fragment.setCount(i);
            } else {
                FrameLayout layout = new FrameLayout(getActivity());
                layout.setLayoutParams(frameLayoutParams);
                int id = generateViewId();
                layout.setId(id);
                ManyListItemFragment fragment = new ManyListItemFragment();
                fragment.setCount(i);
                getChildFragmentManager()
                        .beginTransaction()
                        .replace(id,fragment)
                        .commit();
                view = layout;
                view.setTag(fragment);
            }

            return view;
        }
    };
Run Code Online (Sandbox Code Playgroud)

万一你好奇的是generateViewId():

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public static int generateViewId() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
        for (;;) {
            final int result = sNextGeneratedId.get();
            // aapt-generated IDs have the high byte nonzero; clamp to the range under that.
            int newValue = result + 1;
            if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.
            if (sNextGeneratedId.compareAndSet(result, newValue)) {
                return result;
            }
        }
    } else {
        return View.generateViewId();
    }
}
private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);
Run Code Online (Sandbox Code Playgroud)