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

来源:互联网 发布:新疆大学网络教学平台 编辑:程序博客网 时间:2024/05/21 14:07

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;            }        }    };


大概思路就是上面所说,可能我叙述的比较不直观,没图没真相,但是如果你想实现这样的效果最好还是耐心看完。











0 0
原创粉丝点击