转自博客园 农民伯伯
http://www.cnblogs.com/over140/archive/2011/12/07/2275207.html
前言
ListView是一个纵向滚动的列表视图,也有朋友嵌套HorizontalScrollView来实现,比如这里,但在ListView的API中明确指明了两者不可同时使用,参考ListView的中文API这里。本文分享一种办法,以方便有此需求的朋友。
博客园:http://www.cnblogs.com
农民伯伯: http://over140.cnblogs.com
Android中文翻译组:http://androidbox.sinaapp.com/
a). 支持ListView横行滚动
b). 支持固定第一列
package cn.com.test;
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class ScrollListView extends RelativeLayout {
private Context mContext;
/**
* 列表头的高和宽
*/
private int mTitleHeight = 30;
private int mTitleWidth = 60;
/**
* 可滚动和不可滚动列头的名称
*/
private String[] mTitleMovableStr = { "测试1", "测试2", "测试3", "测试4", "测试5",
"测试6", "测试7", "测试8", "测试9" };
private String[] mTitleFixStr = { "测试10", "测试11" };
private LinearLayout mLayoutTitleMovable;
private LinearLayout mLayoutHeader;
private LinearLayout mLayoutListMovable;
private ListView listViewMovable;
private ArrayList<View> mArrayList;
public ScrollListView(Context context) {
super(context);
mContext = context;
}
public ScrollListView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
// ListView可移动区域
mLayoutListMovable = new LinearLayout(mContext);
mLayoutListMovable.setOrientation(LinearLayout.VERTICAL);
LayoutParams scrollListLp = new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT);
this.addView(buidScrollListView(), scrollListLp);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
/**
* 可滚动得列表头
*
* @return
*/
private View buildMovableHead() {
LinearLayout relativeLayout = new LinearLayout(mContext);
for (int i = 0; i < mTitleMovableStr.length; i++) {
TextView tx = new TextView(mContext);
tx.setText(mTitleMovableStr[i]);
tx.setGravity(Gravity.CENTER);
tx.setBackgroundColor(Color.GREEN);
relativeLayout.addView(tx, mTitleWidth, mTitleHeight);
}
mLayoutTitleMovable = relativeLayout;
return relativeLayout;
}
/**
* 不可滚动得列表头
*
* @return
*/
private View buildFixHead() {
LinearLayout relativeLayout = new LinearLayout(mContext);
for (int i = 0; i < mTitleFixStr.length; i++) {
TextView tx = new TextView(mContext);
tx.setText(mTitleFixStr[i]);
tx.setGravity(Gravity.CENTER);
tx.setBackgroundColor(Color.RED);
relativeLayout.addView(tx, i, new LayoutParams(mTitleWidth,
mTitleHeight));
}
return relativeLayout;
}
/**
* 合并列头
*
* @return
*/
private View buildHeadLayout() {
LinearLayout relativeLayout = new LinearLayout(mContext);
relativeLayout.addView(buildFixHead());
relativeLayout.addView(buildMovableHead());
mLayoutHeader = relativeLayout;
return relativeLayout;
}
/**
* ListView
*
* @return
*/
private View buildMoveableListView() {
LinearLayout relativeLayout = new LinearLayout(mContext);
listViewMovable = new ListView(mContext);
listViewMovable.setCacheColorHint(00000000);
relativeLayout.addView(listViewMovable);
return relativeLayout;
}
private View buidScrollListView() {
LinearLayout relativeLayout = new LinearLayout(mContext);
relativeLayout.setOrientation(LinearLayout.VERTICAL);
relativeLayout.addView(buildHeadLayout());
relativeLayout.addView(buildMoveableListView());
return relativeLayout;
}
// 触摸开始时X的位置
private float mStartX = 0;
private float mStartY = 0;
// X轴方向的偏移量
private int mOffsetX = 0;
private int fixX = 0;
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mStartX = ev.getX();
mStartY = ev.getY();
Log.e("TEST", "中断按下x= " + ev.getX());
break;
case MotionEvent.ACTION_MOVE:
Log.e("TEST", "中断移动x= " + ev.getX());
int offsetX = (int) Math.abs(ev.getX() - mStartX);
if (offsetX > 30) {
return true;
} else {
return false;
}
case MotionEvent.ACTION_UP:
Log.e("TEST", "中断抬起x= " + ev.getX());
actionUP();
break;
default:
break;
}
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.e("TEST", "移动按下x= " + ev.getX());
return true;
case MotionEvent.ACTION_MOVE:
int offsetX = (int) Math.abs(ev.getX() - mStartX);
if (offsetX > 30) {
Log.e("TEST", "移动偏移" + offsetX);
mOffsetX = (int) (mStartX - ev.getX());
mLayoutTitleMovable.scrollTo(mOffsetX, 0);
for (int i = 0; i < mArrayList.size(); i++) {
mArrayList.get(i).scrollTo(mOffsetX, 0);
}
Log.e("TEST", "List数量" + mArrayList.size());
// mLayoutMovable.scrollTo(mOffsetX, 0);
}
break;
case MotionEvent.ACTION_UP:
Log.e("TEST", "移动抬起x= " + ev.getX());
fixX = (int) ((int) ev.getX() - mStartX);
actionUP();
break;
default:
break;
}
return super.onTouchEvent(ev);
}
/**
* 触摸抬起
*/
private void actionUP() {
if (fixX > 0) {
mLayoutTitleMovable.scrollTo(0, 0);
for (int i = 0; i < mArrayList.size(); i++) {
mArrayList.get(i).scrollTo(0, 0);
}
// mLayoutMovable.scrollTo(0, 0);
} else {
if ((mLayoutTitleMovable.getWidth() + Math.abs(fixX)) > mTitleWidth
* mTitleMovableStr.length) {
mLayoutTitleMovable.scrollTo(mTitleWidth
* mTitleMovableStr.length-mLayoutTitleMovable.getWidth(), 0);
for (int i = 0; i < mArrayList.size(); i++) {
mArrayList.get(i).scrollTo(mTitleWidth
* mTitleMovableStr.length-mLayoutTitleMovable.getWidth(), 0);
}
// mLayoutMovable.scrollTo(0, 0);
}
}
}
/**
* 设置可变的列表头信息
*
* @param str
* 列表头显示的名称
*/
public void setMovableHead(String[] str) {
mTitleMovableStr = str;
}
/**
* 设置不可变的列表头信息
*
* @param str
* 列表头显示的名称
* @param height
* 列表头的高度
* @param width
* 列表头的宽度
*/
public void setFixHead(String[] str, int height, int width) {
mTitleHeight = height;
mTitleWidth = width;
mTitleFixStr = str;
}
public View getHeaderLayout(){
return mLayoutHeader;
}
/**
* 设置ListView 适配器
*
* @param adapter
*/
public void setScrollListViewAdapter(
BaseAdapter movableAdapter) {
// listViewFix.setAdapter(fixAdapter);
listViewMovable.setAdapter(movableAdapter);
}
/**
* 可左右滑动View集合
* @param movableView
*/
public void setMovabaleView(ArrayList<View> movableView) {
mArrayList = movableView;
}
/**
* listView 点击
* @param onItemClickedListener
*/
public void setOnItemClickedListener(
OnItemClickListener onItemClickListener) {
listViewMovable.setOnItemClickListener(onItemClickListener);
}
/**
* 列头点击事件
* @param onHeaderClickedListener
*/
public void setOnHeaderClickedListener(
OnHeaderClickedListener onHeaderClickedListener) {
// onHeaderClickedListener.
// mLayoutHeader.getChildAt(0).setOnClickListener(l);
}
/**
* 列头点击事件
*
* @createTime 2011-9-26
* @company 深圳市创真科技
* @author niuxuehao
*/
public static interface OnHeaderClickedListener {
public void onClick(int headerID, int direction);
}
}
- 大小: 323 KB
分享到:
相关推荐
android listview 固定表头,固定前几列
Android ListView 固定列头源码
android listview 固定列头 标题头 列头可以随意定义 列头也可以左右拖动,很好的例子。
Android 移动开发,ListView-固定列头
基于Android studio2.3.3,可随意更改
由于项目需要,我们需要一个可以横向滚动的,又可以竖向滚动的 表格;经过几天的研究终于搞定,感兴趣的朋友可以了解下哦
首先它是一个ExpandableListView,但是它的头部可以固定,其次,在它的上面还有一个头部可以来回伸缩
android的ListView上拉刷新下拉加载和列表头横向滚动(带表头与固定列)。 该demo是我结合网上的两个示例一个是上下拉刷新加载的ListView,一个是横向滚动带固定列和列表头.主要是自定义了两个控件(重写)ListView和...
listview带表头(表头固定)
1.自定义ListView交叉表显示仓库颜色尺码库存数量 2.固定表头,支持上下滚动 3.固定前一列,支持左右滚动 4.按仓库分组显示 5.动态表头,列头,分组头 6.在android模拟器与真机上均测试通过
主要介绍了Android程序开发之ListView实现横向滚动(带表头与固定列)的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
有一个是到网看到后找得,另外一个是我自己仿华股财经的分类排行制作的左右滑动固定左边一列,上下滑动固定第一行,而且没冲突,拿来就能直接用。
android的ListView下拉刷新上拉加载和列表头横向滚动(带表头与固定列).rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
在做图表展示的时候,ListView可以上下左右滑动,但最左边一列在向右滑动时,保持不变,表头在向下滑动时保持不变。
相当漂亮的报表,使用及其方便
ListView 控件可使用四种不同视图显示项目。通过此控件,可将项目组成带有或不带有列标头的列,并显示伴随的图标和文本。 可使用 ListView 控件将称作 ListItem ...PS:横向滚动带表头与固定列(相信蛮多人都有这样的
先上一下可以实现的效果图 要实现的效果有几方面 1、列不固定:可以根据数据源的不同生成不同的列数 2、表格内容可以根据数据源的定义合并列 3、要填写的单元格可以选择自定义键盘还是系统键盘 奔着这三点,做了个...
在Android开发中,经常有一些UI需要进行固定style的动态布局,然而由于现在的UI都喜欢把一个界面拉的很长,所以我们很多情况下需要使用ScrollView来嵌套列表控件来实现UI。这样就导致了很多不顺心的问题。 问题一:...
实现多列和可变大小元素的 Android 自定义 ListView。 请注意,这目前处于预览状态。 这基本上意味着 API 不是固定的,您应该期待不同版本之间的变化。 示例应用: 在上试用示例应用程序 截图: 用法 在您的build...