android中的xml十分方便,在大部分时候xml基本上都能解决问题了,不过有的时候还是不得不用上代码布局,比如动态布局, 或者是通过代码布局来获得更好的复用性。实际上代码布局是相对比较麻烦,因为设置View的属性的时候, 我们需要关心父布局到底是什么布局,才能设置相应的Param,本文讲讲,如何封装代码,让代码布局和xml布局变得一样简单。
我们要实现一个这样的简单的布局,用xml实现非常简单,不过xml的代码量也是不少了,但主要是复制粘贴,所以还是很快的。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_margin="10dp"
android:background="@color/graycolor">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="No.1"
android:gravity="center_vertical"
android:layout_marginLeft="10dp"
android:textSize="20dp"/>
LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_margin="10dp"
android:background="@color/graycolor">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="No.2"
android:gravity="center_vertical"
android:layout_marginLeft="10dp"
android:textSize="20dp"/>
LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_margin="10dp"
android:background="@color/graycolor">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="No.2"
android:gravity="center_vertical"
android:layout_marginLeft="10dp"
android:textSize="20dp"/>
LinearLayout>
LinearLayout>
<View
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@color/DarkGray2"
android:layout_centerInParent="true"/>
RelativeLayout>
public class TestView extends RelativeLayout {
public TestView(Context context) {
this(context,null);
}
public TestView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public TestView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
LinearLayout ll_content = new LinearLayout(context);
ParamUtil.rl_param(ll_content, WhType.match, WhType.match)
.padding(10);
ll_content.setOrientation(LinearLayout.VERTICAL);
this.addView(ll_content);
View center_view = new View(context);
ParamUtil.rl_param(center_view, WhType.dp(20), WhType.dp(20))
.centerInParent();
center_view.setBackgroundColor(getResources().getColor(R.color.DarkGray2));
this.addView(center_view);
ll_content.addView(createLinear(context,"No.1"));
ll_content.addView(createLinear(context,"No.2"));
ll_content.addView(createLinear(context,"No.3"));
}
public LinearLayout createLinear(Context context, String text) {
LinearLayout ll_cell = new LinearLayout(context);
ParamUtil.ll_param(ll_cell, WhType.match, WhType.dp(100))
.margin(10);
TextView textView = new TextView(context);
ParamUtil.ll_param(textView, WhType.wrap, WhType.match)
.marginLeft(10);
textView.setText(text);
ll_cell.addView(textView);
return ll_cell;
}
}
看着是不是也还比较简单,代码量基本上差不太多,核心代码也就30行。
如果父布局是RelativeLayout,子布局就用ParamUtil.rl_param()去设置相关属性。
如果父布局是LinearLayout ,子布局就用ParamUtil.ll_param()去设置相关属性。
match,wrap,dp 直接输入就有提示,使用起来算是很方便了,dsl是没有用过,自己封装的也算是一个简易版的util吧。
enum LayoutType{
linear, relate,frame;
}
public class WhType {
public static final WhType match = new WhType(ViewGroup.LayoutParams.MATCH_PARENT);
public static final WhType wrap = new WhType(ViewGroup.LayoutParams.WRAP_CONTENT);
public static WhType dp(int size) {
return new WhType((int) dp2px(PanamaApplication.getmContext(), size));
}
int size = 0;
public WhType(int size) {
this.size = size;
}
static float dp2px(Context context, float dp) {
final float scale = context.getResources().getDisplayMetrics().density;
return dp * scale + 0.5f;
}
}
public class ParamUtil {
View view;
LayoutType type;
ViewGroup.LayoutParams params;
WhType width;
WhType height;
private float weight;
private int margin;
private int marginLeft;
private int marginRight;
private int marginTop;
private int marginBottom;
private int padding;
private int paddingLeft;
private int paddingRight;
private int paddingTop;
private int paddingBottom;
public static ParamUtil ll_param(View view, WhType width, WhType height) {
return new ParamUtil(LayoutType.linear, view, width, height);
}
public static ParamUtil fl_param(View view, WhType width, WhType height) {
return new ParamUtil(LayoutType.frame, view, width, height);
}
public static ParamUtil rl_param(View view, WhType width, WhType height) {
return new ParamUtil(LayoutType.relate, view, width, height);
}
public ParamUtil(LayoutType type, View view, WhType width, WhType height) {
this.type = type;
this.view = view;
this.width = width;
this.height = height;
switch (type) {
case linear:
params = new LinearLayout.LayoutParams(
width.size,
height.size
);
break;
case relate:
params = new RelativeLayout.LayoutParams(
width.size,
height.size
);
break;
case frame:
params = new FrameLayout.LayoutParams(
width.size,
height.size
);
break;
}
view.setLayoutParams(params);
}
//只有LinearLayout才有
public ParamUtil weight(float weight) {
this.weight = weight;
if (params instanceof LinearLayout.LayoutParams) {
((LinearLayout.LayoutParams) params).weight = weight;
}
return this;
}
//只有RelativeLayout才有
public ParamUtil centerInParent() {
if (params instanceof RelativeLayout.LayoutParams) {
((RelativeLayout.LayoutParams) params).addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
}
return this;
}
private void setPadding(int left, int top, int right, int bottom) {
this.paddingLeft = left;
this.paddingRight = right;
this.paddingTop = top;
this.paddingBottom = bottom;
view.setPadding((int) dp2px(left), (int) dp2px(top), (int) dp2px(right), (int) dp2px(bottom));
}
private void setMargin(int left, int top, int right, int bottom) {
this.marginLeft = left;
this.marginRight = right;
this.marginTop = top;
this.marginBottom = bottom;
if (params instanceof LinearLayout.LayoutParams) {
((LinearLayout.LayoutParams) params)
.setMargins((int) dp2px(left), (int) dp2px(top), (int) dp2px(right), (int) dp2px(bottom));
} else if (params instanceof RelativeLayout.LayoutParams) {
((RelativeLayout.LayoutParams) params)
.setMargins((int) dp2px(left), (int) dp2px(top), (int) dp2px(right), (int) dp2px(bottom));
} else if (params instanceof FrameLayout.LayoutParams) {
((FrameLayout.LayoutParams) params)
.setMargins((int) dp2px(left), (int) dp2px(top), (int) dp2px(right), (int) dp2px(bottom));
}
}
public ParamUtil margin(int margin) {
this.margin = margin;
setMargin(margin, margin, margin, margin);
view.setLayoutParams(params);
return this;
}
public ParamUtil marginLeft(int marginLeft) {
this.marginLeft = marginLeft;
setMargin(marginLeft, marginTop, marginRight, marginBottom);
view.setLayoutParams(params);
return this;
}
public ParamUtil marginRight(int marginRight) {
this.marginRight = marginRight;
setMargin(marginLeft, marginTop, marginRight, marginBottom);
view.setLayoutParams(params);
return this;
}
public ParamUtil marginTop(int marginTop) {
this.marginTop = marginTop;
setMargin(marginLeft, marginTop, marginRight, marginBottom);
view.setLayoutParams(params);
return this;
}
public ParamUtil marginBottom(int marginBottom) {
this.marginBottom = marginBottom;
setMargin(marginLeft, marginTop, marginRight, marginBottom);
view.setLayoutParams(params);
return this;
}
public ParamUtil padding(int padding) {
this.padding = padding;
view.setPadding(padding, padding, padding, padding);
return this;
}
public ParamUtil paddingLeft(int paddingLeft) {
this.paddingLeft = paddingLeft;
view.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
return this;
}
public ParamUtil paddingTop(int paddingTop) {
this.paddingTop = paddingTop;
view.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
return this;
}
public ParamUtil paddingRight(int paddingRight) {
this.paddingRight = paddingRight;
view.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
return this;
}
public ParamUtil paddingBottom(int paddingBottom) {
this.paddingBottom = paddingBottom;
view.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
return this;
}
private float dp2px(float dp) {
final float scale = MyApplication.getmContext().getResources().getDisplayMetrics().density;
return dp * scale + 0.5f;
}
}
以上还只是一个非常基础的封装版本,需要的话,可以自行补充,扩展其实也是很简单的。
希望能给需要的朋友一点提示一点帮助吧。