Andriod自定义组件

来源:互联网 发布:mac下载器 编辑:程序博客网 时间:2024/06/06 10:06

    在最近几天,经常被他人问道Android自定义组件的知识,心里有个大概的框架,但有时有语言描述时,感觉却无从开口。查询资料时感觉有点杂乱,所以今天把自定义组件的资料整理一下。

     自定义组件是在Android开发经常用到,当系统预定义的组件无法满足开发的需求时,或者开发过程中存在类似组件复用时,就可以将其复用的组件自定义成为模板,减少代码的冗余,提高代码的复用。

    自定义组件可以分为两种:一种是自定义View,另一种则就是自定义ViewGroup.。

    这两种自定义组件的流程大指差不多,但其细节却存在很大的异同。下面我简单的书写一下自定义组件的流程

      (1)根据需求确定自定义组件的类型

      (2)根据所需的自定义组件的类型及其开发的需求确定自定义属性

      (3)根据需求重新 onMeasure,onLayout,onDraw方法。注意:防止wrap_content和padding失效

      (4)如果是自定义ViewGroup,则需要防止滑动冲突。


 上述仅是提供自定义组件的开发过程的参考,其中防止wrap_content和padding失效涉及到View的工作流程,防止滑动冲突涉及到时间分发机制。我将在后续详细讲解其知识。下面我将通过一种小demo来总结一下上述的知识。

    此demo为自定义ViewGroup,也成为自定义的组合模式:

    其最终的效果如下:


其实现步骤如下

    1、在res目录下的values目录创建自定义属性文件attrs

   2、实现自定义属性,其中自定义的属性为左边Button的背景,字体颜色,字体大小;右边Button的背景,字体颜色,字体大小,中

间title的背景,字体颜色,字体大小:源码如下:

<?xml version="1.0" encoding="utf-8"?><!--设置自定义组件的属性--><resources>    <declare-styleable name="topBar">        <attr name="titleText" format="string"></attr>        <attr name="titleTextSize" format="dimension"></attr>        <attr name="titleColor" format="color"></attr>        <attr name="titleBackground" format="color|reference"></attr>        <attr name="leftText" format="string"></attr>        <attr name="leftTextColor" format="color"></attr>        <attr name="leftTextSize" format="dimension"></attr>        <attr name="leftBackground" format="color|reference"></attr>        <attr name="rightText" format="string"></attr>        <attr name="rightTextSize" format="dimension"></attr>        <attr name="rightTextColor" format="color"></attr>        <attr name="rightBackground" format="color|dimension"></attr>    </declare-styleable></resources>

3、自定义ViewGroup,实现其构造函数,关联自定义属性,源码如下:

  1)自定义组件的类名     

 public class TopBar extends RelativeLayout 

   2)自定义组件的所关联属性的成员变量

private String titleText;private int titleTextSize;private int titleColor;private Drawable titleBackground;private String leftText;private int leftTextColor;private int leftTextSize;private Drawable leftBackground;private String rightText;private int rightTextColor;private int rightTextSize;private Drawable rightBackground;
private Button leftButton;private Button rightButton;private TextView titleTextView;private LayoutParams leftLayoutParams;private LayoutParams rightLayoutParams;private LayoutParams titleLayoutParams;private TopBarClickListener listener;

3)重写自定义组件的构造函数,关联自定义属性


/** * 实现TopbBar的构造函数用于关联自定义属性 */public TopBar(Context context, AttributeSet attrs) {    super(context, attrs);    relevanceAttr(context, attrs);    relevanceView(context, attrs);    topBarClickListener();}

