制作中量元素陷在头(滚动型/ ListView控件)控件、元素、ListView

2023-09-06 13:13:14 作者:无处话凄凉

我要作出这样的显示在中间的滚动型(或的ListView )的第一个元素然后卡在屏幕上的标题时,它的滚动。

I want to make an element that is shown in the middle of ScrollView (or ListView) at the first and then gets stuck in the header of screen when it’s scrolled.

这是在CSS + JS的原型实现:http://jsfiddle.net/minhee/aPcv4/embedded/result/.

It’s a prototype implementation in CSS+JS: http://jsfiddle.net/minhee/aPcv4/embedded/result/.

乍一看,我会做滚动型来包括的ListView ,但官方文档说:

At first glance I would make ScrollView to include ListView, but the official docs says:

您永远不应该使用滚动型与一个ListView,因为ListView的利用了自己的垂直滚动护理。最重要的是,这样做违背了所有的ListView重要的优化处理大型列表,因为它有效地强制ListView控件显示项目的整个列表,以填补由滚动型提供了无限的容器。

You should never use a ScrollView with a ListView, because ListView takes care of its own vertical scrolling. Most importantly, doing this defeats all of the important optimizations in ListView for dealing with large lists, since it effectively forces the ListView to display its entire list of items to fill up the infinite container supplied by ScrollView.

那么,有什么办法,我可以尝试做到这一点的用户界面?

So, what approaches can I try to achieve this UI?

更新:我想 StickyListHeaders ,但:它是目前不可能有互动元素在头,按钮,开关等,将只能​​工作在头不是卡住了。另外,我觉得不是很适合这种情况。我不需要多个头,但陷在头只是一个中间元素。

Update: I tried StickyListHeaders, but: "it is currently not possible to have interactive elements in the header, Buttons, switches, etc. will only work when the header is not stuck." Plus, I find it’s not very suitable for this situation. I don’t need multiple headers, but just one middle element to get stuck in the header.

推荐答案

我已经使用(或者更确切地说,试图用)的 StickyListHeaders 库中来。用起来会有问题后,我想出了以下内容。这是不是从什么其他海报建议太大的不同。

I have used(or rather, tried to use) the StickyListHeaders library in the past. After having some issues with it, I came up with the following. It is not much different from what other posters have suggested.

主要布局文件 activity_layout.xml 的ListView 的LinearLayout 这是无形的默认。使用OnScrollListener的onScroll()方法时,的LinearLayout的可见性切换。你并不需要夸大其他布局或动态添加视图布局的父。这就是 onScroll 的方法是这样的:

The main layout file activity_layout.xml consists of a ListView and a LinearLayout which is invisible by default. Using the OnScrollListener's onScroll() method, the LinearLayout's visibility is toggled. You don't need to inflate another layout or add views dynamically to your layout's parent. This is what the onScroll method looks like:

public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    if (firstVisibleItem > 3) {        // 5th row will stick
        llHeader.setVisibility(View.VISIBLE);
    } else {
        llHeader.setVisibility(View.GONE);
    }
}

简单,切换知名度得到想要的效果。你可以看看下面的code。它的工作,你可以期望的例子。该活动包含一个的ListView BaseAdapter 的严格准系统的扩展。该的ListView 填充用数字按钮(每个行,从0开始,并持续至19)。

Simply, toggle the visibility to get the desired effect. You can take a look at the following code. Its a working example of what you can expect. The activity contains a ListView with a strictly barebone extension of BaseAdapter. The ListView is populated with numbered Buttons(one on each row, starting at 0, and going up to 19).

public class StickyHeader extends Activity {    

    LinearLayout llHeader;  
    ListView lv;
    SHAdapter shAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_layout);

        lv = (ListView) findViewById(R.id.listView1);        
        llHeader = (LinearLayout) findViewById(R.id.llHeader);        
        shAdapter = new SHAdapter();        
        lv.setAdapter(shAdapter);

        lv.setOnScrollListener(new OnScrollListener() {

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {}

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                if (firstVisibleItem > 3) {
                    llHeader.setVisibility(View.VISIBLE);
                } else {
                    llHeader.setVisibility(View.GONE);
                }
            }
        });
    }   

    public class SHAdapter extends BaseAdapter {

        Button btCurrent;
        int[] arr = new int[] {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};

        @Override
        public int getCount() {
            return 20;
        }

        @Override
        public Object getItem(int arg0) {
            return arr[arg0];
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            convertView = getLayoutInflater().inflate(R.layout.list_item_layout, null);         
            btCurrent = (Button) convertView.findViewById(R.id.button1);            

            if ((Integer)getItem(position) == 4) {
                btCurrent.setText("Number " + getItem(position) + " is sticky");
            } else {
                btCurrent.setText("" + getItem(position));
            }

            return convertView;
        }
    }
}

activity_layout.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>

    <!-- This LinearLayout's visibility is toggled -->

    <!-- Improvement suggested by user 'ar34z' 
         (see comment section below) --> 
    <include layout="@layout/list_item_layout" />

</RelativeLayout>

list_item_layout

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/llHeader"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:background="@color/white"
    android:orientation="vertical" >

    <Button
        android:id="@+id/button1"
        android:layout_gravity="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>