`
hxdawxyhxdawxy
  • 浏览: 126906 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

android listview列固定

 
阅读更多
转自博客园 农民伯伯
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固定表头,固定前几列"的功能。 首先,我们来看表头的固定。表头固定通常是通过自定义ViewGroup来实现的。创建一个新的布局文件,比如`fixed_header.xml`,作为表头...

    Android ListView 固定列头源码

    标题"Android ListView 固定列头源码"提示我们将讨论如何在ListView中实现这样的功能。 在Android中,实现ListView固定列头的一种常见方法是使用自定义适配器和布局管理器。一种常见的实现方式是创建两个ListView:...

    android listview 固定列头

    "android listview 固定列头"正是这样一个技术点,它允许开发者在ListView中创建一个可左右拖动的、自定义的列头。 要实现这个功能,我们需要理解以下几个关键知识点: 1. **自定义ViewGroup**: 首先,我们需要...

    ListView固定头部及某一列,可上下左右滑动

    在特定场景下,我们可能需要实现ListView的头部固定以及某列固定的效果,同时允许用户进行上下左右滑动来浏览更多的内容。这个功能在设计用户界面时,能够提供更好的用户体验,尤其是在处理大数据表格或者长列表时。...

    ListView表头和第一列不动上下左右滑动

    总之,实现"ListView表头和第一列固定不动上下左右滑动"的功能需要对Android布局管理、滚动事件处理以及性能优化有深入理解。通过自定义组件、使用第三方库或者结合现有组件,都可以达到预期效果。在实际开发中,应...

    listview带表头(表头固定)

    总之,实现ListView带表头(表头固定)是Android开发中的一个常见需求,它需要理解ListView的工作原理,以及如何在适配器和滚动事件中正确处理表头。通过实践和优化,你可以创建出既美观又高效的列表界面。

    头部固定不动的listview

    总的来说,实现“头部固定不动的listview”涉及到了Android视图复用、滚动事件处理、自定义布局和动画等多个技术点。开发者可以通过`PinnedHeaderExpandableListView`这样的开源库,简化这一复杂功能的实现,同时也...

    android listview 股东列头

    在“android listview 股东列头”的场景中,我们可能需要实现一个ListView,其中包含股东信息,并且列头是固定的,即使在用户滚动列表时也不会消失。这通常是为了提供更好的用户界面,使用户始终能够看到列头,了解...

    android ListView实现表格

    - 如果需要有固定表头,可以在ListView的顶部添加一个独立的布局,或者创建一个特殊的表头视图类型。 7. **自定义样式** - 可以通过修改单元格的背景颜色、文字颜色、边框等属性,实现个性化样式。 8. **刷新和...

    android开发之横向滚动/竖向滚动的ListView(固定列头)

    在Android开发中,有时我们需要创建一个既可横向滚动又可竖向滚动的表格,这通常涉及到自定义ListView和HorizontalScrollView的组合使用。以下是对这个特殊需求的详细解释和实现思路: 首先,我们用ListView来处理...

    android用ListView实现表格样式

    在Android开发中,ListView是一种非常常用的控件,用于展示大量数据列表。然而,有时我们不仅需要展示单一列表,还可能需要实现类似表格的布局,即行与列的结构。本篇将详细介绍如何在Android中利用ListView实现表格...

    Android锁定指定列的listview

    在Android开发中,为了提供更好的用户体验,有时我们需要对列表视图(ListView)进行特定的定制,比如锁定指定列。这通常在数据展示时,需要保持某些关键信息始终可见的情况下非常有用。本文将深入探讨如何在Android中...

    Android程序开发之ListView实现横向滚动(带表头与固定列)

    标题所提到的"Android程序开发之ListView实现横向滚动(带表头与固定列)"是针对这种需求的一个解决方案,即在ListView中实现横向滚动,同时保持左侧列(通常是表头)固定,顶部表头在向下滚动时也始终保持可见。...

    Android中ListView实现表格效果

    在Android开发中,ListView是一种非常常见的控件,用于展示大量数据列表。然而,有时我们不仅需要展示单一列表,还可能需要实现类似表格的效果,比如显示多列数据。本篇文章将详细讲解如何在Android中利用ListView...

    android瀑布流listview

    瀑布流布局的特点是每一列的高度不固定,根据内容自适应,使得视觉效果更加生动,用户体验更佳。在本案例中,我们讨论的是如何在Android中实现瀑布流ListView,并且它已经集成了上拉刷新和下拉分页功能,以提供更...

    Android Listview表格

    在Android开发中,ListView是一种非常常见且重要的组件,它用于展示大量的数据列表,通常用于创建类似于表格的效果。这篇博客“Android Listview表格”探讨了如何在Android应用中使用ListView来构建表格样式的视图。...

    android如果用ListView做一个表格形式

    1. **理解ListView**: ListView是Android中的一个视图组件,它能够显示一列可滚动的数据项。通常,ListView会与Adapter配合使用,Adapter负责填充数据并决定每个列表项的外观。 2. **Adapter的使用**: Adapter是...

    android的ListView下拉刷新上拉加载和列表头横向滚动(带表头与固定列)

    android的ListView上拉刷新下拉加载和列表头横向滚动(带表头与固定列)。 该demo是我结合网上的两个示例一个是上下拉刷新加载的ListView,一个是横向滚动带固定列和列表头.主要是自定义了两个控件(重写)ListView和...

    android 仿股票 固定左边列可上下左右滑动

    在Android开发中,创建一个类似股票应用的界面是一项常见的任务,尤其当涉及到固定左边列并且支持上下左右滑动的功能时。这个"android 仿股票 固定左边列可上下左右滑动"的项目,旨在实现一种高效且用户体验良好的...

    固定列的listview

    总之,实现固定列的ListView需要对Android的UI组件有深入理解,包括Adapter机制、布局管理以及事件处理。通过自定义Adapter和合理利用布局资源,我们可以创建出满足需求的固定列ListView。在实际开发中,还应考虑...

Global site tag (gtag.js) - Google Analytics