Android自定义控件之标题控件

在Android项目中我们经常会遇到如下的UI展示需求
demo下载

这里写图片描述

就是模块标题的显示,通常后面内容是动态的,还有诸如有无向右箭头,上下是否显示线条等不同需求.之前项目中的做法是用一个include标签将次布局引入,这必然导致布局文件不易读,而且引入太多include标签页会影响界面的渲染速度,所以改为组合控件形式的自定义控件来改造,支持xml属性定义并且对外暴露相关方法.

1.首先还是自定义我们需要的一些属性,在values文件夹下边新建attrs.xml文件<!--自定义表单-->
<declare-styleable name="CommonFormLayout">
<attr name="leftImage" format="reference" />
<attr name="hasRightArrow" format="boolean" />
<attr name="titleText" format="string|reference" />
<attr name="contentText" format="string|reference" />
<attr name="titleTextColor" format="color" />
<attr name="contentTextColor" format="color|reference" />
<attr name="contentTextHintColor" format="color|reference" />
<attr name="contextTextHint" format="string|reference" />
<attr name="titleTextSize" format="integer|reference" />
<attr name="contentTextSize" format="integer|reference" />
<!--有顶部线时设置为true-->
<attr name="hasTopLine" format="boolean" />
<!--短底部线时设置为true-->
<attr name="isShotBottomLine" format="boolean" />
</declare-styleable>

2.自定义类继承自RelativeLayout,这里将控件载入,并且在构造方法中进行属性解析,并且对外提供必要的set(),get()方法,以便在Java代码中控制属性.

package shidong.com.commonformlayout;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.text.TextPaint;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;

/**
 * <declare-styleable name="CommonFormLayout">
 * <attr name="leftImage" format="reference" />
 * <attr name="hasRightArrow" format="boolean" />
 * <attr name="titleText" format="string|reference" />
 * <attr name="contentText" format="string|reference" />
 * <attr name="titleTextColor" format="color|reference" />
 * <attr name="contentTextColor" format="color|reference" />
 * <attr name="contentTextHintColor" format="color|reference" />
 * <attr name="contextTextHint" format="string|reference" />
 * <attr name="titleTextSize" format="integer|reference"/>
 * <attr name="contentTextSize" format="integer|reference"/>
 * <!--有顶部线时设置为true-->
 * <attr name="hasTopLine" format="boolean" />
 * <!--短底部线时设置为true-->
 * <attr name="isShotBottomLine" format="boolean" />
 * </declare-styleable>
 * Created by shidong on 16/7/30.
 */
public class CommonFormLayout extends RelativeLayout {

    private final TextView tv_common_title;
    private final TextView tv_common_content;
    private final View view_top_line;
    private final View view_bottom_long;
    private final View view_bottom_short;

    public CommonFormLayout(Context context) {
        this(context, null);
    }

    public CommonFormLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CommonFormLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        LayoutInflater.from(context).inflate(R.layout.layout_common_form, this, true);
        tv_common_title = (TextView) findViewById(R.id.tv_common_title);
        tv_common_content = (TextView) findViewById(R.id.tv_common_content);
        view_top_line = findViewById(R.id.view_top_line);
        view_bottom_long = findViewById(R.id.view_bottom_long);
        view_bottom_short = findViewById(R.id.view_bottom_short);

