当前位置: 移动技术网 > IT编程>移动开发>Android > android 自定义表格

android 自定义表格

2018年09月19日  | 移动技术网IT编程  | 我要评论

暴走大事件第36期,无损探伤,点裳羽绒服

本文通过scrollview 嵌套 listview来实现滚动表格功能。
实现效果如下图:
这里写图片描述

如上图所示实现功能如下:
1、列表头 和 数据 可以左右滑动,方便超出屏幕数据查看。
2、行表头 和 数据 可以上下滑动,方便超出屏幕数据查看。
3、左右滑动时 行表头固定,上下滑动时 列表头固定。

实现代码如下:

package com.uuch.android_zxinglibrary.tableview;

/**
 * created by wangqiubo on 2018-02-05.
 */

import android.support.v7.app.appcompatactivity;
import android.os.bundle;
import android.view.layoutinflater;
import android.view.view;
import android.view.viewgroup;
import android.widget.baseadapter;
import android.widget.linearlayout;
import android.widget.textview;

import com.uuch.android_zxinglibrary.r;

import java.util.arraylist;
import java.util.list;

public class tableactivity extends appcompatactivity {

    private noscrolllistview mleft;
    private leftadapter mleftadapter;

    private noscrolllistview mdata;
    private dataadapter mdataadapter;

    private synchorizontalscrollview mheaderhorizontal;
    private synchorizontalscrollview mdatahorizontal;

    private list mlistdata;

    @override
    protected void oncreate(bundle savedinstancestate) {
        super.oncreate(savedinstancestate);
        setcontentview(r.layout.list_row_main_layout);

        initview();
    }

    private void initview(){
        mleft = (noscrolllistview) findviewbyid(r.id.lv_left);
        mdata = (noscrolllistview) findviewbyid(r.id.lv_data);
        mdatahorizontal = (synchorizontalscrollview) findviewbyid(r.id.data_horizontal);
        mheaderhorizontal = (synchorizontalscrollview) findviewbyid(r.id.header_horizontal);

        mdatahorizontal.setscrollview(mheaderhorizontal);
        mheaderhorizontal.setscrollview(mdatahorizontal);

        mlistdata = new arraylist<>();
        mlistdata.add("1");
        mlistdata.add("2");
        mlistdata.add("3");
        mlistdata.add("4");
        mlistdata.add("5");
        mlistdata.add("6");
        mlistdata.add("7");
        mlistdata.add("8");
        mlistdata.add("9");
        mlistdata.add("10");
        mlistdata.add("11");
        mlistdata.add("12");
        mlistdata.add("13");

        mleftadapter= new leftadapter();
        mleft.setadapter(mleftadapter);

        mdataadapter = new dataadapter();
        mdata.setadapter(mdataadapter);
    }

    class leftadapter extends baseadapter {

        @override
        public int getcount() {
            return mlistdata.size();
        }

        @override
        public object getitem(int position) {
            return mlistdata.get(position);
        }

        @override
        public long getitemid(int position) {
            return position;
        }

        @override
        public view getview(int position, view convertview, viewgroup parent) {
            viewholder holder = null;
            if (convertview == null) {
                holder = new viewholder();
                convertview = layoutinflater.from(tableactivity.this).inflate(r.layout.table_column_left_layout, null);
                holder.tvleft = (textview) convertview.findviewbyid(r.id.tv_left);
                convertview.settag(holder);
            } else {
                holder = (viewholder) convertview.gettag();
            }

            holder.tvleft.settext("第" + position + "行");

            return convertview;
        }

        class viewholder {
            textview tvleft;
        }
    }

    class dataadapter extends baseadapter {

        @override
        public int getcount() {
            return mlistdata.size();
        }

        @override
        public object getitem(int position) {
            return mlistdata.get(position);
        }

        @override
        public long getitemid(int position) {
            return position;
        }

        @override
        public view getview(int position, view convertview, viewgroup parent) {
            viewholder holder = null;
            if(convertview == null){
                holder = new viewholder();
                convertview = layoutinflater.from(tableactivity.this).inflate(r.layout.achievement_row_layout, null);
                holder.tvdata = (textview) convertview.findviewbyid(r.id.tv_data);
                holder.lincontent = (linearlayout) convertview.findviewbyid(r.id.lin_content);
                convertview.settag(holder);
            }else{
                holder = (viewholder) convertview.gettag();
            }

            return convertview;
        }

        class viewholder {
            textview tvdata;
            linearlayout lincontent;
        }
    }
}
list_row_main_layout.xml




    

        

        

        

            

                

                    

                    

                    

                    

                    

                    

                    

                    

                    

                    
                
            
        
    

    

    

        

            

            

            

                

                    
                
            
        
    

对以上代码进行讲解如下:
1、noscrolllistview的定义。

package com.uuch.android_zxinglibrary.tableview;



import android.content.context;
import android.util.attributeset;
import android.widget.listview;

/**
 * created by wangqiubo on 2018-02-05.
 */

public class noscrolllistview extends listview {

    public noscrolllistview(context context) {
        super(context);
    }

    public noscrolllistview(context context, attributeset attrs) {
        super(context, attrs);
    }

    public noscrolllistview(context context, attributeset attrs, int defstyleattr) {
        super(context, attrs, defstyleattr);
    }

    /*
     *scrollview 中嵌套 listview 会发现有冲突,冲突问题就是无论怎么设置 listview 只显示一行
     * 究其原因就是因为listview的父容器测量模式为unspecified的时候,listview的高度默认为一个item的高度
     * 那么解决冲突,就需要重新设定listview的测量模式,因此,以下重写就是重写设置listview的测量模式为 most
     * unspecified 的值是0向左进位30,就是10 00000000000…(10后跟30个0)
     * exactly 的值是1向左进位30,就是01 00000000000…(01后跟30个0)
     * at_most 的值是2向左进位30,就是10 00000000000…(10后跟30个0)
    **/
    @override
    protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {
        int expandspec = measurespec.makemeasurespec(integer.max_value >> 2, measurespec.at_most);
        super.onmeasure(widthmeasurespec, expandspec);
    }
}

当scrollview 中嵌套 listview 的时候,怎样解决 scrollview、listview 不会同时滚动呢?另外如果scrollview 中嵌套了 listview ,一般listview 只会显示一行。根据上面noscrolllistview 的定义,实现思想就是 让listview不能滚动,实现不滚动的原理就是把所有数据都在listview 展示出来。因此通过设置 at_most 模式,让所有子项都显示出来,那么listview就不再滚动,这样只有scrollview 可以滚动了。

2、synchorizontalscrollview,水平滚动定义。

package com.uuch.android_zxinglibrary.tableview;


import android.content.context;
import android.util.attributeset;
import android.view.view;
import android.widget.horizontalscrollview;

/**
 /**
 * created by wangqiubo on 2018-02-05.
 */


public class synchorizontalscrollview extends horizontalscrollview {
    private view mview;

    public synchorizontalscrollview(context context) {
        super(context);
    }

    public synchorizontalscrollview(context context, attributeset attrs) {
        super(context, attrs);
    }

    public synchorizontalscrollview(context context, attributeset attrs, int defstyleattr) {
        super(context, attrs, defstyleattr);
    }

    protected void onscrollchanged(int l, int t, int oldl, int oldt) {
        super.onscrollchanged(l, t, oldl, oldt);
        if (mview != null) {
            mview.scrollto(l, t);
        }
    }

    public void setscrollview(view view) {
        mview = view;
    }
}

以上自定义水平滚动效果就是,当horizontalscrollview 滚动的时候,那么设置进来的mview 同步滚动,请查看 tableactivity 中的代码:

        mdatahorizontal = (synchorizontalscrollview) findviewbyid(r.id.data_horizontal);
        mheaderhorizontal = (synchorizontalscrollview) findviewbyid(r.id.header_horizontal);

        mdatahorizontal.setscrollview(mheaderhorizontal);
        mheaderhorizontal.setscrollview(mdatahorizontal);

mdatahorizontal 为行数据,mheaderhorizontal 为 列表头,mdatahorizontal 中的同步滚动mview = mheaderhorizontal;mheaderhorizontal中的同步滚动控件mview = mdatahorizontal 。因此,就实现了行数据和列表头可以同时左右滚动。

以上自定义的滑动表格存在问题如下:
noscrolllistview是通过设置 at_most 模式来解决 scrollview 中嵌套 listview 的滑动冲突问题。at_most 就是尺寸根据子节点的实际大小来确定最终大小,因此需要不停的来结算子节点的尺寸,如果涉及到大数据,就涉及到性能性问题。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网