zoukankan      html  css  js  c++  java
  • 自定义组合控件

    在编写安卓程序的时候,针对同一个布局(xml)反复使用的情况下,为了增加代码的重用性,我们需要做一定的封装,其中就包括两种情况:

     1. 布局内填充:

       继承ViewGroup子类(直接继承ViewGroup需要重写它的onLayout方法),并在构造方法中完成自定义view布局的内填充,这种适合于已有的控件进行组合能得到符合实际开发的目的。如:

    编写自定义组合控件的布局图 

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

    <TextView
    android:id="@+id/tv_first"
    android:layout_width="0dp"
    android:layout_weight="1"
    android:layout_height="wrap_content"
    />


    <CheckBox
    android:id="@+id/checkbox_second"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    />

    </LinearLayout>

    在ViewGroup的继承类中,将布局进行内填充

    package com.example.views.view;

    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.LayoutInflater;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.CheckBox;
    import android.widget.RelativeLayout;
    import android.widget.TextView;

    import com.example.views.R;

    public class CustomView extends RelativeLayout {

    private TextView tv_first;
    private CheckBox cb_second;
    public CustomView(Context context) {
    this(context,null);
    }

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

    public CustomView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    View view = LayoutInflater.from(context).inflate(R.layout.view_custom,this,true);
    tv_first = (TextView) view.findViewById(R.id.tv_first);
    cb_second = (CheckBox) findViewById(R.id.checkbox_second);
    }

    public void setText(String content){
    tv_first.setText(content);
    }

    public boolean isSelected(){
    return cb_second.isChecked();
    }

    public void setSelected(boolean isCheck){
    cb_second.setChecked(isCheck);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
    cb_second.setChecked(!cb_second.isChecked());
    return super.onTouchEvent(event);
    }

    /**
    * 这个方法是ViewGroup子类专有方法,表示是否拦截事件
    * true 表示拦截 也就是说Touch事件不交由viewgroup中的控件处理,保证checkbox的点击事件不会执行
    */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
    return true;
    }
    }

    在activity_main.xml文件中,只需要控件的简单声明:

    <RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <com.example.views.view.CustomView
    android:id="@+id/customView1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true" >
    </com.example.views.view.CustomView>

    </RelativeLayout>

      2. 完全自定义控件: 当原的控件不能满足自身的需要我们就需要自定义控件,然后控件分为两种大的方向,一个是View类型,另一个是ViewGroup类型。如果是View类型的话,就需要重写它的onMeasure(), onDraw(Canvas canvas),甚至需要重写OnTouchEven()来处理特殊的触摸事件,比如说,TextView实现滑动换文字内容,就需要处理Touch事件。 如果是ViewGroup类型的话,就可能需要重现onMeasure() onLayout(),而此时的onDraw方法大多情况下就不需要关心了,一般有里面view自行调用自己的onDraw方法。更值得一提的是,在自定义控件的时候,我们可能需要将控件的属性直接写在activity_main.xml(代替所有的布局文件)文件中,免去用代码在进行控件属性的

    设置,这个时候,自定义属性就派上了用场,如:

     res/values/attrs.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    <declare-styleable name="customview">
    <attr name="backColor" format="reference|color"/>
    <attr name="outColor" format="reference|color"/>
    <attr name="ringWidth" format="reference|dimension"/>
    </declare-styleable>
    </resources>

    View控件代码

    package com.example.customview.view;

    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.util.AttributeSet;
    import android.widget.ImageView;

    import com.example.customview.R;

    public class CustomView extends ImageView {

    private int backColor;
    private int outColor;
    private float ringWidth;

    private int mWidth;

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

    public CustomView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.customview);
    backColor = typedArray.getColor(R.styleable.customview_backColor, Color.RED);
    outColor = typedArray.getColor(R.styleable.customview_outColor,Color.BLUE);
    ringWidth = typedArray.getDimension(R.styleable.customview_ringWidth, 0);
    }

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

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    mWidth = Math.min(MeasureSpec.getSize(widthMeasureSpec),
    MeasureSpec.getSize(heightMeasureSpec));
    setMeasuredDimension(mWidth, mWidth);
    }

    @Override
    protected void onDraw(Canvas canvas) {
    Paint paint = new Paint();
    paint.setColor(outColor);
    canvas.drawCircle(mWidth/2, mWidth/2,mWidth/2, paint);
    paint.setColor(backColor);
    canvas.drawCircle(mWidth/2, mWidth/2,mWidth/2-ringWidth, paint);
    }
    }

    //布局文件:

    <RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res/com.example.customview"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.example.customview.view.CustomView
    android:id="@+id/customView1"
    android:layout_width="60dp"
    android:layout_height="60dp"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    app:backColor="#f00"
    app:outColor="#0f0"
    app:ringWidth="5dp"
    />

    </RelativeLayout>

      

  • 相关阅读:
    Django视图之ORM数据库查询操作API
    Django视图之ORM更改数据库连接——配置MySQL库
    TLPI读书笔记第2章-基本概念2
    TLPI读书笔记第2章-基本概念1
    linux防火墙常用命令
    linux配置yum软件仓库
    linux进程管理
    linux文件权限
    linux用yum安装软件
    linux磁盘划分
  • 原文地址:https://www.cnblogs.com/android-er/p/5277619.html
Copyright © 2011-2022 走看看