Wednesday, November 4, 2015

Android custom view how to define the attires? Android为自定义View添加属性


1 Android为自定义View添加属性

如何灵活的定义自己喜欢的  样式?

<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:my="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/viewfinder_mask">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <SurfaceView
            android:id="@+id/preview_view"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />

        <com.eallcn.rentagent.qrcode.ViewfinderView
            android:id="@+id/viewfinder_view"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            my:bottomText="@string/scan_text"
            my:maskColor="@color/viewfinder_mask"
            my:lineDrawable="@drawable/qrcode_scan_line"
            />

    </FrameLayout>

    <com.chow.ui.ChowTitleBar
        android:id="@+id/title_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:center_title_text="@string/qr_code_string"
        app:left_title_icon="@drawable/selector_back_red"
        />


</RelativeLayout>


注意: 第一个坑:
xmlns:my="http://schemas.android.com/apk/res-auto"


在 AS  intillJ 中:xmlns:app="http://schemas.android.com/apk/res-auto" 

但是在Eclispe:
xmlns:app="http://schemas.android.com/apk/lib/com.app.chasebank"

我在这个地方被坑了,其他的地方我都解决了,但是我使用的Android studio, 我按照 全包名配置的,导致了 运行的时候老是找不到我的 自定义的属性!我也很蛋疼。这也许是 As 和 Eclispe 处理机制不同导致的!

首先:我们首先定义一下我们自己的属性文件
在 value/attrs.xml
<?xml version="1.0" encoding="utf-8"?><resources>
    <declare-styleable name="ViewfinderView">        <attr name="bottomText" format="string"></attr>        <attr name="bottomTextColor" format="color"></attr>        <attr name="bottomTextSize" format="dimension"></attr>        <attr name="maskColor" format="color"></attr>        <attr name="lineDrawable" format="reference"></attr>    </declare-styleable>


注意:第二个坑:
这里的 declare-styleable name 必须和你的自定义的View 的名字保持一致,如果不一致自然找不到你自定义的属性呀!
我就在这里被坑了!


第二步: 给自定义的View 设置自己的属性
这是属性有两种方式:

private void setAttrs(Context context,AttributeSet attrs){
// 1 获取属性的数组
   TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ViewfinderView);

// 2 取出你需要的属性   bottomString = array.getString(R.styleable.ViewfinderView_bottomText);   Resources resources = getResources();   maskColor = array.getColor(R.styleable.ViewfinderView_maskColor,resources.getColor(R.color.viewfinder_mask));   lineDrawable = array.getDrawable(R.styleable.ViewfinderView_lineDrawable);

// 3 回收
   array.recycle();}

第二种方式:

public Navbar(Context context, AttributeSet attrs) {
super(context, attrs);
setUp();
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Navbar);
final int N = a.getIndexCount();
for (int i = 0; i < N; ++i) {
int attr = a.getIndex(i);
switch (attr) {
case R.styleable.Navbar_textTitle:
title.setText(a.getString(attr));
break;
case R.styleable.Navbar_onAction:
...
break;
}
}
a.recycle();
}

Ok  you do it 

========================================================================
2  android开发之自定义属性、View和使用
http://blog.csdn.net/zanelove/article/details/43083449#

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="名称">
        <attr name="title" format="string"/>
        <attr name="titleTextSize" format="dimension"/>
        <attr name="titleTextColor" format="color"/>
        <attr name="leftTextColor" format="color"/>
        <attr name="leftBackground" format="reference|color"/>
        <attr name="leftText" format="string"/>
        <attr name="rightTextColor" format="color"/>
        <attr name="rightBackground" format="reference|color"/>
        <attr name="rightText" format="string"/>
    </declare-styleable>
</resources>

==================================================================

public void CustomView(Context context) {} //代号C1
public void CustomView(Context context, AttributeSet attrs) {} //代号C2
public void CustomView(Context context, AttributeSet attrs, int defStyle) {} //代号C3

C1:用code动态创建一个View而不使用布局文件xml inflate,那么实现C1就可以了!
C2:多了一个AttributeSet类型的参数,在通过布局文件xml引用自定义VIew时,这个参数会将xml里引用的自定义View所设定的属性传递给构造函数;如果采用xml inflate的方法却没有在code里实现C2,那么运行时就会报错!
C3:多了一个defStyle的int参数,关于这个参数doc里是这样描述的:


========================================================================


========================================================================

附录:  参考链接

http://stormzhang.com/android/2013/08/04/android-custom-xml-attributes-for-your-custom-widgets/


https://software.intel.com/zh-cn/blogs/2015/03/05/android-view

3  http://blog.csdn.net/zanelove/article/details/43083449#


No comments:

Post a Comment