        //获取属性并解析
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CommonFormLayout);
        int count = typedArray.getIndexCount();
        for (int i = 0; i < count; i++) {
            int itemId = typedArray.getIndex(i);
            if (itemId == R.styleable.CommonFormLayout_titleText) {
                tv_common_title.setText(typedArray.getText(itemId));
            } else if (itemId == R.styleable.CommonFormLayout_contentText) {
                tv_common_content.setText(typedArray.getText(itemId));
            } else if (itemId == R.styleable.CommonFormLayout_hasRightArrow) {
                if (typedArray.getBoolean(itemId, false)) {
                    tv_common_content.setCompoundDrawablesWithIntrinsicBounds(null, null, getResources().getDrawable(R.mipmap.icon_right_arrow), null);
                }
            } else if (itemId == R.styleable.CommonFormLayout_leftImage) {
                tv_common_title.setCompoundDrawablesWithIntrinsicBounds(typedArray.getDrawable(itemId), null, null, null);
            } else if (itemId == R.styleable.CommonFormLayout_titleTextColor) {
                tv_common_title.setTextColor(typedArray.getColor(itemId, getResources().getColor(R.color.grey_333333)));
            } else if (itemId == R.styleable.CommonFormLayout_contentTextColor) {
                tv_common_content.setTextColor(typedArray.getColor(itemId, getResources().getColor(R.color.grey_888888)));
            } else if (itemId == R.styleable.CommonFormLayout_hasTopLine) {
                if (typedArray.getBoolean(itemId, false)) {
                    view_top_line.setVisibility(VISIBLE);
                }
            } else if (itemId == R.styleable.CommonFormLayout_isShotBottomLine) {
                if (typedArray.getBoolean(itemId, false)) {
                    view_bottom_short.setVisibility(VISIBLE);
                    view_bottom_long.setVisibility(GONE);
                }
            } else if (itemId == R.styleable.CommonFormLayout_contentTextHintColor) {
                tv_common_content.setHintTextColor(typedArray.getColor(itemId, getResources().getColor(R.color.grey_d3d3d3)));
            } else if (itemId == R.styleable.CommonFormLayout_contextTextHint) {
                tv_common_content.setHint(typedArray.getText(itemId));
            } else if (itemId == R.styleable.CommonFormLayout_titleTextSize) {
                tv_common_title.setTextSize(TypedValue.COMPLEX_UNIT_SP, typedArray.getInt(itemId, 0));
            } else if (itemId == R.styleable.CommonFormLayout_contentTextSize) {
                tv_common_content.setTextSize(TypedValue.COMPLEX_UNIT_SP, typedArray.getInt(itemId, 0));
            }
        }
    }


    /**
     * 设置左侧标题图标
     *
     * @param resId
     */
    public void setLeftImage(int resId) {
        setLeftImage(getResources().getDrawable(resId));
    }

    /**
     * 设置左侧标题图标
     *
     * @param drawable
     */
    public void setLeftImage(Drawable drawable) {
        tv_common_title.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
    }

    /**
     * 设置是否有向右箭头
     *
     * @param hasRightArrow
     */
    public void setHasRightArrow(boolean hasRightArrow) {
        if (hasRightArrow) {
            tv_common_content.setCompoundDrawablesWithIntrinsicBounds(null, null, getResources().getDrawable(R.mipmap.icon_right_arrow), null);
        } else {
            tv_common_content.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
        }
    }

    /**
     * 设置标题文本
     *
     * @param resID
     */
    public void setTitleText(int resID) {
        setTitleText(getResources().getString(resID));
    }

    /**
     * 设置标题文本
     *
     * @param text
     */
    public void setTitleText(String text) {
        tv_common_title.setText(text);
    }

    /**
     * 返回标题文本
     */
    public CharSequence getTitleText() {
        return tv_common_title.getText();
    }

    /**
     * 设置内容文本
     *
     * @param resId
     */
    public void setContentText(int resId) {
        setContentText(getResources().getString(resId));
    }

    /**
     * 设置内容文本
     *
     * @param text
     */
    public void setContentText(String text) {
        tv_common_content.setText(text);
    }

    /**
     * 返回内容文本
     */
    public CharSequence getContentText() {
        return tv_common_content.getText();
    }

    /**
     * 设置标题文本颜色
     *
     * @param resId
     */
    public void setTitleTextColor(int resId) {
        tv_common_title.setTextColor(resId);
    }

    /**
     * 设置内容文本颜色
     *
     * @param resId
     */
    public void setContentTextColor(int resId) {
        tv_common_content.setTextColor(resId);
    }


    public void addTextChangedListener(TextWatcher watcher) {
        tv_common_content.addTextChangedListener(watcher);
    }

    public void setContentTextHintColor(int resId) {
        tv_common_content.setHintTextColor(resId);
    }

    public void setHintText(int resId) {
        setHintText(getResources().getString(resId));
    }

    public void setHintText(String text) {
        tv_common_content.setHint(text);
    }

    public void setTitleTextStyleBold() {
        TextPaint paint = tv_common_title.getPaint();
        paint.setFakeBoldText(true);
    }

    public void setContentTextStyleBold() {
        TextPaint paint = tv_common_content.getPaint();
        paint.setFakeBoldText(true);
    }

    /**
     * 内容文本点击监听
     *
     * @param onClickListener
     */
    public void setContentTextClickListener(OnClickListener onClickListener) {
        tv_common_content.setOnClickListener(onClickListener);
    }

    /**
     * 设置标题字体大小
     *
     * @param size 文字大小,单位是sp
     */
    public void setTitleTextSize(int size) {
        tv_common_title.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
    }

    /**
     * 设置内容字体大小
     *
     * @param size 文字大小,单位是sp
     */
    public void setContentTextSize(int size) {
        tv_common_content.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
    }

    /**
     * 设置根view的背景
     *
     * @param background
     */
    public void setRootViewBackgroundDrawable11(Drawable background) {
        View view = findViewById(R.id.root_commom_formlayout);
        view.setBackgroundDrawable(null);
    }

}

3.然后在界面中就能很轻松地控制这个控件了

package shidong.com.commonformlayout;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        CommonFormLayout commonFormLayout = (CommonFormLayout) findViewById(R.id.common_layout);
        commonFormLayout.setTitleTextColor(getResources().getColor(R.color.grey_333333));
        commonFormLayout.setContentTextClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(getBaseContext(), "点击内容", Toast.LENGTH_SHORT).show();
            }
        });
    }

}

项目中的一个小功能而已.其实想说的是我们在完成一个功能或者模块之前,一定要先统筹全局想一想,是否可以封装公用的代码;并且自己封装的空间和自定义的属性,方法等一定要命名规范,并且添加简洁明了的注释代码,不要给后人留坑啊,亲身被坑所以深有感触…

demo下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值