您的位置:首页 > 移动开发 > Android开发

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

2018-02-26 19:52 585 查看
最近有时间整理一下一直想要总结的自定义控件,有问题希望大家及时指出。

自定义根据项目需求可以简单的分成以下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大布局)为主,内部嵌套其他控件,来组合成一个新的控件从而实现一些特定的需要,具有简化代码,结构清晰,重用性高的特性。

以上就是最简单的自定义组合控件方式,如有问题请大家及时指出。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: