Android 组合控件

自定义view分为三种:
1、直接继承View
2、继承现有控件
3、组合现有控件,组成新的控件。
组合控件就属于第三种,算是最简单的一种了吧
虽然知道简单,但是还是决定写一篇博客,熟悉一下流程,温故而知新吧

一、定义需要组合控件的视图,当然也可以在代码中定义
例如:定义一个button
Button button=new Button();
简单的还好,但是如果是复杂的布局就需要写大量的代码,得不偿失,还是写到布局文件里面比较好,这里我们定义一个比较常用的页面的标题栏布局。

title_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:paddingLeft="20dp" android:paddingRight="20dp" android:layout_width="match_parent" android:layout_height="47dp">

    <ImageView  android:clickable="true" android:layout_centerVertical="true" android:src="@android:drawable/btn_star" android:layout_alignParentLeft="true" android:id="@+id/leftImage" android:scaleType="fitXY" android:layout_width="30dp" android:layout_height="30dp" />


    <TextView  android:gravity="center" android:layout_toLeftOf="@+id/rightFrame" android:ellipsize="end" android:singleLine="true" android:id="@+id/title" android:layout_toRightOf="@+id/leftImage" android:layout_centerInParent="true" android:textColor="@android:color/white" android:textSize="17sp" android:text="标题" android:layout_width="wrap_content" android:layout_height="wrap_content" />

    <FrameLayout  android:layout_centerVertical="true" android:layout_alignParentRight="true" android:id="@+id/rightFrame" android:layout_width="wrap_content" android:layout_height="wrap_content">
    <ImageView  android:clickable="true" android:visibility="gone" android:src="@android:drawable/btn_star" android:id="@+id/rightImage" android:scaleType="fitXY" android:layout_width="30dp" android:layout_height="30dp" />

    <TextView  android:clickable="true" android:text="完成" android:textSize="15sp" android:textColor="@android:color/white" android:id="@+id/rightText" android:layout_width="wrap_content" android:layout_height="wrap_content" />
    </FrameLayout>

</RelativeLayout>

大概就是这个样子:

这里写图片描述

左边是一张图片,中间是标题名称,右边有可能是图片也有可能是文字。

下面我们把这个加入到我们的自定义控件中去,自定义控件也是自定义View啊,首先还是写属性吧

 <!--自定义组合控件属性-->
    <declare-styleable name="CustomCombinationWiget">
        <attr name="leftImage" format="reference"></attr>
        <attr name="leftImage_width" format="dimension"></attr>
        <attr name="leftImage_height" format="dimension"></attr>
        <attr name="leftImageVisible">
            <enum name="visible" value="1"></enum>
            <enum name="gone" value="0"></enum>
        </attr>
        <attr name="title" format="string"></attr>
        <attr name="titleSize" format="dimension"></attr>
        <attr name="titleColor" format="color"></attr>
        <attr name="titleVisible">
            <enum name="visible" value="1"></enum>
            <enum name="gone" value="0"></enum>
        </attr>
        <attr name="rightImage" format="reference"></attr>
        <attr name="rightImage_height" format="dimension"></attr>
        <attr name="rightImage_width" format="dimension"></attr>
        <attr name="rightImageVisible">
            <enum name="visible" value="1"></enum>
            <enum name="gone" value="0"></enum>
        </attr>
        <attr name="rightText" format="string"></attr>
        <attr name="rightTextSize" format="dimension"></attr>
        <attr name="rightTextColor" format="color"></attr>
        <attr name="rightTextVisible">
            <enum name="visible" value="1"></enum>
            <enum name="gone" value="0"></enum>
        </attr>

    </declare-styleable>

这里面我写的属性比较多,写的都是可能遇到的,当然你可以根据自己的项目需求适量的删减,一般不需要这么多的。

下面看我们的最重要的代码:

//由于我们需要把我们的布局放到一个容器里面,这里就使用最简单的布局容器FramLayout
public class CustomCombinationWiget extends FrameLayout {


    private int  lImage,rImage;//左右imageView


    private  int lheight,lwidth,lVisible,rheight,rwidth,rTextVisible,rImageVisible,cVisible,rTextSize,cTextSize;

    private String cText,rText;//textview的文字

    private int cColor,rColor;

    private TextView mtitle,mrightText;

    private ImageView mlImage,mrImage;



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

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

    public CustomCombinationWiget(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);


        TypedArray typedArray=context.obtainStyledAttributes(attrs, R.styleable.CustomCombinationWiget,defStyleAttr,0);


        lImage= typedArray.getResourceId(R.styleable.CustomCombinationWiget_leftImage,0);

        rImage=typedArray.getResourceId(R.styleable.CustomCombinationWiget_rightImage, 0);

        lheight=typedArray.getDimensionPixelSize(R.styleable.CustomCombinationWiget_leftImage_height,
                (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, getResources().getDisplayMetrics()));

        lwidth=typedArray.getDimensionPixelSize(R.styleable.CustomCombinationWiget_leftImage_width,
                (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, getResources().getDisplayMetrics()));


        lVisible=typedArray.getInt(R.styleable.CustomCombinationWiget_leftImageVisible, 1);
        rImageVisible=typedArray.getInt(R.styleable.CustomCombinationWiget_rightImageVisible, 1);
        rTextVisible=typedArray.getInt(R.styleable.CustomCombinationWiget_rightTextVisible, 0);
        cVisible=typedArray.getInt(R.styleable.CustomCombinationWiget_titleVisible, 1);

        rheight=typedArray.getDimensionPixelSize(R.styleable.CustomCombinationWiget_rightImage_height,
                (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, getResources().getDisplayMetrics()));

        rwidth=typedArray.getDimensionPixelSize(R.styleable.CustomCombinationWiget_rightImage_width,
                (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, getResources().getDisplayMetrics()));

        rTextSize=typedArray.getDimensionPixelSize(R.styleable.CustomCombinationWiget_rightTextSize,
                (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 17, getResources().getDisplayMetrics()));
        cTextSize=typedArray.getDimensionPixelSize(R.styleable.CustomCombinationWiget_titleSize,
                (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 19, getResources().getDisplayMetrics()));


        cColor=typedArray.getColor(R.styleable.CustomCombinationWiget_titleColor, getResources().getColor(android.R.color.white));

        rColor=typedArray.getColor(R.styleable.CustomCombinationWiget_rightTextColor, getResources().getColor(android.R.color.white));


        cText=typedArray.getString(R.styleable.CustomCombinationWiget_title);

        rText=typedArray.getString(R.styleable.CustomCombinationWiget_rightText);

        typedArray.recycle();

        initvView(context);


    }

    private void initvView(Context context) {

        LayoutInflater.from(context).inflate(R.layout.title_layout, this, true);

        mtitle=(TextView)findViewById(R.id.title);
        mrightText=(TextView)findViewById(R.id.rightText);

        mlImage=(ImageView)findViewById(R.id.leftImage);
        mrImage=(ImageView)findViewById(R.id.rightImage);


        //初始化标题的属性
        if(!TextUtils.isEmpty(cText)){


            mtitle.setText(cText);

        }

        mtitle.setTextColor(cColor);

        mtitle.setTextSize(cTextSize);

        //初始化左控件
        mlImage.setImageResource(lImage);

        mlImage.getLayoutParams().height=lheight;
        mlImage.getLayoutParams().width=lwidth;
        mlImage.setLayoutParams(mlImage.getLayoutParams());
        setVisible(mlImage, lVisible);
        mlImage.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {


            }
        });


        //初始化右图片

        setVisible(mrImage, rImageVisible);
        if(mrImage.getVisibility()== View.VISIBLE) {
            mrImage.setImageResource(rImage);

            mrImage.getLayoutParams().width = rwidth;
            mrImage.getLayoutParams().height = rheight;
            mrImage.setLayoutParams(mrImage.getLayoutParams());
        }

        //初始化

        setVisible(mrightText, rTextVisible);

        if(mrightText.getVisibility()== View.VISIBLE){

            if(TextUtils.isEmpty(rText)) {
                mrightText.setText(rText);
            }
            mrightText.setTextSize(rTextSize);
            mrightText.setTextColor(rColor);

        }



    }


    /*** * 为组合控件设置点击事件 * @param combinationListener */
    public  void setCombinationListener(final Combinationlistener combinationListener){


        mlImage.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {

                combinationListener.leftImageListener();
            }
        });


        mrightText.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                combinationListener.rightTextListener();
            }
        });

        mrImage.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                combinationListener.rightImageListener();
            }
        });

    }


    //设置控件是否可见
    private void setVisible(View view,int value){

        if(value==1){

            view.setVisibility(View.VISIBLE);

        }else {

            view.setVisibility(View.GONE);
        }

    }


    //暴露出来的点击事件接口
    public  interface  Combinationlistener{

        void  leftImageListener();

        void rightImageListener();

        void rightTextListener();



    }


}

上面的代码应该比较好理解,可能不好理解的是


        LayoutInflater.from(context).inflate(R.layout.title_layout, this, true);

        mtitle=(TextView)findViewById(R.id.title);
        mrightText=(TextView)findViewById(R.id.rightText);

        mlImage=(ImageView)findViewById(R.id.leftImage);
        mrImage=(ImageView)findViewById(R.id.rightImage);

关于inflate的用法:

可以看一下这篇文章:

inflate探究

初始化了控件属性和控件之后,就是给我们的控件设置监听事件了,我们自定义接口,把接口暴露给调用者。

布局中的使用

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="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:background="@android:color/white"
    tools:context=".MainActivity">

    <com.example.yinwei.myapplication.view.CustomCombinationWiget
        android:id="@+id/cw"
        android:background="@android:color/holo_red_light"
        app:leftImage="@android:drawable/btn_plus"
        app:rightImageVisible="visible"
        app:rightText="@string/hello_world"
        app:title="@string/hello_world"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

看在activity里面的使用:

public class MainActivity extends Activity {

    private CustomCombinationWiget cw;

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

        cw=(CustomCombinationWiget)findViewById(R.id.cw);
        cw.setCombinationListener(new CustomCombinationWiget.Combinationlistener() {
            @Override
            public void leftImageListener() {

                Toast.makeText(MainActivity.this,"左图片按钮被点击了",Toast.LENGTH_SHORT).show();
            }

            @Override
            public void rightImageListener() {


                Toast.makeText(MainActivity.this,"右图片按钮被点击了",Toast.LENGTH_SHORT).show();
            }

            @Override
            public void rightTextListener() {

                Toast.makeText(MainActivity.this,"右文字按钮被点击了",Toast.LENGTH_SHORT).show();
            }
        });

    }




}

效果图:

Android 组合控件_第1张图片

Android 组合控件_第2张图片

你可能感兴趣的:(android,继承,博客,布局,控件)