自定义编辑控件
最近工作不太忙,对于之前像那种个人中心的编辑页面,以前的做法要么是使用RecyclerView,要么是一行一行的画,这次我突发奇想,想着整个项目里,这种地方还是挺多的,就干脆自定义一个算了,每次一行就是一个这个控件得了
需求
类似以下这种界面,太多了,但总归是首先分为
- 有没有二级页面
- 内容靠左还是靠右
- 内容是用EditText还是TextView
实现
EditLayout
public class EditLayout extends RelativeLayout {
private Context mContext;
private TextView mTvTxtTag;//item的名称
private FrameLayout mFlContent;//显示的内容
private ImageView mIvNext;//下一页图标
private int mTagColor;//tag的颜色
private int mHintColor;//hint值的颜色
private int mContentColor;//内容的颜色
private int mTagSize;//tag的size
private int mContentSize;//内容的size
private boolean mIsHasNextPage;//是否有二级页面
private String mTagTxt;//tag的文字内容
private String mContentTxt;//Content的文字内容
private String mHintTxt;//hint的文字内容
private int mLines;//行数
private int mMaxLines;//最大行数
private TextUtils.TruncateAt mEllipsize;//折叠方式
private static final int ELLIPSIZE_START = 0;
private static final int ELLIPSIZE_MIDDLE = 1;
private static final int ELLIPSIZE_END = 2;
private static final int ELLIPSIZE_MARQUEE = 3;
private static final int DEFAULT_LINE = 1;//默认输入一行
private CONTENT_WIDGET mContentWidget;//内容的控件
private static final int CONTENT_EDIT = 0;
private static final int CONTENT_TEXT = 1;
private int mContentGravity;//内容的填充方式
private static final int CONTENT_GRAVITY_LEFT = -1;
private static final int CONTENT_GRAVITY_CENTER = 0;
private static final int CONTENT_GRAVITY_RIGHT = 1;
private onEditLayoutEventLisenter mLisenter;//监听
private int DEFAULT_TAG_SIZE = 48;//默认字体大小
private int DEFAULT_CONTENT_SIZE = 48;//默认字体大小
private EditText etContent;//输入框控件
private TextView tvContent;//文本控件
private int mInputType;//输入类型
private int mContentMarginLeft;//内容距离左边的距离
private static final int INPUT_TYPE_NUMBER = 0;
private static final int INPUT_TYPE_TEXT = 1;
private static final int INPUT_TYPE_DATE = 2;
private static final int INPUT_TYPE_DATETIME = 3;
private static final int INPUT_TYPE_NUMBERDECIMAL = 4;
private static final int INPUT_TYPE_NUMBERPASSWORD = 5;
private static final int INPUT_TYPE_NUMBERSIGNED = 6;
private static final int INPUT_TYPE_PHONE = 7;
private static final int INPUT_TYPE_TEXTAUTOCOMPLETE = 8;
private static final int INPUT_TYPE_TEXTAUTOCORRECT = 9;
private static final int INPUT_TYPE_TEXTEMAILADDRESS = 10;
private static final int INPUT_TYPE_TEXTFILTER = 11;
private static final int INPUT_TYPE_TEXTPASSWORD = 12;
private static final int INPUT_TYPE_TEXTPERSONNAME = 13;
private static final int INPUT_TYPE_TEXTURI = 14;
private static final int INPUT_TYPE_TEXTVISIBLEPASSWORD = 15;
private final AutoLayoutHelper mHelper = new AutoLayoutHelper(this);
//内容的控件:EditText或者TextView
protected enum CONTENT_WIDGET {
EDITTEXT, TEXTVIEW
}
public EditLayout(Context context) {
this(context, null);
}
public EditLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public EditLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
initAttr(attrs);
initView();
}
public int getContentGravity() {
return mContentGravity;
}
public EditLayout setContentGravity(int contentGravity) {
mContentGravity = contentGravity;
if (etContent != null) {
etContent.setGravity(contentGravity);
}
if (tvContent != null) {
tvContent.setGravity(contentGravity);
}
return this;
}
public CONTENT_WIDGET getContentWidget() {
return mContentWidget;
}
public EditLayout setContentWidget(CONTENT_WIDGET contentWidget) {
mContentWidget = contentWidget;
return this;
}
public EditLayout setContentTxt(String contentTxt) {
mContentTxt = contentTxt;
if (etContent != null) {
etContent.setText(mContentTxt);
}
if (tvContent != null) {
tvContent.setText(mContentTxt);
}
return this;
}
public int getInputType() {
return mInputType;
}
public EditLayout setInputType(int inputType) {
mInputType = inputType;
if (etContent != null) {
etContent.setInputType(inputType);
}
return this;
}
public int getTagColor() {
return mTagColor;
}
public EditLayout setTagColor(int tagColor) {
mTagColor = tagColor;
if (mTvTxtTag != null) {
mTvTxtTag.setTextColor(tagColor);
}
return this;
}
public int getHintColor() {
return mHintColor;
}
public EditLayout setHintColor(int hintColor) {
mHintColor = hintColor;
if (etContent != null) {
etContent.setHintTextColor(hintColor);
}
if (tvContent != null) {
tvContent.setHintTextColor(hintColor);
}
return this;
}
public int getContentColor() {
return mContentColor;
}
public EditLayout setContentColor(int contentColor) {
mContentColor = contentColor;
if (etContent != null) {
etContent.setTextColor(contentColor);
}
if (tvContent != null) {
tvContent.setTextColor(contentColor);
}
return this;
}
public int getTagSize() {
return mTagSize;
}
public EditLayout setTagSize(int tagSize) {
mTagSize = tagSize;
if (mTvTxtTag != null) {
mTvTxtTag.setTextSize(mTagSize);
}
return this;
}
public int getContentSize() {
return mContentSize;
}
public EditLayout setContentSize(int contentSize) {
mContentSize = contentSize;
if (etContent != null) {
etContent.setTextSize(mContentSize);
}
if (tvContent != null) {
tvContent.setTextSize(mContentSize);
}
return this;
}
public boolean isHasNextPage() {
return mIsHasNextPage;
}
public EditLayout setHasNextPage(boolean hasNextPage) {
mIsHasNextPage = hasNextPage;
if (mIsHasNextPage) {
if (mIvNext != null)
mIvNext.setVisibility(VISIBLE);
} else {
if (mIvNext != null)
mIvNext.setVisibility(INVISIBLE);
}
return this;
}
public String getTagTxt() {
return mTagTxt;
}
public EditLayout setTagTxt(String tagTxt) {
mTagTxt = tagTxt;
if (mTvTxtTag != null) {
mTvTxtTag.setText(tagTxt);
}
return this;
}
public String getContentTxt() {
return mContentTxt;
}
public String getHintTxt() {
return mHintTxt;
}
public EditLayout setHintTxt(String hintTxt) {
mHintTxt = hintTxt;
if (etContent != null) {
etContent.setHint(mHintTxt);
}
if (tvContent != null) {
tvContent.setHint(mHintTxt);
}
return this;
}
public int getContentMarginLeft() {
return mContentMarginLeft;
}
public EditLayout setContentMarginLeft(int contentMarginLeft) {
mContentMarginLeft = contentMarginLeft;
if (mFlContent != null) {
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) mFlContent.getLayoutParams();
lp.setMargins(contentMarginLeft, 0, 0, 0);
mFlContent.setLayoutParams(lp);
}
return this;
}
/**
* 初始化属性
*
* @param attrs
*/
private void initAttr(AttributeSet attrs) {
TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.EditLayout);
mTagColor = typedArray.getColor(R.styleable.EditLayout_tag_color, getResources().getColor(R.color.default_black));
mHintColor = typedArray.getColor(R.styleable.EditLayout_hint_color, getResources().getColor(R.color.default_gray_light));
mContentColor = typedArray.getColor(R.styleable.EditLayout_content_color, getResources().getColor(R.color.default_black));
mTagSize = typedArray.getDimensionPixelSize(R.styleable.EditLayout_tag_size, DEFAULT_TAG_SIZE);
mContentSize = typedArray.getDimensionPixelSize(R.styleable.EditLayout_content_size, DEFAULT_CONTENT_SIZE);
mIsHasNextPage = typedArray.getBoolean(R.styleable.EditLayout_has_next_page, false);
mTagTxt = typedArray.getString(R.styleable.EditLayout_tag_txt);
mContentTxt = typedArray.getString(R.styleable.EditLayout_content_txt);
mHintTxt = typedArray.getString(R.styleable.EditLayout_hint_txt);
mLines = typedArray.getInt(R.styleable.EditLayout_lines, DEFAULT_LINE);
mMaxLines = typedArray.getInt(R.styleable.EditLayout_max_line, DEFAULT_LINE);
int ellipsize = typedArray.getInt(R.styleable.EditLayout_ellipsize, ELLIPSIZE_END);
if (ellipsize == ELLIPSIZE_START) {
mEllipsize = TextUtils.TruncateAt.START;
} else if (ellipsize == ELLIPSIZE_MIDDLE) {
mEllipsize = TextUtils.TruncateAt.MIDDLE;
} else if (ellipsize == ELLIPSIZE_END) {
mEllipsize = TextUtils.TruncateAt.END;
} else if (ellipsize == ELLIPSIZE_END) {
mEllipsize = TextUtils.TruncateAt.MARQUEE;
}
int widgetType = typedArray.getInt(R.styleable.EditLayout_content_widget, CONTENT_EDIT);
if (widgetType == CONTENT_EDIT) {
mContentWidget = CONTENT_WIDGET.EDITTEXT;
} else if (widgetType == CONTENT_TEXT) {
mContentWidget = CONTENT_WIDGET.TEXTVIEW;
}
int contentGravity = typedArray.getInt(R.styleable.EditLayout_content_gravity, CONTENT_GRAVITY_LEFT);
if (contentGravity == CONTENT_GRAVITY_LEFT) {
mContentGravity = Gravity.LEFT;
} else if (contentGravity == CONTENT_GRAVITY_CENTER) {
mContentGravity = Gravity.CENTER;
} else if (contentGravity == CONTENT_GRAVITY_RIGHT) {
mContentGravity = Gravity.RIGHT;
}
int inputType = typedArray.getInt(R.styleable.EditLayout_input_type, InputType.TYPE_CLASS_TEXT);
if (inputType == INPUT_TYPE_NUMBER) {//number
mInputType = InputType.TYPE_CLASS_NUMBER;
} else if (inputType == INPUT_TYPE_TEXT) {//text
mInputType = InputType.TYPE_CLASS_TEXT;
} else if (inputType == INPUT_TYPE_DATE) {//date
mInputType = InputType.TYPE_DATETIME_VARIATION_DATE;
} else if (inputType == INPUT_TYPE_DATETIME) {//datetime
mInputType = InputType.TYPE_CLASS_DATETIME;
} else if (inputType == INPUT_TYPE_NUMBERDECIMAL) {//numberDecimal
mInputType = InputType.TYPE_NUMBER_FLAG_DECIMAL;
} else if (inputType == INPUT_TYPE_NUMBERPASSWORD) {//numberPassword
mInputType = InputType.TYPE_NUMBER_VARIATION_PASSWORD;
} else if (inputType == INPUT_TYPE_NUMBERSIGNED) {//numberSigned
mInputType = InputType.TYPE_NUMBER_FLAG_SIGNED;
} else if (inputType == INPUT_TYPE_PHONE) {//phone
mInputType = InputType.TYPE_CLASS_PHONE;
} else if (inputType == INPUT_TYPE_TEXTAUTOCOMPLETE) {//textAutoComplete
mInputType = InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE;
} else if (inputType == INPUT_TYPE_TEXTAUTOCORRECT) {//textAutoCorrect
mInputType = InputType.TYPE_TEXT_FLAG_AUTO_CORRECT;
} else if (inputType == INPUT_TYPE_TEXTEMAILADDRESS) {//textEmailAddress
mInputType = InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
} else if (inputType == INPUT_TYPE_TEXTFILTER) {//textFilter
mInputType = InputType.TYPE_TEXT_VARIATION_FILTER;
} else if (inputType == INPUT_TYPE_TEXTPASSWORD) {//textPassword
mInputType = InputType.TYPE_TEXT_VARIATION_PASSWORD;
} else if (inputType == INPUT_TYPE_TEXTPERSONNAME) {//textPersonName
mInputType = InputType.TYPE_TEXT_VARIATION_PERSON_NAME;
} else if (inputType == INPUT_TYPE_TEXTURI) {//textUri
mInputType = InputType.TYPE_TEXT_VARIATION_URI;
} else if (inputType == INPUT_TYPE_TEXTVISIBLEPASSWORD) {//textVisiblePassword
mInputType = InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD;
}
typedArray.recycle();
}
/**
* 初始化布局
*/
private void initView() {
View view = View.inflate(getContext(), R.layout.lay_edit_layout, this);
mTvTxtTag = view.findViewById(R.id.tv_txt_tag);
mFlContent = view.findViewById(R.id.fl_content);
mIvNext = view.findViewById(R.id.iv_next);
//tag的初始化
mTvTxtTag.setText(mTagTxt);
mTvTxtTag.setTextColor(mTagColor);
mTvTxtTag.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTagSize);
AutoUtils.autoTextSize(mTvTxtTag);
//内容的组件的初始化
if (mContentWidget == CONTENT_WIDGET.EDITTEXT) {
etContent = new EditText(mContext);
etContent.setInputType(mInputType);
etContent.setLines(mLines);
etContent.setMaxLines(mMaxLines);
etContent.setEllipsize(mEllipsize);
etContent.setText(mContentTxt);
etContent.setTextColor(mContentColor);
etContent.setTextSize(TypedValue.COMPLEX_UNIT_PX, mContentSize);
etContent.setBackgroundDrawable(null);
etContent.setPadding(0, 0, 0, 0);
etContent.setHint(mHintTxt);
etContent.setHintTextColor(mHintColor);
etContent.setGravity(mContentGravity | Gravity.CENTER_VERTICAL);
mFlContent.removeAllViews();
mFlContent.addView(etContent);
AutoUtils.autoTextSize(etContent);
} else if (mContentWidget == CONTENT_WIDGET.TEXTVIEW) {
tvContent = new TextView(mContext);
tvContent.setInputType(mInputType);
tvContent.setLines(mLines);
tvContent.setMaxLines(mMaxLines);
tvContent.setEllipsize(mEllipsize);
tvContent.setText(mContentTxt);
tvContent.setTextColor(mContentColor);
tvContent.setTextSize(TypedValue.COMPLEX_UNIT_PX, mContentSize);
tvContent.setHint(mHintTxt);
tvContent.setHintTextColor(mHintColor);
tvContent.setGravity(mContentGravity | Gravity.CENTER_VERTICAL);
mFlContent.removeAllViews();
mFlContent.addView(tvContent);
AutoUtils.autoTextSize(tvContent);
}
//是否有二级页面
if (mIsHasNextPage) {
mIvNext.setVisibility(VISIBLE);
this.setOnClickListener(v -> {
mLisenter.onClickItem(mContentTxt);
});
} else {
mIvNext.setVisibility(INVISIBLE);
}
AutoUtils.autoSize(this);
}
@Override
public EditLayout.LayoutParams generateLayoutParams(AttributeSet attrs) {
return new EditLayout.LayoutParams(getContext(), attrs);
}
public static class LayoutParams extends RelativeLayout.LayoutParams implements AutoLayoutHelper.AutoLayoutParams {
private AutoLayoutInfo mAutoLayoutInfo;
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
mAutoLayoutInfo = AutoLayoutHelper.getAutoLayoutInfo(c, attrs);
}
@Override
public AutoLayoutInfo getAutoLayoutInfo() {
return mAutoLayoutInfo;
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (!isInEditMode()) {
mHelper.adjustChildren();
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
//整个Item的点击事件
public interface onEditLayoutEventLisenter {
void onClickItem(String content);
}
public void setOnEditLayoutEventLisenter(onEditLayoutEventLisenter onClickItemLisenter) {
mLisenter = onClickItemLisenter;
}
}
lay_edit_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="@color/white"
android:layout_height="150px"
android:paddingLeft="36px"
android:paddingRight="36px">
<TextView
android:id="@+id/tv_txt_tag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:ems="4"
android:textColor="#333333"
android:textSize="48px"/>
<FrameLayout
android:id="@+id/fl_content"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:layout_marginRight="36px"
android:layout_toLeftOf="@+id/iv_next"
android:layout_toRightOf="@+id/tv_txt_tag"
android:background="@color/white"/>
<ImageView
android:id="@+id/iv_next"
android:layout_width="26px"
android:layout_height="47px"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@drawable/ic_arrow"/>
</RelativeLayout>
test_editlayout.xml
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/default_bg"
android:orientation="vertical">
<com.example.myapplication2.EditLayout
android:id="@+id/et_layout1"
android:layout_width="match_parent"
android:layout_height="@dimen/px150"
app:content_txt="我是标题"
app:content_widget="textview"
app:has_next_page="true"
app:hint_txt="请填写标题"
app:tag_txt="标题"/>
<View style="@style/view_title"/>
<com.example.myapplication2.EditLayout
android:id="@+id/et_layout2"
android:layout_width="match_parent"
android:layout_height="@dimen/px150"
app:content_txt="我是内容"
app:content_widget="edittext"
app:hint_txt="请填写内容"
app:tag_txt="内容"/>
<View style="@style/view_title"/>
<com.example.myapplication2.EditLayout
android:id="@+id/et_layout3"
android:layout_width="800px"
android:layout_height="@dimen/px150"
app:content_widget="textview"
app:hint_txt="请填写公司地址"
app:tag_txt="公司地址"/>
<Button
android:id="@+id/btn_click"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="设置我啊"/>
</LinearLayout>
attrs.xml
<!--EditLayout-->
<declare-styleable name="EditLayout">
<attr name="tag_color" format="color|reference"/>
<attr name="hint_color" format="color|reference"/>
<attr name="content_color" format="color|reference"/>
<attr name="tag_size" format="dimension"/>
<attr name="content_size" format="dimension"/>
<attr name="has_next_page" format="boolean"/>
<attr name="tag_txt" format="string|reference"/>
<attr name="hint_txt" format="string|reference"/>
<attr name="content_txt" format="string|reference"/>
<attr name="lines" format="integer"/>
<attr name="max_line" format="integer"/>
<attr name="ellipsize">
<enum name="start" value="0"/>
<enum name="middle" value="1"/>
<enum name="end" value="2"/>
<enum name="marquee" value="3"/>
</attr>
<attr name="content_widget">
<enum name="edittext" value="0"/>
<enum name="textview" value="1"/>
</attr>
<attr name="content_gravity">
<enum name="left" value="-1"/>
<enum name="center" value="0"/>
<enum name="right" value="1"/>
</attr>
<attr name="input_type">
<enum name="number" value="0"/>
<enum name="text" value="1"/>
<enum name="date" value="2"/>
<enum name="datetime" value="3"/>
<enum name="numberDecimal" value="4"/>
<enum name="numberPassword" value="5"/>
<enum name="numberSigned" value="6"/>
<enum name="phone" value="7"/>
<enum name="textAutoComplete" value="8"/>
<enum name="textAutoCorrect" value="9"/>
<enum name="textEmailAddress" value="10"/>
<enum name="textFilter" value="11"/>
<enum name="textPassword" value="12"/>
<enum name="textPersonName" value="13"/>
<enum name="textUri" value="14"/>
<enum name="textVisiblePassword" value="15"/>
</attr>
</declare-styleable>
colors.xml
<color name="default_gray_light">#999999</color>
<color name="default_black">#333333</color>
<color name="white">#ffffff</color>
<color name="default_bg">#f2f2f2</color>
<color name="default_line">#dddddd</color>
styles.xml
<!-- 分割线 -->
<style name="view_title">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">1px</item>
<item name="android:background">@color/default_line
</item>
</style>
另外我在app的build.gradle里引入了
java8
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
和张鸿洋的AutoLayout
https://github.com/hongyangAndroid/AndroidAutoLayout
compile 'com.zhy:autolayout:1.4.5'