【问题标题】:Google's Mentality: ListView in ScrollView [duplicate]Google 的心态:ScrollView 中的 ListView [重复]
【发布时间】:2011-06-06 19:29:12
【问题描述】:

我是那些想将ListView 放在ScrollView 中的可怜的菜鸟之一。

现在我知道他们不想要嵌套的可滚​​动元素 - 我不确定我是否同意他们的设计,但我可以理解。我无法理解的是为什么我不能制作一个不可滚动的ListView 并将其嵌套到另一个 Scrollable 元素中。

listView.setScrollContainer(false) 似乎是解决方案(因为我认为它可以关闭 ListView 的可滚动性)但没有运气。

那么有人可以解释为什么 Google 不会让 listViews 不滚动 - 有没有办法做到这一点,这个 numty 只是忘记了?

【问题讨论】:

  • 如果是 Google 的心态,那你为什么更喜欢学习 Android?

标签: android android-widget android-layout


【解决方案1】:

您可以使用LinearLayout 作为不可滚动的ListViewListView 的强大之处在于它如何处理元素的延迟加载。这在不可滚动版本的上下文中没有任何意义。

但实际上,您很可能需要重新考虑您的 UI。为什么需要多个滚动部分?从用户的角度来看,这似乎非常不友好。您可以通过页眉或页脚轻松地将内容放在ListView 的上方和下方。

【讨论】:

  • 我想要 ListView 是为了按索引添加和删除元素,基本上只是附加到一个数组列表。如果您可以使用 LinearLayout 做到这一点,请告诉我如何。
  • 你可以用 TableLayout 做到这一点:developer.android.com/reference/android/widget/TableLayout.html
  • addView 在 TableLayout 上看起来很有希望,但是否有某种相当于 setAdapter 的东西?
  • @j3frea 不,您需要自己处理添加视图。它基本上只是一个允许您添加和删除特定行的 LinearLayout。
【解决方案2】:

就像 Mayra 所说,您应该重新考虑您的 UI。

除非您有多个 ListView,否则我可以看到您的问题的解决方案。由于您的滚动视图中似乎只有一个列表视图。这意味着你想在上面或下面放一些东西。

你有setHeader,setFooter。在那里你只需要放任何你想要的东西。您必须在 setAdapter() 之前添加这些视图。

如果您的滚动视图中有多个 ListView。我有第二个解决方案给你。我真的无法详细说明。但是您必须创建一个自定义适配器并覆盖 ViewTypeCount,以便您可以处理多种类型的项目。这样你就可以通过适配器加载你想要的一切。而您真正需要的只是一个 ListView。

如果您想处理多种类型的项目(多个列表视图),这里有一个“未经测试”的示例

您必须继承适配器并覆盖 getView。习惯上我们应该有类似的东西用于视图回收

if(view == null){
    //inflate view
}

在你的情况下,你需要这样做。

