动态添加/删除页眉和页脚

9
我需要动态地添加和删除我的ListView的头部和底部。因此,我在活动中初始化我的头部和底部,然后在某个时候我想要隐藏它们,稍后我需要添加以前的头部和底部,并保持相同的Adapter
所以我找到了这个解决方案,但它很丑陋,我真的希望有其他方法。
基本上,我必须设置一个空适配器才能添加头视图,然后设置一个空适配器来添加脚视图。最后我设置我的真正的适配器。
编辑:我必须补充说明,在我的中间过程中,使用可见性属性(GONE和VISIBLE)不是一个解决方案,因为头部和底部视图在适配器中不能存在。
    public class TestAdapterHeader extends ListActivity implements OnClickListener {
        private static String[] items = { "test 1", "test 2", "test 3", "test 4",
                "test 5", "test 6", "test 7", "test 8", "test 9", "test 10",
                "test 11", "test 12", "test 13", "test 14", "test 15", "test 16",
                "test 17", "test 18", "test 19", "test 20" };

        private ArrayAdapter mAdapter;
        private LinearLayout mParentView;
        private TextView mHeaderView, mFooterView;

        private boolean mViewsHidden = false;


        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            initViews();

            mAdapter = new ArrayAdapter<String>(this,
                    android.R.layout.simple_list_item_1, items);
            setListAdapter(mAdapter);
        }


        private void initViews() {
            // The main layout
            mParentView = new LinearLayout(this);
            mParentView.setOrientation(LinearLayout.VERTICAL);
            mParentView.setBackgroundColor(Color.BLACK);

            // The button to hide the views
            Button hideViewsButton = new Button(this);
            hideViewsButton.setText("Add/Remove views");
            hideViewsButton.setOnClickListener(this);

            // The listview
            ListView listView = new ListView(this);
            listView.setId(android.R.id.list);
            listView.setCacheColorHint(Color.TRANSPARENT);

            mParentView.addView(hideViewsButton);
            mParentView.addView(listView);

            // Set the content view
            setContentView(mParentView);

            AbsListView.LayoutParams lp = new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, 150);

            mHeaderView = new TextView(this);
            mHeaderView.setTextColor(Color.WHITE);
            mHeaderView.setBackgroundColor(Color.BLUE);
            mHeaderView.setGravity(Gravity.CENTER);
            mHeaderView.setLayoutParams(lp);
            mHeaderView.setText("Header");

            mFooterView = new TextView(this);
            mFooterView.setTextColor(Color.WHITE);
            mFooterView.setBackgroundColor(Color.BLUE);
            mFooterView.setGravity(Gravity.CENTER);
            mFooterView.setLayoutParams(lp);
            mFooterView.setText("Footer");


            getListView().addHeaderView(mHeaderView);
            getListView().addFooterView(mFooterView);
        }


        @Override
        public void onClick(View v) {
            mViewsHidden = !mViewsHidden;

            // Remove header & footer views
            if (mViewsHidden) {
                getListView().removeHeaderView(mHeaderView);
                getListView().removeFooterView(mFooterView);
            } 
            else {
                // Remove the ListAdapter to be able to add our headerView
                setListAdapter(null);
                getListView().addHeaderView(mHeaderView);

                // Set an empty ListAdapter to be able to add our footerView
                setListAdapter(new ArrayAdapter<String>(TestAdapterHeader.this, -1));
                getListView().addFooterView(mFooterView);

                // Re set our Adapter
                setListAdapter(mAdapter);
            }

            mParentView.requestLayout();

        }
    }

你在这方面有什么进展吗?我也有类似的需求。 - Vadim Peretokin
没有,我没有找到比我提供的解决方案更聪明的方法。但至少它能够运行。 - Chayy
11个回答

8
请勿尝试添加/删除标题/页脚视图。
要能够动态添加/删除标题和页脚视图,只需在设置适配器之前添加一个RelativeLayout作为标题和页脚即可。 然后,您可以添加/删除任何您想要的内容到RelativeLayout中。
将RelativeLayout的大小设置为WRAP_CONTENT。
Harry

