安卓视线可锁定首行和首列的表格视图

如上图所示效果,整体视图构成已标记,联动效果通过两个CustomHorizontalScrollView的setOnScrollChangeListener方法绑定实现。

 

表格里面数据通过动态添加textview和分割线view绘制而成。

具体看以下代码:

package com.rmondjone.locktableview;

import android.content.Context;
import android.os.Handler;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 说明 可锁定首行和首列的表格视图
 * 作者 康汉斌
 * 创建时间 2017/3/29.
 */

public class LockTableView implements View.OnClickListener {
    /**
     * 上下文
     */
    private Context mContext;
    /**
     * 表格父视图
     */
    private ViewGroup mContentView;
    /**
     * 表格数据,每一行为一条数据,从表头计算
     */
    private ArrayList<ArrayList<String>> mTableDatas = new ArrayList<ArrayList<String>>();
    /**
     * 表格视图
     */
    private View mTableView;
    /**
     * 是否锁定首行
     */
    private boolean isLockFristRow = true;
    /**
     * 是否锁定首列
     */
    private boolean isLockFristColumn = true;
    /**
     * 最大列宽(dp)
     */
    private int maxColumnWidth;
    /**
     * 最小列宽(dp)
     */
    private int minColumnWidth;
    /**
     * 最大行高(dp)
     */
    private int maxRowHeight;
    /**
     * 最小行高dp)
     */
    private int minRowHeight;
    /**
     * 第一行背景颜色
     */
    private int mFristRowBackGroudColor;
    /**
     * 数据为空时的缺省值
     */
    private String mNullableString;
    /**
     * 单元格字体大小
     */
    private int mTextViewSize;
    /**
     * 表格头部字体颜色
     */
    private int mTableHeadTextColor;
    /**
     * 表格内容字体颜色
     */
    private int mTableContentTextColor;
    /**
     * 表格监听事件
     */
    private OnTableViewListener mTableViewListener;


    //表格数据
    /**
     * 表格第一行数据,不包括第一个元素
     */
    private ArrayList<String> mTableFristData = new ArrayList<>();
    /**
     * 表格第一列数据,不包括第一个元素
     */
    private ArrayList<String> mTableColumnDatas = new ArrayList<>();
    /**
     * 表格左上角数据
     */
    private String mColumnTitle;
    /**
     * 表格每一行数据,不包括第一行和第一列
     */
    private ArrayList<ArrayList<String>> mTableRowDatas = new ArrayList<ArrayList<String>>();
    /**
     * 记录每列最大宽度
     */
    private ArrayList<Integer> mColumnMaxWidths = new ArrayList<Integer>();
    /**
     * 记录每行最大高度
     */
    private ArrayList<Integer> mRowMaxHeights = new ArrayList<Integer>();
    /**
     * 把所有的滚动视图放图列表,后面实现联动效果
     */
    private ArrayList<HorizontalScrollView> mScrollViews = new ArrayList<HorizontalScrollView>();


    //表格视图
    /**
     * 表格左上角视图
     */
    private TextView mColumnTitleView;
    /**
     * 第一行布局(锁状态)
     */
    private LinearLayout mLockHeadView;
    /**
     * 第一行布局(未锁状态)
     */
    private LinearLayout mUnLockHeadView;
    /**
     * 第一行滚动视图(锁状态)
     */
    private CustomHorizontalScrollView mLockScrollView;
    /**
     * 第一行滚动视图(未锁状态)
     */
    private CustomHorizontalScrollView mUnLockScrollView;
    /**
     * 表格主视图
     */
    private ScrollView mTableScrollView;

    private View lockTableViewContent;

    private CustomHorizontalScrollView lockScrollViewParent;


    /**
     * 构造方法
     *
     * @param mContext 上下文
     * @param mContentView 表格父视图
     * @param mTableDatas 表格数据
     */
    public LockTableView(Context mContext, ViewGroup mContentView, ArrayList<ArrayList<String>> mTableDatas) {
        this.mContext = mContext;
        this.mContentView = mContentView;
        this.mTableDatas = mTableDatas;
        initAttrs();
    }

    /**
     * 初始化属性
     */
    private void initAttrs() {
        mTableView = LayoutInflater.from(mContext).inflate(R.layout.locktableview, null);
        maxColumnWidth = 100;
        minColumnWidth = 70;
        minRowHeight=20;
        maxRowHeight=60;
        mNullableString = "N/A";
        mTableHeadTextColor = R.color.beijin;
        mTableContentTextColor = R.color.border_color;
        mFristRowBackGroudColor = R.color.table_head;
        mTextViewSize = 16;
    }

    /**
     * 展现视图
     */
    public void show() {
        initData();
        initView();
        mContentView.addView(mTableView);
    }


    /**
     * 初始化表格数据
     */
    private void initData() {
        if (mTableDatas != null && mTableDatas.size() > 0) {
            //检查数据,如果有一行数据长度不一致,以最长为标准填"N/A"字符串,如果有null也替换
            int maxLength = 0;
            for (int i = 0; i < mTableDatas.size(); i++) {
                if (mTableDatas.get(i).size() >= maxLength) {
                    maxLength = mTableDatas.get(i).size();
                }
                ArrayList<String> rowDatas = mTableDatas.get(i);
                for (int j = 0; j < rowDatas.size(); j++) {
                    if (rowDatas.get(j) == null || rowDatas.get(j).equals("")) {
                        rowDatas.set(j, mNullableString);
                    }
                }
                mTableDatas.set(i, rowDatas);
            }
//            Log.e("每行最多个数",maxLength+"");
            for (int i = 0; i < mTableDatas.size(); i++) {
                ArrayList<String> rowDatas = mTableDatas.get(i);
                if (rowDatas.size() < maxLength) {
                    int size=maxLength - rowDatas.size();
                    for (int j = 0; j <size; j++) {
                        rowDatas.add(mNullableString);
                    }
                    mTableDatas.set(i, rowDatas);
                }
            }

//            //测试
//            for (int i=0;i<mTableDatas.size();i++){
//                ArrayList<String> rowDatas=mTableDatas.get(i);
//                StringBuffer b=new StringBuffer();
//                for (String str:rowDatas){
//                    b.append("["+str+"]");
//                }
//                Log.e("第"+i+"行数据",b.toString()+"/"+rowDatas.size()+"个");
//            }
            //初始化每列最大宽度
            for (int i = 0; i < mTableDatas.size(); i++) {
                ArrayList<String> rowDatas = mTableDatas.get(i);
                StringBuffer buffer = new StringBuffer();
                for (int j = 0; j < rowDatas.size(); j++) {
                    TextView textView = new TextView(mContext);
                    textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextViewSize);
                    textView.setText(rowDatas.get(j));
                    textView.setGravity(Gravity.CENTER);
                    //设置布局
                    LinearLayout.LayoutParams textViewParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                            LinearLayout.LayoutParams.WRAP_CONTENT);
                    textViewParams.setMargins(45, 45, 45, 45);//android:layout_margin="15dp"
                    textView.setLayoutParams(textViewParams);
                    if (i == 0) {
                        mColumnMaxWidths.add(measureTextWidth(textView, rowDatas.get(j)));
                        buffer.append("[" + measureTextWidth(textView, rowDatas.get(j)) + "]");
                    } else {
                        int length = mColumnMaxWidths.get(j);
                        int current = measureTextWidth(textView, rowDatas.get(j));
                        if (current > length) {
                            mColumnMaxWidths.set(j, current);
                        }
                        buffer.append("[" + measureTextWidth(textView, rowDatas.get(j)) + "]");
                    }
                }
//                Log.e("第"+i+"行列最大宽度",buffer.toString());
            }
//            Log.e("每列最大宽度dp:",mColumnMaxWidths.toString());


            //初始化每行最大高度
            for (int i = 0; i < mTableDatas.size(); i++) {
                ArrayList<String> rowDatas = mTableDatas.get(i);
                StringBuffer buffer = new StringBuffer();

                TextView textView = new TextView(mContext);
                textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextViewSize);
                textView.setGravity(Gravity.CENTER);
                //设置布局
                LinearLayout.LayoutParams textViewParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                        LinearLayout.LayoutParams.WRAP_CONTENT);
                textViewParams.setMargins(45, 45, 45, 45);//android:layout_margin="15dp"
                textView.setLayoutParams(textViewParams);
                int maxHeight=measureTextHeight(textView,rowDatas.get(0));
                mRowMaxHeights.add(maxHeight);
                for (int j = 0; j < rowDatas.size(); j++) {
                    int currentHeight=measureTextHeight(textView,rowDatas.get(j));
                    buffer.append("["+currentHeight+"]");
                    if (currentHeight>maxHeight){
                        mRowMaxHeights.set(i,currentHeight);
                    }
                }
//                Log.e("第"+i+"行高度",buffer.toString());
            }
//            Log.e("每行最大高度dp:",mRowMaxHeights.toString());

            if (isLockFristRow) {
                ArrayList<String> fristRowDatas = mTableDatas.get(0);
                if (isLockFristColumn) {
                    //锁定第一列
                    mColumnTitle = fristRowDatas.get(0);
                    fristRowDatas.remove(0);
                    mTableFristData.addAll(fristRowDatas);
                    //构造第一列数据,并且构造表格每行数据
                    for (int i = 1; i < mTableDatas.size(); i++) {
                        ArrayList<String> rowDatas = mTableDatas.get(i);
                        mTableColumnDatas.add(rowDatas.get(0));
                        rowDatas.remove(0);
                        mTableRowDatas.add(rowDatas);
                    }
                } else {
                    mTableFristData.addAll(fristRowDatas);
                    for (int i = 1; i < mTableDatas.size(); i++) {
                        mTableRowDatas.add(mTableDatas.get(i));
                    }
                }
            } else {
                if (isLockFristColumn) {
                    //锁定第一列
                    //构造第一列数据,并且构造表格每行数据
                    for (int i = 0; i < mTableDatas.size(); i++) {
                        ArrayList<String> rowDatas = mTableDatas.get(i);
                        mTableColumnDatas.add(rowDatas.get(0));
                        rowDatas.remove(0);
                        mTableRowDatas.add(rowDatas);
                    }
                } else {
                    for (int i = 0; i < mTableDatas.size(); i++) {
                        mTableRowDatas.add(mTableDatas.get(i));
                    }
                }
            }