package com.neutrino.lvt;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class Main extends Activity {
    private ListView lv;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        lv = (ListView)findViewById(R.id.lv);

        ArrayList<Items> items = new ArrayList<Items>();

        items.add(new ItemA("Une"));
        items.add(new ItemA("Une3"));
        items.add(new ItemA("Une4"));
        items.add(new ItemA("Une5"));
        items.add(new ItemA("Une6"));
        items.add(new ItemA("Une7"));
        items.add(new ItemA("Une8"));
        items.add(new ItemA("Une9"));
        items.add(new ItemA("Une0"));
        items.add(new ItemA("Une0-"));
        items.add(new ItemB("bbb", "cc1c"));
        items.add(new ItemB("bbb3", "c2cc"));
        items.add(new ItemB("bbb4", "c2cc"));
        items.add(new ItemB("bbb5", "c1cc"));
        items.add(new ItemB("bbb6", "cc5c"));
        items.add(new ItemB("bbb7", "cc4c"));
        items.add(new ItemB("bbb7", "c2cc"));
        items.add(new ItemB("bbb8", "c1cc"));
        items.add(new ItemB("bbb9", "cc6c"));
        items.add(new ItemB("bbb0", "cc8c"));
        items.add(new ItemB("bbb0", "cc0c"));
        items.add(new ItemB("bb3b", "cc6c"));
        items.add(new ItemA("Une"));
        items.add(new ItemA("Une3"));
        items.add(new ItemA("Une4"));
        items.add(new ItemA("Une5"));
        items.add(new ItemA("Une6"));
        items.add(new ItemA("Une7"));
        items.add(new ItemA("Une8"));
        items.add(new ItemA("Une9"));
        items.add(new ItemA("Une0"));
        items.add(new ItemA("Une0-"));
        items.add(new ItemB("bbb6", "cc5c"));
        items.add(new ItemB("bbb7", "cc4c"));
        items.add(new ItemB("bbb7", "c2cc"));
        items.add(new ItemB("bbb8", "c1cc"));
        items.add(new ItemB("bbb9", "cc6c"));
        items.add(new ItemB("bbb0", "cc8c"));
        items.add(new ItemB("bbb0", "cc0c"));
        items.add(new ItemB("bb3b", "cc6c"));

        SpecialAdapter b = new SpecialAdapter(this, items);
        lv.setAdapter(b);

    }

    private class SpecialAdapter extends BaseAdapter{

        List<Items> list;
        Context context;

        public SpecialAdapter(Context context, List<Items> list) {
            this.list = list;
            this.context = context;
        }

        public Context getContext(){
            return this.context;
        }

        @Override
        public int getCount() {
            return list.size();
        }

        @Override
        public Items getItem(int position) {
            return list.get(position);
        }

        @Override
        public long getItemId(int position) {
            return list.get(position).hashCode();
        }

        @Override
        public int getViewTypeCount() {
            return 2;
        }

        @Override
        public int getItemViewType(int position) {
            Items b = getItem(position);
            if(b instanceof ItemA){
                return 0;
            }else{
                return 1;
            }
        }



        @Override
        public View getView(int position, View v, ViewGroup parent) {
            Items o = getItem(position);
            if(v == null){
                LayoutInflater vi = (LayoutInflater)this.getContext()
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);     
                if(getItemViewType(position) == 0){
                    v = vi.inflate(
                                     android.R.layout.simple_list_item_multiple_choice,
                                     null
                                    );
                    Log.i(this.getClass().getName(), 
                                        "Inflate two line"
                                    );
                }else{
                    v = vi.inflate(
                                     android.R.layout.two_line_list_item, 
                                     null
                                    );
                    Log.i(this.getClass().getName(), 
                                     "Inflate one line"
                                    );
                }
            }

            switch (getItemViewType(position)) {
            case 0:
                ItemA oa = (ItemA)o;
                ((TextView)v.findViewById(android.R.id.text1)).setText(oa.toString());
                break;
            case 1:
                ItemB ob = (ItemB)o;
                ((TextView)v.findViewById(android.R.id.text1)).setText(ob.toString());
                ((TextView)v.findViewById(android.R.id.text2)).setText(ob.getClasse());
                break;
            }
            return v;
        }

    }

    private abstract class Items {}

    private class ItemA extends Items {
        String name;

        public ItemA(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return "ItemA: " + name;
        }
    }

    private class ItemB extends Items {
        private String name;
        private String classe;

        public ItemB(String name, String classe) {
            this.name = name;
            this.classe = classe;
        }

        public String getClasse(){
            return classe;
        }

        @Override
        public String toString() {
            return "ItemB: " + name;
        }
    }
}

我会尝试编写一个示例并尽快提出更新。我想我遗漏了一些东西,因为当视图被回收时,您需要检查回收的视图是否对应于 ItemType。但是你绝对可以单独通过 ListView 来做到这一点。无需滚动。

【讨论】:

  • 其实我想利用 ListView 的适应性——我可以用适配器快速插入和删除元素(按索引)的方式。如果有办法使用 LinearLayout 做到这一点,请告诉我。但我需要不止一个 ListView,这就是为什么我想将两者都放入 ScrollView(我实际上什至不希望 ListViews 可滚动)。
  • 告诉我代码是否清晰?您需要为您拥有的每个列表视图处理多个视图类型 1。您甚至可以为您的项目添加排序,以便 ItemA 始终位于 ItemB 之上。
  • 这是有道理的——但这是我的观点。为什么谷歌不仅仅允许嵌套的可滚​​动元素。让我们做出 UI 决定,如果我们失败了,那就这样吧,但给我们功能......我理解你的代码,但我的意思是它是不必要的。
  • @j3frea 为什么谷歌要浪费时间去实现他们知道会带来非常糟糕的用户体验的东西?他们还可以关注许多其他对更多人有用的事情。
  • @j3frea 有充分的理由说明它不可能。 Scroller 不会回收视图。 ListView 回收视图并且内存高效。如果列表视图以可滚动的形式展开,则如果您有 100 个项目,则不会回收视图,这等于内存中至少有 100 个视图。在我上面的代码中,20、100、1000 个项目最多有 20 个视图。所以是的,我发布的代码是必要的。滚动视图不能自行回收任何东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-21
  • 1970-01-01
  • 1970-01-01
  • 2013-08-25
  • 2015-11-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多