2
适配器滚动ListView到顶部不是很奇怪吗?如何避免这种情况?顺便说一句,大家都应该感谢谷歌提供这样精彩的API。。。:( - Piotr

6
您可以使用以下代码来实现相同的功能。
// to show the footer view
footerView.setVisibility(View.VISIBLE); 

// to hide the footer view    
footerView.setVisibility(View.GONE); 

我真的更喜欢将它们直接删除。用户可以使用拖放系统重新排列列表中的项目,就像我们在音乐应用程序中看到的那样。在这种情况下,标题和页脚不应该在适配器中。 - Chayy
@Chayy,你的黑科技在大多数设备和操作系统上都适用,也许你会一直使用它。但是,我通过艰难的方式发现 setListAdapter(null); 和 getListView().addHeaderView(mHeaderView); 在2.3.5版本的droid 3手机上并不可靠。因此,即使你不喜欢,设置可见性可能是最好的选择。 - LEO

3

我刚遇到了这个问题,以下是我的解决方法。在视图中添加一个标签,然后通过该标签找到并删除它。

        final Button btnAddMore = new Button(this);
        btnAddMore.setTag("footer");   

        if(myList.getFooterViewsCount() >0)
        {
            View v = myList.findViewWithTag("footer");
            if(v != null)
            {
                 myList.removeFooterView(v);
            }           
        }

2
您应该使用 view.setVisibility(int visibility) 方法,参数可选值为 View.GONE、View.VISIBLE 或 View.INVISIBLE 。
        ....
        if (mViewsHidden) {
            mHeaderView.setVisibility(View.GONE);
            mFooterView.setVisibility(View.GONE);
        } 
        .... 
        else {
            mHeaderView.setVisibility(View.VISIBLE);
            mFooterView.setVisibility(View.VISIBLE);
        } 
        .... 

就像我向Maneesh解释的那样,在这里使用visibility属性并不是一个解决方案。 - Chayy

1
非常简单!
1)为页脚的布局容器提供一个ID。
例如:`footer.xml`。
 <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:id="@+id/parent_footer_search_list"
        android:layout_height="fill_parent"
        android:background="#fff"
        android:orientation="vertical">
       <TextView

            android:layout_width="fill_parent"
            android:layout_height="fill_parent"

            android:gravity="center|left"
            android:lineSpacingExtra="5dp"

            android:text="Create new list"


            android:textColor="#666666"
            android:textSize="16.8sp"
            android:textStyle="bold" />
      </LinearLayout>

在上面的xml中,parent_footer_search_list 是您的主容器id。 现在让我们回到您填充此页脚的片段/活动中。 因此,为了删除它,

LinearLayout parentContainerForFooter = (LinearLayout) footer.findViewById(R.id.parent_footer_search_list);

**yourview**.removeFooterView(parentContainerForFooter); 

完成!这样,您就可以使用正确的Android标准。不要使用wrap_content,visibility GONE等。它们只是hack!


1

在设置适配器之前和之后,您需要在ListView中添加页眉和页脚视图,然后就可以使用setVisibility进行操作。

祝你好运;)


0
its work fine for me!  

 private void addHeaderList(){
       mListView.setAdapter(null);
       mListView.addHeaderView(headerList);

   }
   private  void removeHeaderList(){
       mListView.removeHeaderView(headerList);
   }

     just called call function before setadapter again.
            addHeaderList();
            mListView.setAdapter(mAdapter);

0

我遇到了类似的问题- 我需要动态添加或删除标题,我是这样做的:
- 我从适配器中删除了项目并设置 adapter=null;
- 删除:removeHeaderView(mHeaderView);
- 添加标题: addHeaderView(mHeaderView);
- 再次创建适配器并设置内容

它可以工作,但没有动画效果看起来很丑陋


0

我找到了一个解决这种情况的方法,虽然大多数人可能不喜欢它。只需在列表视图上方和下方添加线性布局即可。现在,您可以使用可见性选项动态添加和删除视图。如果将参数设置为WRAP_CONTENT,则如果没有子元素,布局将不占用任何空间。


一个位于ListView上方的视图不是header,它不会与ListView一起滚动。页脚也是同样的情况。 - Chayy
ListView自带的标题不会随着列表滚动,就我所知也是如此。为什么不能在没有任何信息的情况下插入标题,并在运行时更改其内容/可见性?你说你不能在那里放它们,但我不确定为什么。 - Slynk
嗯,我的ListView可以设置为编辑模式,我可以重新排序和删除项目。为了进行这个操作,我需要先删除头部和尾部,然后让用户编辑ListView,在他离开编辑模式时,我重新添加头部/尾部。也许更清晰的方法是使此编辑模式忽略头部和尾部... - Chayy
对啊,我觉得直接忽略索引0和索引大小-1会更容易。 - Slynk

0

这似乎是少数解决方案之一。我刚刚尝试了非常相似的东西,它起作用了,但我也面临同样的问题。对我来说,它感觉像是一个hack。

还有其他几个选项,比如手动将页眉/页脚添加/删除/隐藏到列表视图外的视图中。然而,您可能无法获得漂亮的滚动效果,这几乎是列表视图标题的重点。

我刚刚尝试将一个视图设置为View.GONE,但是该视图并没有消失,而是在ListView顶部留下了一个间隙。


4
不应将View.GONE设置为标头视图本身。您应该将一个高度为wrap_content的LinearLayout放置在所需的内容视图周围。您将此父布局设置为标题。当您要隐藏或显示标题时,将内容视图(而不是父视图)的可见性设置为View.GONE。这样就不会出现间隙。这确实是一种像黑客般的解决方案,但它有效 :-D - stoilkov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接