Android自定义xml属性,自定义(组合)控件
来源:互联网 发布:霍山县淘宝农村产业园 编辑:程序博客网 时间:2024/06/04 18:48
原文链接
本文是在“剑萧舞蝶”的“Android中View自定义组合控件的基本编写方法”的基础上进行修正而来的。按照原作者的说发和代码来写自定义控件,结果使用的时候出了不少问题。我之前对于这块完全没有去接触,又看到有人说网上的例子都是大同小异,很多细节也没有说清楚,所以在此记一下。
此处的所谓“自定义”组合控件的意思是,一个整体的控件里面包含了若干个控件,比如本文示例的是一个linearlayout包含了两个textview一个CheckBox,使用的时候,是把它们当做一个控件来使用的,并没有什么高深的意思(小小吐槽一下,鄙人很讨厌别人把简单的一件事情说的复杂化)。
来说一下这个“组合控件”的用处。在需要使用若干个相同的布局的时候,最简单也是最不经济的做法就是复制粘贴,需要使用多少次就粘贴多少次,既增添了代码量也不利于管理。如果这个时候有一个现成的封装好的控件能够使用,并且子控件的属性和功能也是封装好的,能节省很多代码量,方便管理,用起来也很爽。这就是组合控件啦,貌似也有人叫它组合View吧。
组合控件的实现是不难的。自定义一个布局类继承自RelativeLayout或者LinearLayout或者FrameLayout........,如果你是采用渲染的方式来完成这个组合控件的,继承自哪个layout都无所谓,如果你是采用addView方式的话,就得考虑用哪个layout比较合适。到此,如果不使用自定义xml属性的话,那么渲染好布局或者添加好控件之后,再根据需求做事件或者逻辑处理,再在需要用的layout里面用上就可以了。像这样:
<com.example.administrator.mmpapplication.CombinationView android:id="@+id/view1" android:layout_width="match_parent" android:layout_height="wrap_content" ></com.example.administrator.mmpapplication.CombinationView>
想看自定义xml属性或者渲染方式的宝宝请往下,继续阅读。
那么,我们先来自定义xml属性。首先,在/res/values目录下新建一个attrs.xml文件,内容如下:
<?xml version="1.0" encoding="utf-8"?><resources> <!--此处的name必须和自定义View的类名一致--> <declare-styleable name="CombinationView"> <attr name="desc_off" format="string"></attr> <attr name="title" format="string"></attr> <attr name="desc_on" format="string"></attr> </declare-styleable></resources>
三个attribute代表有三个属性,属性名字分别desc_off,desc_on,title,三个属性的内容格式都是string类型。ormat有好几种不同的值:string , integer , dimension , reference , color , enum。当format是enum枚举类型的时候,attr里面这样写:
<attr name="tEnum"> <enum name="hello" value="-1"/> <enum name="kitty" value="-2"/> </attr>
接下来,使用自定义属性,先拿到。
TypedArray attrArray = context.obtainStyledAttributes(attrs, R.styleable.CombinationView); String title = attrArray.getString(R.styleable.CombinationView_title); String desc_on = attrArray.getString(R.styleable.CombinationView_desc_on); String desc_off = attrArray.getString(R.styleable.CombinationView_desc_off);title,desc_on,desc_off就是我们拿到的属性的值,这时候可以使用它们了。
tv_title.setText(title);
完整的自定义类代码:
public class CombinationView extends RelativeLayout { private String TAG = "CombinationView"; private TextView tv_title, tv_desc; private CheckBox cb_status; private String title, desc_on, desc_off; public CombinationView(Context context, AttributeSet attrs) { super(context, attrs);//使用渲染的方式加载布局 View view = View.inflate(context, R.layout.layout_combinationview, this); tv_title = (TextView) view.findViewById(R.id.tv_title); tv_desc = (TextView) view.findViewById(R.id.tv_desc); cb_status = (CheckBox) view.findViewById(R.id.cb_status); TypedArray attrArray = context.obtainStyledAttributes(attrs, R.styleable.CombinationView); title = attrArray.getString(R.styleable.CombinationView_title); desc_on = attrArray.getString(R.styleable.CombinationView_desc_on); desc_off = attrArray.getString(R.styleable.CombinationView_desc_off); Log.e(TAG, "----->title:" + title + " desc_on:" + desc_on + " desc_off:" + desc_off); if (null != title) { tv_title.setText(title); } if (null != desc_off) { tv_desc.setText(desc_off); } } public boolean isCehcked() { return cb_status.isChecked(); } public void setChecked(boolean isChecked) { cb_status.setChecked(isChecked); if (isChecked) { tv_desc.setText(desc_on); } else { tv_desc.setText(desc_off); } }}完整的attrs.xml代码:
<?xml version="1.0" encoding="utf-8"?><resources> <!--此处的name必须和自定义View的类名一致--> <declare-styleable name="CombinationView"> <attr name="desc_off" format="string"></attr> <attr name="title" format="string"></attr> <attr name="desc_on" format="string"></attr> </declare-styleable></resources>在Activity的布局里边使用自定义控件:<com.example.administrator.mmpapplication.CombinationView android:id="@+id/view1" android:layout_width="match_parent" android:layout_height="wrap_content" example:title="title 1" example:desc_off="unselect 1" example:desc_on="select 1" ></com.example.administrator.mmpapplication.CombinationView>在Activity里边处理事件:public class SelfDenideViewActivity extends AppCompatActivity implements View.OnClickListener { private CombinationView combinationView1, combinationView2, combinationView3; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_self_denide_view); combinationView1 = (CombinationView) findViewById(R.id.view1); combinationView2 = (CombinationView) findViewById(R.id.view2); combinationView3 = (CombinationView) findViewById(R.id.view3); combinationView1.setOnClickListener(this); combinationView2.setOnClickListener(this); combinationView3.setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.view1: if (combinationView1.isCehcked()) { combinationView1.setChecked(false); } else { combinationView1.setChecked(true); } break; case R.id.view2: if (combinationView2.isCehcked()) { combinationView2.setChecked(false); } else { combinationView2.setChecked(true); } break; case R.id.view3: if (combinationView3.isCehcked()) { combinationView3.setChecked(false); } else { combinationView3.setChecked(true); } break; } }}到这里,例子就完了。有几个需要注意的地方,一个是在attrs.xml文件 中,declare_styleable的name的名称必须和自定义的View的类名称一致,如果是Android studio,输入之后会有提示出来。一个是 attr属性,除了指定name之外,format也必须指定。最后的也是最重点的就是命名空间的问题,我就说说我在Android studio使用的情况,刚开始我使用的是应用的包名,就是在AndroidMenifest里边的包名(补充一个,有人说此自定义的类必须要在应用包名下,不能在子包名下,本人没去试,有兴趣的宝宝可以试一下),结果Android studio直接报红线,然后根据提示,换成了这样子:xmlns:example="http://schemas.android.com/apk/res-auto"就好了。0 0
- Android自定义xml属性,自定义(组合)控件
- Android自定义控件---组合控件(包括自定义属性)
- Android 自定义组合控件,属性
- Android自定义组合控件之自定义属性
- 组合控件-自定义属性
- 自定义控件:自定义组合控件+自定义属性
- Android组合控件详解 & 自定义属性
- 自定义组合控件(Android)
- Android自定义组合控件
- android自定义组合控件
- Android自定义组合控件
- android组合自定义控件
- android 自定义组合控件
- android 自定义组合控件
- android 自定义组合控件
- Android自定义组合控件
- android自定义组合控件
- Android 自定义组合控件
- Determining IP information for eth0... failed; no link present. Check cable?
- Nginx反向代理Node.js-https
- final和static的区别
- 用两个栈实现队列
- Yii获取地址
- Android自定义xml属性,自定义(组合)控件
- java面试题
- 高阶篇:4.3.3)DFMEA现有设计:预防控制与探测控制
- python-时间序列
- 贾扬清撰文详解Caffe2:从强大的新能力到入门上手教程
- 关于我的JS插件
- OpenCV中值得学习的知识
- easyui实现tabs选项卡之间的切换(只显示一个)
- MySQL-索引