android自定义控件_自定义组合控件1

最近有时间整理一下一直想要总结的自定义控件,有问题希望大家及时指出。

自定义根据项目需求可以简单的分成以下3种:
1.自定义组合控件;
2.继承已有的控件   比如smartImageView继承ImageView;
3.完全自定义控件   1)定义一个类继承安卓中的基类View   2)定义一个类继承安卓中的基类ViewGroup;

自定义组合控件:使用结构相同的布局,而且布局中不只有一个控件同时子控件位置都是一样的,即把已有的原生控件组合成一个新的控件
比如图1仿微信底部四个icon所示(上面imageview 下面textview)

        图2设置页面控件开关所示(左边 textview 右边switch)

其实现的原理都是一样的,自定义一个类继承RelatiiveLayout或者LinearLayout等容器(这样的容器都可以包含多个控件)然后重写其方法
本文中第一个列子很简单,没有用到AttributeSet属性,最终实现的效果如图(点击图和文字都同时变化): 


自定类MyButton代码如下:
/**
 * 自定义button
 */

public class MyButton extends LinearLayout {

    /**
     * 底部名称
     */
    private TextView btnText;

    /**
     * 图标icon
     */
    private ImageView imageView;

    /**
     * 成员变量isSelected 是不是选中的状态 默认false
     */
    private boolean isSelected = false;

    private int imageDefault;

    private int imageSelected;

    private String text;

    public MyButton(Context context) {
        super(context);
        init(context, null);
    }

    public MyButton(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public MyButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }


    /**
     * 初始化 根据布局文件填充控件
     *
     * @param context
     * @param attrs
     */
    private void init(Context context, AttributeSet attrs) {
        //inflate 函数有3个参数 参数一是填充的布局文件 参数二 本布局添加到父控件中 作用类似于addView
        View butttonView = LayoutInflater.from(context).inflate(R.layout.layout_mybutton, this, true);
        imageView = (ImageView) butttonView.findViewById(R.id.mybtn_img);
        btnText = (TextView) butttonView.findViewById(R.id.mybtn_txt);

    }

    /**
     * 使用控件先初始化
     *
     * @param imageDefault
     * @param imageSelected
     * @param text
     */
    public void setButtonView(int imageDefault, int imageSelected, String text) {
        this.imageDefault = imageDefault;
        this.imageSelected = imageSelected;
        this.text = text;

        imageView.setImageResource(imageDefault);
        btnText.setText(text);

    }

    /**
     * 重写基类View的是否select的方法
     * LinearLayout <= ViewGroup <= View
     *
     * @return
     */
    @Override
    public boolean isSelected() {
        return isSelected;
    }

    /**
     * 重写基类View的设置select的方法
     * 用的时候:代码中点击事件触发时先走这个方法 标志了状态
     *
     * @return
     */
    @Override
    public void setSelected(boolean selected) {
        isSelected = selected;
        changeSelected();
    }

    /**
     * 点击底部切换按钮的时候 改变状态 即selected标志
     */
    public void changeSelected() {

        if (isSelected) {
            //选中的话
            isSelected = false;
            imageView.setImageResource(imageSelected);
            btnText.setText(text);
            btnText.setTextColor(Color.parseColor("#fed955"));
        } else {
            isSelected = true;
            imageView.setImageResource(imageDefault);
            btnText.setText(text);
            btnText.setTextColor(Color.parseColor("#666666"));
        }
    }
}

首先MyButton继承于LinearLayout 。控件的继承关系如下:LinearLayout继承与ViewGroup;ViewGroup继承于基类View;然后每个都有针对自己的实现(这也体现了java面向对象的好处,单继承、多实现) 。
其中:isSelected()和setSelected()是View中的方法;setButtonView()是用于控件初始化;changeSelected()用于改变状态。
布局文件:
<?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="match_parent"
    android:clipChildren="false"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/mybtn_img"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_gravity="center"
        android:layout_marginTop="3dp"
        android:layout_weight="1"
        android:src="@drawable/icon_account" />

    <TextView
        android:id="@+id/mybtn_txt"
        android:layout_width="match_parent"
        android:textColor="@color/common_h1"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:text="名称"
        android:textSize="12sp" />
</LinearLayout>

使用方法:
public class MainActivity extends AppCompatActivity {

    private boolean isSeleced = false;//默认是不选中的

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

        final MyButton myButton = findViewById(R.id.btn_text);
        myButton.setButtonView(R.drawable.icon_account, R.drawable.icon_account_selected, "账单");
        myButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (isSeleced) {
                    isSeleced = false;
                    myButton.setSelected(true);
                } else {
                    isSeleced = true;
                    myButton.setSelected(false);
                }

            }
        });
    }
}

主布局文件中的引用方式:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    tools:context="com.yezhu.myapplication.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <com.yezhu.myapplication.MyButton
            android:id="@+id/btn_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>

</LinearLayout>

综上所述,自定义组合控件一般都是以继承ViewGroup及其子类(4大布局)为主,内部嵌套其他控件,来组合成一个新的控件从而实现一些特定的需要,具有简化代码,结构清晰,重用性高的特性。
以上就是最简单的自定义组合控件方式,如有问题请大家及时指出。






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值