您的位置:首页 > 移动开发 > Android开发

Android使用TableLayout之固定表头(标题栏)

2014-04-03 17:04 741 查看
TableLayout布局的效果就是整齐的表格,看着非常舒心。当遇到数据较多时,可以添加到ScrollView和HorizontalScrollView进行上下和左右的滑动。左右滑动的体验性一般比较合理,但是上下滑动就有些不舒心了。因为常规中,第一行数据是表头,即所谓的列名,在上下滑动的时候标题列也随着滑动而隐藏掉。这就导致看下面的数据时不知道每列的数据指的是什么,体验性就比较差。理想的做法就是固定标题栏,只有数据可以上下滚动,这样,就可以一直看到标题栏了。遗憾的是Android并没有提供直接固定标题栏的方法,那么这就要我们程序猿自己想法实现了。当然,程序猿是一种非常聪明的生物,这群家伙大脑非常活跃,想出了不止一种实现的方法。而我作为其中一支猿,只想出了一种,其他方法还望猿们一块分享。

首先说下实现思路:和普通的加载数据一样,把数据完整的显示在TableLayout中,创建一个ScrollView,将TableLayout添加其中。这时,上下滚动的时候标题栏会滚动隐藏,这个TableLayout叫做数据Layout。然后再创建一个TableLayout,这个TableLayout只用于显示标题栏,这个叫做标题Layout。再创建一个FramLayout,把数据Layout和标题Layout按照顺序添加到FramLayout中。这时,整个显示并不会左右滑动,因此需要将FramLayout加入到一个HorizontalScrollView中。大概就是这样。

不过遇到一种情况时需要做下处理:当你的TableRow中每列数据的宽度是WRAP_CONTENT时,这个时候需要设置标题Layout中每个列的宽度与数据Layout中对应列的宽度相同。

下面贴下伪代码,不能运行、

ScrollView ssv=new ScrollView(this);                   //竖向滑动
HorizontalScrollView sv=new HorizontalScrollView(this);//横向滑动
FrameLayout frameLayout=new FrameLayout(this);         //布局
Timer timer;
TimerTask timerTask;

loadData(){                                            
	TableLayout dataLayout= new TableLayout(this); //显示数据的TableLayout 
	TableRow dataHead=new TableRow(this);          //显示标题的行
	init(dataHead);	                               //加载数据给标题
	dataLayout.addView(dataHead);
	//显示标题的TableLayout 
	TableLayout headLayout= new TableLayout(this);                                                       
	//显示标题的行 
	TableRow newHead=new TableRow(this);                                                                                                  
	init(newHead);                                //加载数据给标题

	ssv.addView(dataLayout);                      //使数据Layout能上下滑动
	frameLayout.addView(ssv);                     //添加数据Layout到FrameLayout中
                                     
	//覆盖数据Layout中的标题行,注意,headLayout没在ScrollView中,所以不会上下滑动
	frameLayout.addView(headLayout);              
 	//使整体能够左右滑动	
	sv.addView(frameLayout);                     

	//加载数据到dataLayout中
	.....//加载完成

	//由于数据Layout每列的宽度是根据内容调节的,所以在数据Layout加载好后,等待那么一小会儿,给标题Layout设置宽度,与数据Layout宽度对齐
    	timer = new Timer();         
    	startTimerTask();	
}

init(TableRow row){
	//加载列名到第一行
}

	private void startTimerTask() {
        if (timer != null) {
            if (timerTask != null) {
                timerTask.cancel();
            }
        }
        timerTask = new TimerTask() {
            @Override
            public void run() {
                Message message = new Message();
                message.what = 9;
                handler1.sendMessage(message);
            }
        };
        timer.schedule(timerTask, 300);   //300毫秒后执行
    }

    Handler handler1 = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 9:			
		//遍历数据Layout标题行的子元素
                    for (int i = 0; i < dataHead.getChildCount(); i++) { 
			//获取数据Layout标题行中的子元素    
                        Object o = dataHead.getChildAt(i); 
			//获取标题Layout中标题行的子元素                 
                        Object o2 = newHead.getChildAt(i);                  
                        if (o instanceof TextView) {
                            TextView tv = (TextView) o;
			 //获取数据Layout标题行中的子元素的宽度  
                            int w = tv.getWidth();                                                                     
			//设置标题Layout中标题行子元素的宽度
                         ((TextView) o2).setLayoutParams(new TableRow.LayoutParams(w, ViewGroup.LayoutParams.WRAP_CONTENT)); 

                        }
                    }
                    if (newHead.getParent() == null) {
                        headLayout.addView(newHead, new TableLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT
                                , ROW_HEIGHT));
                    }
                    if (timerTask != null) {
                        timerTask.cancel();
                    }
                    break;
            }
        }
    };


大概思路就是上面所说,可能我叙述的比较不直观,没图没真相,但是如果你想实现这样的效果最好还是耐心看完。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: