安卓自定义文字居中排列控件

来源:互联网 发布:英特尔人工智能大会 编辑:程序博客网 时间:2024/05/19 17:59


语言表达能力有问题,先上效果图

开发中多多少少遇到这种需求

上面这行字和下面这行字需要左右对齐,一般我都是用一个相对布局包裹上面,然后在里面写3个TextView,但这样写多了就真的很烦,所以自定义一个控件来解决这个问题.

先上代码

public class CenterTextLayout extends LinearLayout{    private int width = 0;    private boolean isFirst = true;    public CenterTextLayout(Context context) {        this(context,null,0);    }    public CenterTextLayout(Context context, @Nullable AttributeSet attrs) {        this(context, attrs,0);    }    public CenterTextLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    private void init(){        Log.v("CenterTextLayoutMsg","width:" + width);        Log.v("CenterTextLayoutMsg","child count:" + getChildCount());        setOrientation(HORIZONTAL);        TextView tv = (TextView) getChildAt(0);        Log.v("CenterTextLayoutMsg","texts" + tv.getText().toString());        char[] texts = tv.getText().toString().toCharArray();        Log.v("CenterTextLayoutMsg","texts length:" + texts.length);        Log.v("CenterTextLayoutMsg","all text width:" + tv.getLayout().getWidth());//准确的拿到所有的字的长度,用于计算平均值        if(texts.length <= 1) {            return;        }        int textWidth = tv.getLayout().getWidth() / texts.length;        float textSize = tv.getTextSize();        Log.v("CenterTextLayoutMsg","textSize:" + textSize);        tv.setText(String.valueOf(texts[0]));        //解释一下,第一段,计算出除第一个字外剩下的宽度.第二点,计算出平局每个字所占的宽度.第三段,减去自己的宽度等于marginLeft        int marginLeft = (width - textWidth) / (texts.length - 1) - textWidth;        for(int i = 1;i < texts.length;i++){            TextView textView = new TextView(getContext());            textView.setText(String.valueOf(texts[i]));            textView.setTextSize(TypedValue.COMPLEX_UNIT_PX,textSize);            addView(textView);            CenterTextLayout.LayoutParams params = (LayoutParams) textView.getLayoutParams();            params.setMargins(marginLeft,0,0,0);            textView.setLayoutParams(params);        }    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        width = MeasureSpec.getSize(widthMeasureSpec);        if(isFirst) {            init();            isFirst = false;        }    }}

我的思路是:

1,继承LinearLayout,设置orientation为horizontal

2,然后在xml文件爱你里面的LinearLayout写一个textView,写要显示的内容

3,获取LinearLayou的第一个字viw,并转换成textView

4,将每个字都添加到一个tv,再把这个tv添加到ll,再设置tv的marginLeft

接下来是代码分析,目前我对控件的生命周期还不清楚,在测试中发现如果不判断是否第一次,总会出现这样那样的问题.所以如果能理解view的生命周期并想到办法,完全可以去掉isFirst

setOrientation(HORIZONTAL);TextView tv = (TextView) getChildAt(0);char[] texts = tv.getText().toString().toCharArray();if(texts.length <= 1) {    return;}
当字数小于等于1的时候,完全没必要继续下去

int textWidth = tv.getLayout().getWidth() / texts.length;float textSize = tv.getTextSize();int marginLeft = (width - textWidth) / (texts.length - 1) - textWidth;
这里的textWidth和textSize是一样的,也可以只用一个就够了

第三行计算marginLeft的值,with就是LinearLayout的宽度.第一段,总宽度减去第一个字的宽度,得到剩下的宽度.第二段,获取剩下的字数.第一段除以第二段得到剩下的每个字的平均宽度,再减去每个字的宽度,就得到每个字的marinLeft

for(int i = 1;i < texts.length;i++){       TextView textView = new TextView(getContext());       textView.setText(String.valueOf(texts[i]));       //注意:上面拿到的textSize的单位是px,但直接调用设置textSize的单位是sp,所以要调用这个方法设置单位      textView.setTextSize(TypedValue.COMPLEX_UNIT_PX,textSize);       addView(textView);       //将tv设置到ll之后才能拿到LayoutParams.这个时候才能设置margin      CenterTextLayout.LayoutParams params = (LayoutParams) textView.getLayoutParams();       params.setMargins(marginLeft,0,0,0);       textView.setLayoutParams(params);}


注:这种方式只支持中文,不支持英文和数字.因为发现每个英文和数字的字体大小都不一样,好像没那么容易计算,而且这种场景也不多


原创粉丝点击