android listview列固定

转自博客园 农民伯伯
http://www.cnblogs.com/over140/archive/2011/12/07/2275207.html

[img]http://dl.iteye.com/upload/attachment/0070/5507/7496a09d-d864-3cce-95eb-88926385a48f.gif[/img]

前言
   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);

}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值