zoukankan      html  css  js  c++  java
  • Android 自定义 attr

    好纠结,弄了一个下午老是报错如是总结一下安卓自定视图和自定义属性。

    (一)自定义属性

      在Values文件下建立一个attrs.xml文件,attr的format可以参考:http://www.cnblogs.com/crashmaker/p/3521310.html

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <declare-styleable name="nfyh">
            <attr name="title" format="reference"/>
            <attr name="icon" format="reference"/>
            <attr name="border_width" format="dimension"/>
            <attr name="enable_right" format="boolean"/>
            <attr name="selected" format="boolean"/>
        </declare-styleable>
    
    </resources>

    (一)自定义视图(View)

    /**
     * 列表项视图
     * 
     * @author Chenrui
     * 
     */
    public class ListItemView extends LinearLayout
    {
        
        private TextView        tvTitle;
        private TextView        tvSubTitle;
        private ImageView        imgNext;
        private OnClickListener    listener;
        private Context            context;
        private View            viewBorder;
        private LinearLayout    customerViews;
        private Intent            nextIntent;
        
        public ListItemView(Context context,AttributeSet attrs)
        {
            this(context, attrs, 0); // 使用XML文件布局的时候,不会调用 ListItemView(Context context) 的构造函数,如果有主题的需要调用这个构造函数
        }
        
        public ListItemView(Context context, AttributeSet attrs, int defStyle)
        {
            super(context, attrs, defStyle);
            this.context = context;
            LayoutInflater.from(context).inflate(R.layout.view_list_item, this); //初始化布局
            this.tvTitle = (TextView) this
                    .findViewById(R.id.tv_view_liset_item_title);
            this.tvSubTitle = (TextView) this
                    .findViewById(R.id.tv_view_liset_item_sub_title);
            this.imgNext = (ImageView) this
                    .findViewById(R.id.img_view_liset_item_right);
            
            this.viewBorder = findViewById(R.id.view_list_item_border);
            customerViews = (LinearLayout) this
                    .findViewById(R.id.viewStub_view_list_item);
            
            initView(attrs, defStyle);
        }
        
        private void initView(AttributeSet attrs, int defStyle)
        {
            if (attrs == null) return; //赋值
            
            TypedArray typeArray = null;
            try
            {
                typeArray = context.obtainStyledAttributes(attrs, R.styleable.nfyh,
                        defStyle, 0); //这里获取自定义属性
                
                int count = typeArray.getIndexCount();
                //试过使用typeArray.getString(R.styleable.nfyh_title);获取不了值,不知道为何??!!
                for (int i = 0; i < count; i++)
                {
                    int index = typeArray.getIndex(i); 
                    switch (index)
                    {
                        case R.styleable.nfyh_title:
                            this.setText(typeArray.getString(index)); break;
                        case R.styleable.nfyh_enable_right:
                            this.setNextEnable(typeArray.getBoolean(index, false));
                            break;
                        case R.styleable.nfyh_selected:
                            if (typeArray.getBoolean(index, false)) this
                                    .setSelected();
                            break;
                        case R.styleable.nfyh_icon:
                            this.setIcon(typeArray.getResourceId(index, 0));
                            break;
                        case R.styleable.nfyh_border_
                            this.setBorder(typeArray.getDimensionPixelOffset(index,
                                    1));
                            break;
                        default:
                            break;
                    }
                }
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
            finally
            {
                typeArray.recycle();//一定要调用回收
            }
        }
        
        @Override
        public void setOnClickListener(View.OnClickListener l)
        {
            super.setOnClickListener(l);
            this.listener = l;
        }
        
        public void setIcon(int id)
        {
            this.tvTitle.setCompoundDrawablesWithIntrinsicBounds(id, 0, 0, 0);
            
        }
        
        public void setText(String text)
        {
            this.tvTitle.setText(text);
        }
        
        public void setSubText(String text)
        {
            this.tvSubTitle.setText(text);
        }
        
        public void setSelected()
        {
            this.tvTitle.setTextColor(context.getResources()
                    .getColor(R.color.green));
        }
        
        public void setBorder(int height)
        {
            this.viewBorder.setLayoutParams(new LayoutParams(
                    LayoutParams.MATCH_PARENT, height));
            //        this.viewBorder.setBackgroundColor(colorID);
        }
        
        public void setNextEnable(boolean value)
        {
            int visibility = value ? View.VISIBLE : View.GONE;
            this.imgNext.setVisibility(visibility);
        }
        
        public void setCustomerView(View v)
        {
            customerViews.addView(v);
        }
        
        public void removeCustomerViews()
        {
            customerViews.removeAllViews();
        }
        
        public void setNextIntent(Intent intent)
        {
            this.nextIntent = intent;
        }
        
    }

    在布局文件中使用自定义视图,直接使用包名。

    <com.yixin.nfyh.cloud.ui.ListItemView style="@style/Widget.Light.IOS.ListItem.Title" 
                    nfyh:title="@string/canshuxuanzhe">
                </com.yixin.nfyh.cloud.ui.ListItemView>

    这里很重要的是命名空间,这里的命名空间(xmlns:nfyh)是可以随便命名的,和attrs的name不必对上。

    <?xml version="1.0" encoding="utf-8"?>
    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:nfyh="http://schemas.android.com/apk/res-auto" //注意这里,res-auto也可以是你的包名 xmlns:nfyh="http://schemas.android.com/apk/res/com.yixin.nfyh.cloud"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#eeeded"
        android:orientation="vertical" >
       <com.yixin.nfyh.cloud.ui.ListItemView style="@style/Widget.Light.IOS.ListItem.Title" 
                    nfyh:title="@string/canshuxuanzhe">
                </com.yixin.nfyh.cloud.ui.ListItemView>
    
                <LinearLayout
                    android:id="@+id/ll_ui_sign_detail_params_title"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical" >
                </LinearLayout>
    
    
    

    .... 此处省略

     style文件

     <style name="Widget.Light.IOS.ListItem.Title" parent="@style/match_warp">
            <item name="android:layout_marginBottom">10dp</item>
            <item name="android:layout_marginTop">10dp</item>
            <item name="android:orientation">vertical</item>
        <!-- ...以下自定以属性 -->
    <item name="border_width">5dp</item> <item name="icon">@drawable/ic_tile_list</item> <item name="selected">true</item> <item name="enable_right">false</item> </style>

     总结:

    1. 记得自定义调用构造函数的区别
    2. 不能忘了自定义命名空间的
  • 相关阅读:
    CodeForces 734F Anton and School
    CodeForces 733F Drivers Dissatisfaction
    CodeForces 733C Epidemic in Monstropolis
    ZOJ 3498 Javabeans
    ZOJ 3497 Mistwald
    ZOJ 3495 Lego Bricks
    CodeForces 732F Tourist Reform
    CodeForces 732E Sockets
    CodeForces 731E Funny Game
    CodeForces 731D 80-th Level Archeology
  • 原文地址:https://www.cnblogs.com/chenrui7/p/3614373.html
Copyright © 2011-2022 走看看