由于项目中使用到一些重复并且不太复杂而且可以复用的控件组合,不停的粘贴复制也挺烦人的,并且布局文件写的很low,于是乎,激发我内心对美的追求和欲望,做一个优雅的码农!大家看下面的情况
这个场景是不是很熟悉,而且很多这样的情况,左图完全可以linearLayout里面放textview,edittext,右图可以linearLayout里面放textview,textview.这样下来,加上别的控件布局文件有个200-300行是没啥问题的,我想用几十行解决问题,并且google提倡我们复用.当然也有网友会说右边的图上的两个textview可以用一个来代替,这个我觉得不太行,因为右边的textview都是对齐的,如果每一行使用一个textview,那么和左边的距离无法控制,我希望用一个控件,设置一个左边一个宽度,右边一个宽度,这样就解决问题了.我们以右边的两个textview为例封装一个组合控件.
大体的思路是这样的:
第一:把这几个控件封装在一起写个布局文件,这个view继承自framlayout,并提供一些对外方法
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/llayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
tools:context="com.example.multiytextview.MainActivity">
<TextView
android:id="@+id/tv_left"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:text="abcdef"
tools:text="Hello !" />
<TextView
android:id="@+id/tv_right"
android:text="12233123"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text=" World!" />
</LinearLayout>
第二:自定义个属性
在value文件夹下创建attrs属性文件,定义这个组合控件的属性,其实还是textview控件本身的属性,我只是给他换个名字
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="textView2">
<!--左边textview属性:文字,大小,gravity,宽高,颜色-->
<attr name="leftText" format="string" />
<attr name="leftTextSize" format="dimension"/>
<attr name="leftGravity" format="integer" />
<attr name="leftWidth" format="dimension" />
<attr name="leftPaddingleft" format="dimension" />
<attr name="leftMargingleft" format="dimension" />
<attr name="leftHeight" format="dimension" />
<attr name="leftTextColor" format="color" />
<!--右边textview属性-->
<attr name="rightText" format="string" />
<attr name="rightTextSize" format="dimension" />
<attr name="rightPaddingleft" format="dimension" />
<attr name="rightMargingleft" format="dimension" />
<attr name="rightGravity" format="integer" />
<attr name="rightWidth" format="dimension" />
<attr name="rightHeight" format="dimension" />
<attr name="rightTextColor" format="color" />
</declare-styleable>
</resources>
第三:继承framlayout在view中获取属性,并设置给view
这个textview2就是我们封装好的控件,左边一个textview,右边一个textview,宽度高度字体大小padding都可以设置,当然这个就够我用了,你也可以在属性文件中自己定义要用到的属性在这个textview2类中一共干了两件事:
1:在构造函数中拿到在布局文件中设置的属性
2View.inflate()得到我们写好的布局文件的view
3设置拿到的属性给这个view
4添加到当前的Framlayout中
5对外暴露
package com.example.multiytextview; import android.content.Context; import android.content.res.TypedArray; import android.text.TextUtils; import android.util.AttributeSet; import android.view.View; import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.TextView; /** * Created by 瑜哥 on 2017/2/24. */ public class TextView2 extends FrameLayout { Context ctx; private TextView tvleft; private LinearLayout ll; private TextView tvright; private int leftHeight; private int leftWidth; private int leftGravity; private int leftTextColor; private String leftText; private float leftTextSize; private int leftPaddingleft; private int leftMargingleft; private int rightHeight; private float rightTextSize; private int rightPaddingleft; private int rightMargingleft; private int rightWidth; private int rightGravity; private int rightTextColor; private String rightText; public TextView2(Context context) { this(context,null); } public TextView2(Context context, AttributeSet attrs) { this(context, attrs,0); } public TextView2(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.ctx = context; if (attrs == null) { return; } initView(context, attrs, defStyleAttr); } private void initView(Context context, AttributeSet attrs, int defStyleAttr) { TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.textView2); leftHeight = typedArray.getDimensionPixelSize(R.styleable.textView2_leftHeight, -1); leftTextSize = typedArray.getDimensionPixelSize(R.styleable.textView2_leftTextSize, -1); leftPaddingleft = typedArray.getDimensionPixelSize(R.styleable.textView2_leftPaddingleft, -1); leftMargingleft = typedArray.getDimensionPixelSize(R.styleable.textView2_leftMargingleft, -1); leftWidth = typedArray.getDimensionPixelSize(R.styleable.textView2_leftWidth, -1); leftGravity = typedArray.getInteger(R.styleable.textView2_leftGravity, -1); leftTextColor = typedArray.getColor(R.styleable.textView2_leftTextColor, -1); leftText = typedArray.getString(R.styleable.textView2_leftText); rightHeight = typedArray.getDimensionPixelSize(R.styleable.textView2_rightHeight, -1); rightTextSize = typedArray.getDimensionPixelSize(R.styleable.textView2_rightTextSize, -1); rightPaddingleft = typedArray.getDimensionPixelSize(R.styleable.textView2_rightPaddingleft, -1); rightMargingleft = typedArray.getDimensionPixelSize(R.styleable.textView2_rightMargingleft, -1); rightWidth = typedArray.getDimensionPixelSize(R.styleable.textView2_rightWidth, -1); rightGravity = typedArray.getInteger(R.styleable.textView2_rightGravity, -1); rightTextColor = typedArray.getColor(R.styleable.textView2_rightTextColor, -1); rightText = typedArray.getString(R.styleable.textView2_rightText); typedArray.recycle(); ll = (LinearLayout) View.inflate(ctx, R.layout.textview2, null); tvleft = (TextView) ll.findViewById(R.id.tv_left); tvright = (TextView) ll.findViewById(R.id.tv_right); if (leftTextSize>0) { tvleft.setTextSize(leftTextSize); } if (leftGravity>0) { tvleft.setGravity(leftGravity); } LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) tvleft.getLayoutParams(); if (leftWidth > 0) { params.width = leftWidth; } if (leftHeight > 0) { params.height = leftHeight; } if (leftMargingleft>0) { params.setMargins(leftMargingleft, 0, 0, 0); } tvleft.setLayoutParams(params); if (leftPaddingleft>0) { tvleft.setPadding(leftPaddingleft,0,0,0); } if (leftTextColor!=-1) { tvleft.setTextColor(leftTextColor); } if (!TextUtils.isEmpty(leftText)) { tvleft.setText(leftText); } if (rightTextSize>0) { tvright.setTextSize(rightTextSize); } if (rightGravity>0) { tvright.setGravity(rightGravity); } if (rightMargingleft>0) { LinearLayout.LayoutParams params1 = (LinearLayout.LayoutParams)tvright.getLayoutParams(); params1.setMargins(rightMargingleft, 0, 0, 0); tvright.setLayoutParams(params); } if (rightTextColor!=-1) { tvright.setTextColor(rightTextColor); } if (!TextUtils.isEmpty(rightText)) { tvright.setText(rightText); } addView(ll); } public void setText(String string) { tvright.setText(string); } public String getText() { return tvright.getText().toString().trim(); } }
第四使用:直接使用在attr文件中定义好的属性就行 了<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/llayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:orientation="vertical" tools:context="com.example.multiytextview.MainActivity"> <com.example.multiytextview.TextView2 android:layout_width="match_parent" android:layout_height="40dp" app:leftHeight="50px" app:leftPaddingleft="20dp" app:leftText="抵用金可抵扣" app:leftTextColor="#0f0" app:leftTextSize="@dimen/activity_vertical_margin" app:leftWidth="500px" app:rightText="0.00" app:rightTextColor="#f0f" app:rightTextSize="@dimen/leftSize" /> <com.example.multiytextview.TextView2 android:layout_width="match_parent" android:layout_height="40dp" app:leftHeight="@dimen/leftHeight" app:leftPaddingleft="@dimen/Paddingleft" app:leftText="库存" app:leftTextColor="#098" app:leftTextSize="@dimen/activity_vertical_margin" app:leftWidth="@dimen/leftwidth" app:rightText="100" app:rightTextSize="@dimen/leftSize" /> <com.example.multiytextview.TextView2 android:layout_width="match_parent" android:layout_height="40dp" app:leftHeight="@dimen/leftHeight" app:leftPaddingleft="@dimen/Paddingleft" app:leftText="商品条目" app:leftTextColor="#0ff" app:leftTextSize="@dimen/activity_vertical_margin" app:leftWidth="@dimen/leftwidth" app:rightText="坚果杏仁" app:rightTextColor="#f0f" app:rightTextSize="@dimen/leftSize" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="界面2" /> </LinearLayout>
无论想让左边控件统一对齐还是右边控件统一对齐,都是那么容易,加上一个属性就形了,当然还可以把这些属性统一抽取到style里面,那么布局文件代码就更清爽了