效果图


代码

hv_listview_item.xml

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

hv_listview_layout.xml

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

HvListView的layout_width是item中列宽的总和。


HvListView.java

import android.content.Context;import android.util.AttributeSet;import android.view.GestureDetector;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.widget.LinearLayout;import android.widget.ListView;/** * 横向滚动ListView * 自定义ListView,增加了横向手势监听,并在横向滚动时手动触发Layout容器内的滚动。 */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 GestureDetector.OnGestureListener mOnGesture = new GestureDetector.SimpleOnGestureListener() {        @Override        public boolean onDown(MotionEvent e) {            return true;        }        @Override        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,                               float velocityY) {            return false;        }        /** 滚动 */        @Override        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 true;        }    };    /**     * 获取屏幕可见范围内最大屏幕     * @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();    }}

HvListViewAdapter.java

import java.util.List;import java.util.Map;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;/** * 自定义Adapter,填充HvListView,并实现隔行变色的功能 */public class HvListViewAdapter extends BaseAdapter {    private List<? extends Map> data = null;    private Context context = null;    private int resource = 0;    private String[] from = null;    private int[] to = null;    private HvListView listView = null;    public HvListViewAdapter(Context context,                             List<? extends Map> data,                             int resource,                             String[] from,                             int[] to,                             HvListView listView){        this.context = context;        this.data = data;        this.resource = resource;        this.from = from;        this.to = to;        this.listView = listView;    }    @Override    public int getCount() {        return data.size();    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        if (convertView == null) {            LayoutInflater inflater = LayoutInflater.from(context);            convertView = inflater.inflate(resource, null);        }        for (int i = 0; i < to.length; i++) {            ((TextView) convertView.findViewById(to[i])).setText(data.get(position).get(from[i]).toString());        }        //校正(处理同时上下和左右滚动出现错位情况)        View child = ((ViewGroup) convertView).getChildAt(1);        int head = listView.getHeadScrollX();        if (child.getScrollX() != head) {            child.scrollTo(listView.getHeadScrollX(), 0);        }        //隔行变色        if (position % 2 == 0){            convertView.setBackgroundResource(R.color.ivory);        }else{            convertView.setBackgroundResource(R.color.peachpuff);        }        return convertView;    }    @Override    public Object getItem(int position) {        return null;    }    @Override    public long getItemId(int position) {        return 0;    }}

HvListViewActivity.java

import android.app.Activity;import android.os.Bundle;import android.widget.LinearLayout;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;public class HvListViewActivity extends Activity {    private HvListView listView;    @Override    public void onCreate(Bundle savedInstanceState)    {        super.onCreate(savedInstanceState);        setContentView(R.layout.hv_listview_layout);        listView = (HvListView)findViewById(R.id.hv_listview);        listView.mListHead = (LinearLayout)findViewById(R.id.hv_listview_item_head);        initData();    }    private void initData(){        List> data = new ArrayList>();        for (int i=0;i<50;i++){            Map item = new HashMap();            item.put("c1", i+"行1列");            item.put("c2", i+"行2列");            item.put("c3", i+"行3列");            item.put("c4", i+"行4列");            item.put("c5", i+"行5列");            item.put("c6", i+"行6列");            data.add(item);        }        HvListViewAdapter adapter = new HvListViewAdapter(this,                data,                R.layout.hv_listview_item,                new String[]{                        "c1",                        "c2",                        "c3",                        "c4",                        "c5",                        "c6"                },                new int[]{                        R.id.hv_listview_item_column1,                        R.id.hv_listview_item_column2,                        R.id.hv_listview_item_column3,                        R.id.hv_listview_item_column4,                        R.id.hv_listview_item_column5,                        R.id.hv_listview_item_column6                },                listView        );        listView.setAdapter(adapter);    }}

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

当前不支持Fling操作,所以即使用力滑也不好滑太多。


参考:Android支持横行滚动的ListView控件

更多相关文章

  1. Crazy Android(安卓)Note Chapter-8
  2. android HorizontalScrollView实现滚动监听
  3. TextView跑马灯效果
  4. [置顶] Android(安卓)自定义UI文章汇总
  5. [转]Android文字跑马灯控件
  6. android中TextView嵌套在ScrollView中并自由滚动
  7. Android实现广告滚动,ViewFlipper
  8. 横向 纵向结合的ScrollView
  9. Android(安卓)自定义滚动视图

随机推荐

  1. 三分钟了解C语言中自定义的标识符及规则
  2. C语言中“\n”是什么意思
  3. 带你了解C语言中的Sleep函数(附代码)
  4. C语言中“||”是什么意思
  5. c语言关系运算符号有哪些?
  6. C语言中a++和++a有什么区别
  7. c++是面向对象还是面向过程?
  8. “\n\n”在c语言中是什么意思?
  9. struct student在c语言中是什么意思?
  10. 如何区分c# 前台和后台线程