/** * @param context * @param attrs * @return void * 关联自定义属性 */private void relevanceAttr(Context context, AttributeSet attrs) {    /**     * attrs 自定义的资源文件     *     *     * R.styleable.topBar 自定义的属性资源名     *     *     * 关联自定义属性文件,将自定义属性保存在该集合里面     * */    TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.topBar);    titleText = ta.getString(R.styleable.topBar_titleText);    titleTextSize = (int) ta.getDimension(R.styleable.topBar_titleTextSize, 0);    titleColor = ta.getColor(R.styleable.topBar_titleColor, 0);    titleBackground = ta.getDrawable(R.styleable.topBar_titleBackground);    leftText = ta.getString(R.styleable.topBar_leftText);    leftTextColor = ta.getColor(R.styleable.topBar_leftTextColor, 0);    leftTextSize = (int) ta.getDimension(R.styleable.topBar_leftTextSize, 0);    leftBackground = ta.getDrawable(R.styleable.topBar_leftBackground);    rightText = ta.getString(R.styleable.topBar_rightText);    rightTextColor = ta.getColor(R.styleable.topBar_rightTextColor, 0);    rightTextSize = (int) ta.getDimension(R.styleable.topBar_rightTextSize, 0);    rightBackground = ta.getDrawable(R.styleable.topBar_rightBackground);    ta.recycle();//手动回收ta}/** * @param context * @param attrs * @return void * <p/> * 将自定义的属性与组件关联 */private void relevanceView(Context context, AttributeSet attrs) {    leftButton = new Button(context);    rightButton = new Button(context);    titleTextView = new TextView(context);    titleTextView.setText(titleText);    titleTextView.setTextSize(titleTextSize);    titleTextView.setTextColor(titleColor);    titleTextView.setBackground(titleBackground);    titleTextView.setGravity(Gravity.CENTER);    leftButton.setText(leftText);    leftButton.setTextColor(leftTextColor);    leftButton.setTextSize(leftTextSize);    leftButton.setBackground(leftBackground);    rightButton.setText(rightText);    rightButton.setTextColor(rightTextColor);    rightButton.setTextSize(rightTextSize);    rightButton.setBackground(rightBackground);    setBackgroundColor(0x59563);    //设置leftButtonwidthheight    leftLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,            ViewGroup.LayoutParams.WRAP_CONTENT);    //leftButton居左对齐    leftLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE);    this.addView(leftButton, leftLayoutParams);    //设置rightButtonwidthheight    rightLayoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,            ViewGroup.LayoutParams.WRAP_CONTENT);    //使rightButton居右对齐    rightLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, TRUE);    this.addView(rightButton, rightLayoutParams);    //设置titlewidthheight    titleLayoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,            ViewGroup.LayoutParams.MATCH_PARENT);    //使titleTextView居中对齐    titleLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, TRUE);    this.addView(titleTextView, titleLayoutParams);}

   4)运用接口回调机制,提供事件监听  

/** * 该接口用于外部点击事件 */public interface TopBarClickListener {    public void setLeftOnClickListener();    public void setRightOnClickListener();}
/** * @param listener * @return void * 将接口暴露给外部,提供外部访问 */public void setOnClickListener(TopBarClickListener listener) {    this.listener = listener;}
/** * @param * @return void * <p/> * 设置接口回调 */private void topBarClickListener() {    leftButton.setOnClickListener(new OnClickListener() {        @Override        public void onClick(View v) {            listener.setLeftOnClickListener();        }    });    rightButton.setOnClickListener(new OnClickListener() {        @Override        public void onClick(View v) {            listener.setRightOnClickListener();        }    });}


5)设置左右Button是否显示

/** * @param leftVisibility * @param rightVisibility * @return void * 设置左右Button是否显示 */public void setVisibility(boolean leftVisibility, boolean rightVisibility) {    if (!leftVisibility && !rightVisibility) {        leftButton.setVisibility(GONE);        rightButton.setVisibility(GONE);    } else if (leftVisibility && !rightVisibility) {        leftButton.setVisibility(VISIBLE);        rightButton.setVisibility(GONE);    } else if (!leftVisibility && rightVisibility) {        leftButton.setVisibility(GONE);        rightButton.setVisibility(VISIBLE);    } else {        leftButton.setVisibility(VISIBLE);        rightButton.setVisibility(VISIBLE);    }}

6)在activity_content的xml文布局该自定义的组件


<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:custom="http://schemas.android.com/apk/res-auto" //关联自定义的属性    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    app:layout_behavior="@string/appbar_scrolling_view_behavior"    tools:context=".MainActivity"    tools:showIn="@layout/activity_main">    <com.yongxiang.sm.customview.TopBar        android:id="@+id/top"        android:layout_width="match_parent"        android:layout_height="50dp"        custom:leftBackground="#e78df2"        custom:leftText="back"        custom:leftTextColor="#FFFFFF"        custom:leftTextSize="12sp"        custom:rightBackground="#e78df2"        custom:rightText="more"        custom:rightTextColor="#FFFFFF"        custom:rightTextSize="12sp"        custom:titleBackground="#64f2a0"        custom:titleColor="#456321"        custom:titleText="title"        custom:titleTextSize="16sp"        ></com.yongxiang.sm.customview.TopBar></RelativeLayout>


7)在Activity中运用

public class MainActivity extends AppCompatActivity {    private TopBar topBar;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();        initEvent();        initVisiblity();    }    /**     * @param     * @return void     * 初始化组件     */    private void initView() {        this.topBar = (TopBar) findViewById(R.id.top);    }    /**     * @param     * @return void     * <p/>     * 初始化事件监听     */    private void initEvent() {        this.topBar.setOnClickListener(new TopBar.TopBarClickListener() {            @Override            public void setLeftOnClickListener() {                Toast.makeText(MainActivity.this, "left Button OnClick!", Toast.LENGTH_SHORT).show();            }            @Override            public void setRightOnClickListener() {                Toast.makeText(MainActivity.this, "right Button OnClick!", Toast.LENGTH_SHORT).show();            }        });    }    /**     * @param     * @return void     * <p/>     * 设置左右Button是否显示     */    private void initVisiblity() {        topBar.setVisibility(true, true);    }}



ps:以上源代码可以粘贴到module运行看其效果




    

    

        

0 0
原创粉丝点击