ListView悬浮Header的简单实现

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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值