天天看点

Android支持横行滚动的ListView控件

前言

声明

  欢迎转载,但请保留文章原始出处:) 

    博客园:http://www.cnblogs.com

农民伯伯: http://over140.cnblogs.com  

正文

  一、本文目标

    效果图:

    

Android支持横行滚动的ListView控件

    a).  支持listview横行滚动

    b).  支持固定第一列

  二、 实现代码

    2.1  java类

      自定义控件hvlistview

Android支持横行滚动的ListView控件

/**

 * 自定义支持横向滚动的listview

 * @author 农民伯伯

 *

 */

public class hvlistview extends listview {

    /** 手势 */

    private gesturedetector mgesture;

    /** 列头 */

    public linearlayout mlisthead;

    /** 偏移坐标 */

    private int moffset = 0;

    /** 屏幕宽度 */

    private int screenwidth;

    /** 构造函数 */

    public hvlistview(context context, attributeset attrs) {

        super(context, attrs);

        mgesture = new gesturedetector(context, mongesture);

    }

    /** 分发触摸事件 */

    @override

    public boolean dispatchtouchevent(motionevent ev) {

        super.dispatchtouchevent(ev);

        return mgesture.ontouchevent(ev);

    private ongesturelistener mongesture = new gesturedetector.simpleongesturelistener() {

        @override

        public boolean ondown(motionevent e) {

            return true;

        }

        public boolean onfling(motionevent e1, motionevent e2, float velocityx,

                float velocityy) {

            return false;

        /** 滚动 */

        public boolean onscroll(motionevent e1, motionevent e2,

                float distancex, float distancey) {

            synchronized (hvlistview.this) {

                int movex = (int) distancex;

                int curx = mlisthead.getscrollx();

                int scrollwidth = getwidth();

                int dx = movex;

                //控制越界问题

                if (curx + movex < 0)

                    dx = 0;

                if (curx + movex + getscreenwidth() > scrollwidth)

                    dx = scrollwidth - getscreenwidth() - curx;

                moffset += dx;

                //根据手势滚动item视图

                for (int i = 0, j = getchildcount(); i < j; i++) {

                    view child = ((viewgroup) getchildat(i)).getchildat(1);

                    if (child.getscrollx() != moffset)

                        child.scrollto(moffset, 0);

                }

                mlisthead.scrollby(dx, 0);

            }

            requestlayout();

    };

    /**

     * 获取屏幕可见范围内最大屏幕

     * @return

     */

    public int getscreenwidth() {

        if (screenwidth == 0) {

            screenwidth = getcontext().getresources().getdisplaymetrics().widthpixels;

            if (getchildat(0) != null) {

                screenwidth -= ((viewgroup) getchildat(0)).getchildat(0)

                        .getmeasuredwidth();

            } else if (mlisthead != null) {

                //减去固定第一列

                screenwidth -= mlisthead.getchildat(0).getmeasuredwidth();

        return screenwidth;

    /** 获取列头偏移量 */

    public int getheadscrollx() {

        return mlisthead.getscrollx();

}

Android支持横行滚动的ListView控件

        代码说明:

          自定义hvlistview继承自listview,增加了横向手势监听,并在横向滚动时手动触发layout容器内的滚动。

      activity

Android支持横行滚动的ListView控件

public class testhvlistviewactivity extends activity {

    private layoutinflater minflater;

    private hvlistview mlistview;

    /** called when the activity is first created. */

    public void oncreate(bundle savedinstancestate) {

        super.oncreate(savedinstancestate);

        setcontentview(r.layout.main);

        mlistview = (hvlistview) findviewbyid(android.r.id.list);

        //设置列头

        mlistview.mlisthead = (linearlayout) findviewbyid(r.id.head);

        //设置数据

        mlistview.setadapter(new dataadapter());

        minflater = (layoutinflater) getsystemservice(layout_inflater_service);

    private class dataadapter extends baseadapter {

        public int getcount() {

            return 50;//固定显示50行数据

        public view getview(int position, view convertview, viewgroup parent) {

            if (convertview == null) {

                convertview = minflater.inflate(r.layout.item, null);

            for (int i = 0; i < 8; i++) {

                ((textview) convertview.findviewbyid(r.id.item2 + i)).settext("数据" + position + "行" + (i + 2) + "列");

            //校正(处理同时上下和左右滚动出现错位情况)

            view child = ((viewgroup) convertview).getchildat(1);

            int head = mlistview.getheadscrollx();

            if (child.getscrollx() != head) {

                child.scrollto(mlistview.getheadscrollx(), 0);

            return convertview;

        public object getitem(int position) {

            return null;

        public long getitemid(int position) {

            return 0;

Android支持横行滚动的ListView控件

      代码说明:

        为listview提供了模拟数据。注意getview里面还有一段代码是校验,是专门处理同时横向和纵向滚动出现错位的情况。

    2.2  xml文件

      main.xml

Android支持横行滚动的ListView控件

<?xml version="1.0" encoding="utf-8"?>

<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical" android:background="#eeffcc"

    android:layout_width="wrap_content" android:layout_height="fill_parent">

    <include layout="@layout/item" />

    <com.nmbb.hvlistview android:id="@android:id/list"

        android:background="#ffb84d" android:fastscrollenabled="true"

        android:fadingedgelength="0.0sp" android:layout_width="1400.0dip"

        android:layout_height="fill_parent" android:drawselectorontop="false"

        android:cachecolorhint="@null" android:dividerheight="1.0dip">

    </com.nmbb.hvlistview>

</linearlayout>

Android支持横行滚动的ListView控件

          注意这里需要指定hvlistview的layout_width为滑动范围值,由item累加。

      item.xml

Android支持横行滚动的ListView控件

    android:orientation="horizontal" android:layout_width="wrap_content"

    android:layout_height="wrap_content">

    <textview android:id="@+id/item1" android:text="不动列头1"

        android:textsize="20.0sp" android:gravity="center"

        android:layout_width="100.0dip" android:layout_height="wrap_content"></textview>

    <linearlayout android:orientation="horizontal" android:id="@+id/head"

        android:layout_width="1200.0dip" android:layout_height="wrap_content">

        <textview android:id="@+id/item2" android:text="不动列头2"

            android:textcolor="@android:color/black" android:textsize="20.0sp"

            android:singleline="true" android:gravity="center"

            android:layout_width="150.0dip" android:layout_height="wrap_content"></textview>

        <textview android:id="@+id/item3" android:text="不动列头3"

            android:textsize="20.0sp" android:singleline="true" android:gravity="center"

        <textview android:id="@+id/item4" android:text="不动列头4"

        <textview android:id="@+id/item5" android:text="不动列头5"

        <textview android:id="@+id/item6" android:text="不动列头6"

        <textview android:id="@+id/item7" android:text="不动列头7"

        <textview android:id="@+id/item8" android:text="不动列头8"

        <textview android:id="@+id/item9" android:text="不动列头9"

    </linearlayout>

Android支持横行滚动的ListView控件

          注意指定了每一个textview的宽度为固定宽度,这样表格看起来就比较整齐。

  三、注意问题

    从代码看得出,本办法只能算个笨办法,能满足基本需求,比较麻烦的是需要自己来指定固定宽度。在企业应用展示多行多列数据时还是非常有用的,比如炒股软件也有这样的需求。

    特别提醒大家注意设置固定宽度,还需要把最外面的容器的宽度设置为warp_content,以便支持容器内能够延伸。

    当前不支持fling操作,所以即使用力滑也不好滑太多,希望在后续版本改进。

  四、代码下载

  五、扩展阅读

    (不推荐这种做法,但有参考价值,里面网格也画得很好)

    (实现较为复杂,但后续改进可以参考其实现,有很重要研究价值)

结束 

   虽然实现了功能,但一直不太满意,用起来较为繁琐,期待下一个版本的改进版。谢谢!欢迎交流!

转载:http://www.cnblogs.com/over140/archive/2011/12/07/2275207.html

继续阅读