ListView悬浮Header的简单实现

来源:互联网 发布:蓝光电影播放器 mac 编辑:程序博客网 时间:2024/05/22 00:17

ListView悬浮Header的简单实现

需求

如图,在某些情况下,我们可能会需要设计这样一种页面——页面中含有一个ListView,且要求页面中某一可滚动部分需要保持一直可见,即不会被滚动到屏幕之外,像是悬浮在页面上一样。
(如自定义布局的ListView标题栏,或者导航栏等)
界面图解

有一个简单的实现方法就是,将其他可滚动部分、悬浮部分都作为ListView的header添加到ListView中,再给悬浮部分设置悬浮效果。
如何实现悬浮效果?我们先看看程序运行实例图

效果演示图

这里写图片描述

实现

实现悬浮部分的悬浮效果,思路其实很简单,就是把要悬浮的部分的layout复制成两份,一份添加到ListView中作为ListView的header(称为itemLayout),另一份则在页面布局中,与ListView放在同一个FrameLayout下(称为invisLayout),然后根据ListView当前滑动的位置,动态设置invisLayout显示与否。——当itemLayout未滚到屏幕顶部时,不显示invisLayout;当itemLayout滚到屏幕顶部、要滚出或已滚出屏幕时,显示invisLayout。

于是看起来就像某一控件悬浮在页面上一样,其实只是把它的分身显示出来而已。

如果被博主捉急的表达能力绕晕了,到现在还是弄不明白,那我们就直接来看代码吧

代码

首先先定义悬浮部分(invisLayout)的布局 invis_layout.xml,示例用的布局都很简单,具体根据自己的项目需求设计布局

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:background="@color/invis_bg"    android:orientation="vertical" >    <TextView         android:layout_marginLeft="10dp"        android:text="这是悬浮部分"        android:textSize="18sp"        android:textColor="@color/white"        android:layout_margin="10dp"        android:id="@+id/tv_invis_title"        android:layout_width="match_parent"        android:layout_height="wrap_content"/>    <LinearLayout         android:orientation="horizontal"        android:background="@color/white"        android:layout_width="match_parent"        android:layout_height="wrap_content">        <Button            android:layout_margin="10dp"            android:text="Button 1"            android:background="@drawable/btn_bg"            android:textSize="14sp"            android:textColor="@color/white"            android:layout_height="wrap_content"            android:layout_width="wrap_content"            android:id="@+id/tv_invis_text1"/>         <Button            android:layout_margin="10dp"            android:text="Button 2"            android:background="@drawable/btn_bg"            android:textSize="14sp"            android:textColor="@color/white"            android:layout_height="wrap_content"            android:layout_width="wrap_content"            android:id="@+id/tv_invis_text2"/>      </LinearLayout></LinearLayout>

这里博主给Button做了一个美化,简单地设置Button控件外围弧度和背景颜色,代码如下:

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:state_pressed="false">    <shape>        <solid android:color="@color/btn_press_color"/>        <corners android:radius="8dp"/>    </shape></item><item android:state_pressed="true">    <shape>        <solid android:color="@color/btn_pressed_color"/>        <corners android:radius="8dp"/>    </shape></item></selector>

然后是页面其他可滚动的部分(不需要悬浮的部分)的布局header_layout.xml,这里也很简单只是一个TextView

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="wrap_content" >    <TextView        android:id="@+id/tv"        android:layout_width="match_parent"        android:layout_height="200dp"        android:background="#cccccc"        android:gravity="center"        android:text="这是其他可滚动头部内容" /></LinearLayout>

然后是主界面的布局文件activity_invis_demo.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent" >    <TextView        android:id="@+id/title"        android:layout_width="match_parent"        android:layout_height="30dp"        android:background="#332b3b"        android:textColor="@color/white"        android:gravity="center"        android:text="页面固定头部" />    <FrameLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_below="@id/title" >        <ListView            android:id="@+id/lv"            android:layout_width="match_parent"            android:layout_height="match_parent" />       <include layout="@layout/invis_layout"           android:visibility="gone"           android:id="@+id/invis_layout"           android:layout_width="match_parent"           android:layout_height="wrap_content"/>    </FrameLayout></RelativeLayout>

这里就是把悬浮部分(invis_layout)和ListView放在同一个FrameLayout下面,并默认不显示悬浮部分,在程序中实现OnScrollListener#onScroll()方法,控制悬浮部分的显示时间。

最后是程序代码InvisDemoActivity

public class InvisDemoActivity extends Activity {    //listView    private ListView lv;    //悬浮部分layout    private LinearLayout invisLayout;    //store listview data    private String[] strs;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_invis_demo);        //取得悬浮部分(invisLayout)        invisLayout = (LinearLayout) findViewById(R.id.invis_layout);        strs = new String[20];        for (int i = 0; i < 20; i++) {            strs[i] = "data-----" + i;        }        //取得listView        lv = (ListView) findViewById(R.id.lv);        //取得页面可滚动的其他部分        View header = View.inflate(this, R.layout.header_layout, null);        //添加到listView头部        lv.addHeaderView(header);        //取得ListView条目中的悬浮部分(itemLayout),并将其添加到头部        lv.addHeaderView(View.inflate(this, R.layout.invis_layout, null));        lv.setAdapter(new ArrayAdapter<String>(this,                android.R.layout.simple_list_item_1, strs));        //监听listView滚动状态        lv.setOnScrollListener(new OnScrollListener() {            @Override            public void onScrollStateChanged(AbsListView view, int scrollState) {            }            //动态控制是否显示invisLayout            @Override            public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {                if (firstVisibleItem >= 1) {                    invisLayout.setVisibility(View.VISIBLE);                } else {                    invisLayout.setVisibility(View.GONE);                }            }        });    }}

到这里我们就实现了ListView的悬浮头部,大家可以自己试试写个demo,有问题可评论或者发邮件跟我联系yetwish@gmail.com

0 0
原创粉丝点击