//            Log.e("第一行数据",mTableFristData.toString());
//            Log.e("第一列数据",mTableColumnDatas.toString());
//            Log.e("每行数据",mTableRowDatas.toString());
        } else {
            Toast.makeText(mContext, "表格数据为空!", Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 初始化表格视图
     */
    private void initView() {
        mColumnTitleView = (TextView) mTableView.findViewById(R.id.lockHeadView_Text);
        mLockHeadView = (LinearLayout) mTableView.findViewById(R.id.lockHeadView);
        mUnLockHeadView = (LinearLayout) mTableView.findViewById(R.id.unLockHeadView);
        mLockScrollView = (CustomHorizontalScrollView) mTableView.findViewById(R.id.lockHeadView_ScrollView);
        mUnLockScrollView = (CustomHorizontalScrollView) mTableView.findViewById(R.id.unlockHeadView_ScrollView);
        mTableScrollView = (ScrollView) mTableView.findViewById(R.id.table_scrollView);
        mLockHeadView.setBackgroundColor(ContextCompat.getColor(mContext, mFristRowBackGroudColor));
        mUnLockHeadView.setBackgroundColor(ContextCompat.getColor(mContext, mFristRowBackGroudColor));

        if (isLockFristRow) {
            if (isLockFristColumn) {
                mLockHeadView.setVisibility(View.VISIBLE);
                mUnLockHeadView.setVisibility(View.GONE);
            } else {
                mLockHeadView.setVisibility(View.GONE);
                mUnLockHeadView.setVisibility(View.VISIBLE);
            }
            creatHeadView();
        } else {
            mLockHeadView.setVisibility(View.GONE);
            mUnLockHeadView.setVisibility(View.GONE);
        }
        createTableView();
    }

    /**
     * 创建头部视图
     */
    private void creatHeadView() {
        if (isLockFristColumn) {
            mColumnTitleView.setTextColor(ContextCompat.getColor(mContext, mTableHeadTextColor));
            mColumnTitleView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextViewSize);
            mColumnTitleView.setText(mColumnTitle);
            LinearLayout.LayoutParams layoutParams =(LinearLayout.LayoutParams) mColumnTitleView.getLayoutParams();
            layoutParams.width = DisplayUtil.dip2px(mContext, mColumnMaxWidths.get(0));
            layoutParams.height=DisplayUtil.dip2px(mContext,mRowMaxHeights.get(0));
            layoutParams.setMargins(45, 45, 45, 45);
            mColumnTitleView.setLayoutParams(layoutParams);
            //构造滚动视图
            createScollview(mLockScrollView, mTableFristData, true);
            mScrollViews.add(mLockScrollView);
            mLockScrollView.setOnScrollChangeListener(new CustomHorizontalScrollView.onScrollChangeListener() {
                @Override
                public void onScrollChanged(HorizontalScrollView scrollView, int x, int y) {
                    changeAllScrollView(x, y);
                }
            });
        } else {
            createScollview(mUnLockScrollView, mTableFristData, true);
            mScrollViews.add(mUnLockScrollView);
            mUnLockScrollView.setOnScrollChangeListener(new CustomHorizontalScrollView.onScrollChangeListener() {
                @Override
                public void onScrollChanged(HorizontalScrollView scrollView, int x, int y) {
                    changeAllScrollView(x, y);
                }
            });
        }
    }

    /**
     * 构造表格主视图
     */
    private void createTableView() {
        if (isLockFristColumn) {
            createLockColumnView();
        } else {
            createUnLockColumnView();
        }
    }

    /**
     * 创建锁定列视图
     */
    private void createLockColumnView() {
         lockTableViewContent=LayoutInflater.from(mContext).inflate(R.layout.locktablecontentview,null);
        LinearLayout lockViewParent=(LinearLayout) lockTableViewContent.findViewById(R.id.lockView_parent);
         lockScrollViewParent=(CustomHorizontalScrollView)lockTableViewContent.findViewById(R.id.lockScrollView_parent);
        //构造锁定视图
        for (int i=0;i<mTableColumnDatas.size();i++){
            //构造TextView容器,如果要设置背景色设置这一个而不是设置TextView,TextView有外边距设置不全
            LinearLayout textViewContainer=new LinearLayout(mContext);
            LinearLayout.LayoutParams textLinearParams=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);
            textViewContainer.setOrientation(LinearLayout.HORIZONTAL);
            textViewContainer.setLayoutParams(textLinearParams);
            //构造TextView
            TextView textView=new TextView(mContext);
            //设置布局
            LinearLayout.LayoutParams textViewParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);
            textViewParams.setMargins(45, 45, 45, 45);
            textView.setLayoutParams(textViewParams);
            textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextViewSize);
            textView.setText(mTableColumnDatas.get(i));
            textView.setGravity(Gravity.CENTER);
            ViewGroup.LayoutParams layoutParams = textView.getLayoutParams();
            layoutParams.width = DisplayUtil.dip2px(mContext, mColumnMaxWidths.get(0));
            if (isLockFristRow){
                layoutParams.height=DisplayUtil.dip2px(mContext,mRowMaxHeights.get(i+1));
            }else{
                layoutParams.height=DisplayUtil.dip2px(mContext,mRowMaxHeights.get(i));
            }
            textView.setLayoutParams(layoutParams);
            if (!isLockFristRow){
                if (i==0){
                    textViewContainer.setBackgroundColor(ContextCompat.getColor(mContext,mFristRowBackGroudColor));
                    textView.setTextColor(ContextCompat.getColor(mContext, mTableHeadTextColor));
                }else{
                    textView.setTextColor(ContextCompat.getColor(mContext, mTableContentTextColor));
                }
            }else{
                textView.setTextColor(ContextCompat.getColor(mContext, mTableContentTextColor));
            }
            textViewContainer.addView(textView);
            //表格线
            View splite=new View(mContext);
            ViewGroup.LayoutParams spliteLayoutParam= new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    DisplayUtil.dip2px(mContext,1));
            splite.setLayoutParams(spliteLayoutParam);
            splite.setBackgroundColor(ContextCompat.getColor(mContext,R.color.light_gray));
            lockViewParent.addView(textViewContainer);
            lockViewParent.addView(splite);
        }
        //构造滚动视图
        LinearLayout scollViewItemContentView=new LinearLayout(mContext);
        LinearLayout.LayoutParams scollViewItemContentViewParams=new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        scollViewItemContentView.setLayoutParams(scollViewItemContentViewParams);
        scollViewItemContentView.setOrientation(LinearLayout.VERTICAL);
        for (int i=0;i<mTableRowDatas.size();i++){
            final ArrayList<String> datas=mTableRowDatas.get(i);
            //设置LinearLayout
            LinearLayout linearLayout = new LinearLayout(mContext);
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);
            linearLayout.setLayoutParams(layoutParams);
            linearLayout.setGravity(Gravity.CENTER);
            linearLayout.setOrientation(LinearLayout.HORIZONTAL);
            if (!isLockFristRow){
                if (i==0){
                    linearLayout.setBackgroundColor(ContextCompat.getColor(mContext,mFristRowBackGroudColor));
                }
            }
            for (int j = 0; j < datas.size(); j++) {
                //构造单元格
                TextView textView = new TextView(mContext);
                if (!isLockFristRow){
                    if (i==0) {
                        textView.setTextColor(ContextCompat.getColor(mContext, mTableHeadTextColor));
                    } else {
                        textView.setTextColor(ContextCompat.getColor(mContext, mTableContentTextColor));
                    }
                }else{
                    textView.setTextColor(ContextCompat.getColor(mContext, mTableContentTextColor));
                }
                textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextViewSize);
                textView.setGravity(Gravity.CENTER);
                textView.setText(datas.get(j));
                //设置布局
                LinearLayout.LayoutParams textViewParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                        LinearLayout.LayoutParams.WRAP_CONTENT);
                textViewParams.setMargins(45, 45, 45, 45);
                if (isLockFristRow){
                    textViewParams.height=DisplayUtil.dip2px(mContext,mRowMaxHeights.get(i+1));
                }else{
                    textViewParams.height=DisplayUtil.dip2px(mContext,mRowMaxHeights.get(i));
                }
                textView.setLayoutParams(textViewParams);
                ViewGroup.LayoutParams textViewParamsCopy = textView.getLayoutParams();
                textViewParamsCopy.width = DisplayUtil.dip2px(mContext, mColumnMaxWidths.get(j+1));
                linearLayout.addView(textView);
                //右侧分隔线
                if (j != datas.size() - 1) {
                    View splitView = new View(mContext);
                    ViewGroup.LayoutParams splitViewParmas = new ViewGroup.LayoutParams(DisplayUtil .dip2px(mContext, 1),
                            ViewGroup.LayoutParams.MATCH_PARENT);
                    splitView.setLayoutParams(splitViewParmas);
                    if (!isLockFristRow){
                        if (i==0) {
                            splitView.setBackgroundColor(ContextCompat.getColor(mContext, R.color.white));
                        } else {
                            splitView.setBackgroundColor(ContextCompat.getColor(mContext, R.color.light_gray));
                        }
                    }else{
                        splitView.setBackgroundColor(ContextCompat.getColor(mContext, R.color.light_gray));
                    }
                    linearLayout.addView(splitView);
                }
                //加入点击事件
                // 加入点击事件
                final int finalJ = j;
                textView.setClickable(true);

                final int finalI = i;
                textView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Log.e("断案事件", datas.get(finalJ));
                        String msg = "";
                        if (finalJ == 0) {
                            msg = mTableColumnDatas.get(finalI)+"下一个数据为" + datas.get(finalJ + 1);
                        } else if (finalJ == datas.size() - 1) {
                            msg = "上个数据为" + datas.get(finalJ - 1);
                        } else {
                            msg = "上个数据为" + datas.get(finalJ - 1) + "\n" + "下一个数据为" + datas.get(finalJ + 1);
                        }
                        new AlertDialog.Builder(mContext)
                                .setTitle("短按提示")
                                .setMessage(msg)
                                .setCancelable(true)
                                .show();
                    }
                });
                // 加入长按事件
                textView.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View v) {
                        Log.e("长按事件", datas.get(finalJ));
                        String msg = "";
                        if (finalJ == 0) {
                            msg = "下一个数据为" + datas.get(finalJ + 1);
                        } else if (finalJ == datas.size() - 1) {
                            msg = "上个数据为" + datas.get(finalJ - 1);

                        } else {
                            msg = "上个数据为" + datas.get(finalJ - 1) + "\n" + "下一个数据为" + datas.get(finalJ + 1);

                        }
                        new AlertDialog.Builder(mContext)
                                .setTitle("短按提示")
                                .setMessage(msg)
                                .setCancelable(true)
                                .show();
                        return true;
                    }
                });
            }
            scollViewItemContentView.addView(linearLayout);
            //底部分隔线
            View splite=new View(mContext);
            ViewGroup.LayoutParams spliteLayoutParam= new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    DisplayUtil.dip2px(mContext,1));
            splite.setLayoutParams(spliteLayoutParam);
            splite.setBackgroundColor(ContextCompat.getColor(mContext,R.color.light_gray));
            scollViewItemContentView.addView(splite);
        }
        lockScrollViewParent.addView(scollViewItemContentView);
        mScrollViews.add(lockScrollViewParent);
        lockScrollViewParent.setOnScrollChangeListener(new CustomHorizontalScrollView.onScrollChangeListener() {
            @Override
            public void onScrollChanged(HorizontalScrollView scrollView, int x, int y) {
                changeAllScrollView(x,y);
            }
        });
        mTableScrollView.addView(lockTableViewContent);
    }

    /**
     * 创建不锁定列视图
     */
    private void createUnLockColumnView() {
        lockTableViewContent=LayoutInflater.from(mContext).inflate(R.layout.unlocktablecontentview,null);
        lockScrollViewParent=(CustomHorizontalScrollView) lockTableViewContent.findViewById(R.id.unlockScrollView_parent);
        //构造滚动视图
        LinearLayout scollViewItemContentView=new LinearLayout(mContext);
        LinearLayout.LayoutParams scollViewItemContentViewParams=new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        scollViewItemContentView.setLayoutParams(scollViewItemContentViewParams);
        scollViewItemContentView.setOrientation(LinearLayout.VERTICAL);
        for (int i=0;i<mTableRowDatas.size();i++){
            ArrayList<String> datas=mTableRowDatas.get(i);
            //设置LinearLayout
            LinearLayout linearLayout = new LinearLayout(mContext);
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);
            linearLayout.setLayoutParams(layoutParams);
            linearLayout.setGravity(Gravity.CENTER);
            linearLayout.setOrientation(LinearLayout.HORIZONTAL);
            if (!isLockFristRow){
                if (i==0){
                    linearLayout.setBackgroundColor(ContextCompat.getColor(mContext,mFristRowBackGroudColor));
                }
            }
            for (int j = 0; j < datas.size(); j++) {
                //构造单元格
                TextView textView = new TextView(mContext);
                if (!isLockFristRow){
                    if (i==0) {
                        textView.setTextColor(ContextCompat.getColor(mContext, mTableHeadTextColor));
                    } else {
                        textView.setTextColor(ContextCompat.getColor(mContext, mTableContentTextColor));
                    }
                }else{
                    textView.setTextColor(ContextCompat.getColor(mContext, mTableContentTextColor));
                }
                textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextViewSize);
                textView.setGravity(Gravity.CENTER);
                textView.setText(datas.get(j));
                //设置布局
                LinearLayout.LayoutParams textViewParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                        LinearLayout.LayoutParams.WRAP_CONTENT);
                textViewParams.setMargins(45, 45, 45, 45);
                if (isLockFristRow){
                    textViewParams.height=DisplayUtil.dip2px(mContext,mRowMaxHeights.get(i+1));
                }else{
                    textViewParams.height=DisplayUtil.dip2px(mContext,mRowMaxHeights.get(i));
                }
                textView.setLayoutParams(textViewParams);
                ViewGroup.LayoutParams textViewParamsCopy = textView.getLayoutParams();
                textViewParamsCopy.width = DisplayUtil.dip2px(mContext, mColumnMaxWidths.get(j));
                linearLayout.addView(textView);
                //右侧分隔线
                if (j != datas.size() - 1) {
                    View splitView = new View(mContext);
                    ViewGroup.LayoutParams splitViewParmas = new ViewGroup.LayoutParams(DisplayUtil.dip2px(mContext, 1),
                            ViewGroup.LayoutParams.MATCH_PARENT);
                    splitView.setLayoutParams(splitViewParmas);
                    if (!isLockFristRow){
                        if (i==0) {
                            splitView.setBackgroundColor(ContextCompat.getColor(mContext, R.color.white));
                        } else {
                            splitView.setBackgroundColor(ContextCompat.getColor(mContext, R.color.light_gray));
                        }
                    }else{
                        splitView.setBackgroundColor(ContextCompat.getColor(mContext, R.color.light_gray));
                    }
                    linearLayout.addView(splitView);
                }
            }
            scollViewItemContentView.addView(linearLayout);
            //底部分隔线
            View splite=new View(mContext);
            ViewGroup.LayoutParams spliteLayoutParam= new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    DisplayUtil.dip2px(mContext,1));
            splite.setLayoutParams(spliteLayoutParam);
            splite.setBackgroundColor(ContextCompat.getColor(mContext,R.color.light_gray));
            scollViewItemContentView.addView(splite);
        }
        lockScrollViewParent.addView(scollViewItemContentView);
        mScrollViews.add(lockScrollViewParent);
        lockScrollViewParent.setOnScrollChangeListener(new CustomHorizontalScrollView.onScrollChangeListener() {
            @Override
            public void onScrollChanged(HorizontalScrollView scrollView, int x, int y) {
                changeAllScrollView(x,y);
            }
        });
        mTableScrollView.addView(lockTableViewContent);
    }

    /**
     * 改变所有滚动视图位置
     *
     * @param x
     * @param y
     */
    private void changeAllScrollView(int x, int y) {
        if (mScrollViews.size() > 0) {
            if (mTableViewListener!=null){
                mTableViewListener.onTableViewScrollChange(x,y);
            }
            for (int i = 0; i < mScrollViews.size(); i++) {
                HorizontalScrollView scrollView = mScrollViews.get(i);
                scrollView.scrollTo(x, y);
            }
        }
    }

    /**
     * 根据最大最小值,计算TextView的宽度
     *
     * @param textView
     * @param text
     * @return
     */
    private int measureTextWidth(TextView textView, String text) {
        if (textView != null) {
            LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) textView.getLayoutParams();
            int width = DisplayUtil.px2dip(mContext, layoutParams.leftMargin) +
                    DisplayUtil.px2dip(mContext, layoutParams.rightMargin) +
                    getTextViewWidth(textView, text);
            if (width <= minColumnWidth) {
                return minColumnWidth;
            } else if (width > minColumnWidth && width <= maxColumnWidth) {
                return width;
            } else {
                return maxColumnWidth;
            }
        }
        return 0;
    }

    /**
     * 计算TextView高度
     * @param textView
     * @param text
     * @return
     */
    private int measureTextHeight(TextView textView,String text){
        if (textView != null) {
            LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) textView.getLayoutParams();
            int height = getTextViewHeight(textView, text);
            if (height<minRowHeight){
                return minRowHeight;
            }else if(height>minRowHeight&&height<maxRowHeight){
                return height;
            }else{
                return maxRowHeight;
            }
        }
        return 0;
    }

    /**
     * 根据文字计算textview的高度
     *
     * @param textView
     * @param text
     * @return
     */
    private int getTextViewHeight(TextView textView, String text) {
        if (textView != null) {
            int width=measureTextWidth(textView,text);
            TextPaint textPaint  = textView.getPaint();
            StaticLayout staticLayout = new StaticLayout(text, textPaint, DisplayUtil.dip2px(mContext,width), Layout.Alignment.ALIGN_NORMAL, 1, 0, false);
            int height=DisplayUtil.px2dip(mContext,staticLayout.getHeight());
            return height;
        }
        return 0;
    }

    /**
     * 根据文字计算textview的高度
     *
     * @param view
     * @param text
     * @return
     */
    private int getTextViewWidth(TextView view, String text) {
        if (view != null) {
            TextPaint paint = view.getPaint();
            return DisplayUtil.px2dip(mContext, (int) paint.measureText(text));
        }
        return 0;
    }


    /**
     * 构造滚动视图
     *
     * @param scrollView
     * @param datas
     * @param isFristRow 是否是第一行
     */
    private void createScollview(HorizontalScrollView scrollView, List<String> datas, boolean isFristRow) {
        //设置LinearLayout
        LinearLayout linearLayout = new LinearLayout(mContext);
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.MATCH_PARENT);
        linearLayout.setLayoutParams(layoutParams);
        linearLayout.setGravity(Gravity.CENTER);
        linearLayout.setOrientation(LinearLayout.HORIZONTAL);
        for (int i = 0; i < datas.size(); i++) {
            //构造单元格
            TextView textView = new TextView(mContext);
            if (isFristRow) {
                textView.setTextColor(ContextCompat.getColor(mContext, mTableHeadTextColor));
            } else {
                textView.setTextColor(ContextCompat.getColor(mContext, mTableContentTextColor));
            }
            textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextViewSize);
            textView.setGravity(Gravity.CENTER);
            textView.setText(datas.get(i));
            //设置布局
            LinearLayout.LayoutParams textViewParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);
            textViewParams.setMargins(45, 45, 45, 45);
            textView.setLayoutParams(textViewParams);
            ViewGroup.LayoutParams textViewParamsCopy = textView.getLayoutParams();
            if (isLockFristColumn) {
                textViewParamsCopy.width = DisplayUtil.dip2px(mContext, mColumnMaxWidths.get(i + 1));
            } else {
                textViewParamsCopy.width = DisplayUtil.dip2px(mContext, mColumnMaxWidths.get(i));
            }
            linearLayout.addView(textView);
            //画分隔线
            if (i != datas.size() - 1) {
                View splitView = new View(mContext);
                ViewGroup.LayoutParams splitViewParmas = new ViewGroup.LayoutParams(DisplayUtil.dip2px(mContext, 1),
                        ViewGroup.LayoutParams.MATCH_PARENT);
                splitView.setLayoutParams(splitViewParmas);
                if (isFristRow) {
                    splitView.setBackgroundColor(ContextCompat.getColor(mContext, R.color.white));
                } else {
                    splitView.setBackgroundColor(ContextCompat.getColor(mContext, R.color.light_gray));
                }
                linearLayout.addView(splitView);
            }
        }
        scrollView.addView(linearLayout);
    }


    //属性设置
    public LockTableView setLockFristRow(boolean lockFristRow) {
        isLockFristRow = lockFristRow;
        return this;
    }

    public LockTableView setLockFristColumn(boolean lockFristColumn) {
        isLockFristColumn = lockFristColumn;
        return this;
    }

    public LockTableView setMaxColumnWidth(int maxColumnWidth) {
        this.maxColumnWidth = maxColumnWidth;
        return this;
    }

    public LockTableView setMinColumnWidth(int minColumnWidth) {
        this.minColumnWidth = minColumnWidth;
        return this;
    }

    public LockTableView setFristRowBackGroudColor(int mFristRowBackGroudColor) {
        this.mFristRowBackGroudColor = mFristRowBackGroudColor;
        return this;
    }

    public LockTableView setNullableString(String mNullableString) {
        this.mNullableString = mNullableString;
        return this;
    }

    public LockTableView setTextViewSize(int mTextViewSize) {
        this.mTextViewSize = mTextViewSize;
        return this;
    }

    public LockTableView setTableHeadTextColor(int mTableHeadTextColor) {
        this.mTableHeadTextColor = mTableHeadTextColor;
        return this;
    }

    public LockTableView setTableContentTextColor(int mTableContentTextColor) {
        this.mTableContentTextColor = mTableContentTextColor;
        return this;
    }

    public LockTableView setMaxRowHeight(int maxRowHeight) {
        this.maxRowHeight = maxRowHeight;
        return this;
    }

    public LockTableView setMinRowHeight(int minRowHeight) {
        this.minRowHeight = minRowHeight;
        return this;
    }

    public LockTableView setTableViewListener(OnTableViewListener mTableViewListener) {
        this.mTableViewListener = mTableViewListener;
        return this;
    }

    /**
     * 设置数据源
     * @param tableDatas
     * @return
     */
    public LockTableView setTableViewDatas(ArrayList<ArrayList<String>> tableDatas) {
        this.mTableDatas = tableDatas;
        return this;
    }

    public LockTableView setScrollToBottom() {

        Handler mHandler = new Handler();
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mTableScrollView.fullScroll(ScrollView.FOCUS_DOWN);
            }
        });
        return this;
    }
    public LockTableView setScrollToRight() {

        Handler mHandler = new Handler();
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                lockScrollViewParent.fullScroll(ScrollView.FOCUS_RIGHT);
            }
        });
        return this;
    }


    /**
     * 添加数据钱重置
     * @return
     */
    public LockTableView clear() {
        mTableFristData.clear();
        mTableColumnDatas.clear();
        mTableRowDatas.clear();

        mContentView.removeAllViews();
        mLockScrollView.removeAllViews();
        mTableScrollView.removeAllViews();
        return this;
    }


    //值获取
    public ArrayList<Integer> getColumnMaxWidths() {
        return mColumnMaxWidths;
    }

    public ArrayList<Integer> getRowMaxHeights() {
        return mRowMaxHeights;
    }

    public LinearLayout getLockHeadView() {
        return mLockHeadView;
    }

    public LinearLayout getUnLockHeadView() {
        return mUnLockHeadView;
    }

    public ArrayList<HorizontalScrollView> getScrollViews() {
        return mScrollViews;
    }

    @Override
    public void onClick(View v) {

    }

    //回调监听
    public interface OnTableViewListener{
        /**
         * 滚动监听
         * @param x
         * @param y
         */
        void onTableViewScrollChange(int x,int y);
    }
}















 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值