• Android自定义控件


    第一步:定义一个有图片和文本的布局:

    • <?xmlversion="1.0"encoding="utf-8"?> 
    • <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"  
    •     android:orientation="horizontal"  
    •     android:layout_width="wrap_content"  
    •     android:layout_height="wrap_content"  
    •     >  
    • <ImageView  
    •     android:id="@+id/widget_image_text_btn_Img"  
    •     android:layout_width="wrap_content"  
    •     android:layout_height="wrap_content"  
    •     />  
    • <TextView  
    •     android:id="@+id/widget_image_text_btn_TV"  
    •     android:layout_width="wrap_content"  
    •     android:layout_height="wrap_content"  
    •     android:textColor="#000000"  
    •     android:layout_marginLeft="8dip"  
    •     android:layout_gravity="center_vertical"  
    •     />  
    • </LinearLayout>  

    第二步:定义一个与这个布局对应的类:

    • publicclass ImgTextBtnH extends LinearLayout { 
    •  
    •     privatestaticfinal String TAG = ImgTextBtnH.class.getSimpleName(); 
    •      
    •     private ImageView mImg;  
    •     private TextView  mTV;  
    •     private Button mBtn; 
    •     private Context mContext = null
    •   
    •     public ImgTextBtnH(Context context) {  
    •         this(context, null);  
    •         mContext = context; 
    •     }  
    •   
    •     protectedvoid inflaterLayout(Context context) { 
    •         // 导入布局  
    •         LayoutInflater.from(context).inflate(R.layout.widget_image_text_btn_horizontal_layout, this, true);  
    •     } 
    •      
    •      
    •     @SuppressLint("NewApi"
    •     public ImgTextBtnH(Context context, AttributeSet attrs) {  
    •         super(context, attrs);  
    •         mContext = context; 
    •          
    •         Resources.Theme theme = context.getTheme(); 
    •          
    •         inflaterLayout(context); 
    •         // 导入布局  
    • //        LayoutInflater.from(context).inflate(R.layout.widget_image_text_btn_layout, this, true);  
    •         mImg = (ImageView) findViewById(R.id.widget_image_text_btn_Img);  
    •         mTV = (TextView) findViewById(R.id.widget_image_text_btn_TV);  
    •         mBtn = (Button) findViewById(R.id.widget_image_text_btn_Btn); 
    •          
    •         //不能够使用ImageView的click方法, 在android里点击事件消息是从内向外传递的,设置了false之后才能传递出来给LinearLayout 
    •         mImg.setClickable(false); //谢谢 Brightshadow11111 朋友的提醒 
    •          
    •         TypedArray typeArray = context.obtainStyledAttributes(attrs, 
    •                 R.styleable.ImgTextBtn); 
    •         if (typeArray == null) { 
    •             return
    •         } 
    •          
    •         int count = typeArray.getIndexCount(); 
    •         int resId = 0
    •         for (int i = 0; i < count; i++) { 
    •             int attr = typeArray.getIndex(i); 
    •             switch(attr) { 
    •             case R.styleable.ImgTextBtn_ImgDraw: 
    •                 Drawable background = typeArray.getDrawable(attr); 
    •                 int sdk = android.os.Build.VERSION.SDK_INT; 
    •                 if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) { 
    •                     mImg.setBackgroundDrawable(background); 
    •                 } else
    •                     mImg.setBackground(background); 
    •                 } 
    •                 break
    •             case R.styleable.ImgTextBtn_ImgDrawWidth: 
    •                 int imageWidth = typeArray.getDimensionPixelSize(attr, -1); 
    •                 mImg.setMaxWidth(imageWidth); 
    •                 mImg.setMinimumWidth(imageWidth); 
    •                 break
    •             case R.styleable.ImgTextBtn_ImgDrawHeight: 
    •                 int imageHeight = typeArray.getDimensionPixelSize(attr, -1); 
    •                 mImg.setMaxHeight(imageHeight); 
    •                 mImg.setMinimumHeight(imageHeight); 
    •                 break
    •             case R.styleable.ImgTextBtn_ImgDrawMinWidth: 
    •                 int imageMinWidth = typeArray.getDimensionPixelSize(attr, -1); 
    •                 mImg.setMinimumHeight(imageMinWidth); 
    •                 break
    •             case R.styleable.ImgTextBtn_ImgDrawMinHeight: 
    •                 int imageMinHeight = typeArray.getDimensionPixelSize(attr, -1); 
    •                 mImg.setMinimumHeight(imageMinHeight); 
    •                 break
    •             case R.styleable.ImgTextBtn_ImgDrawMaxHeight: 
    •                 int imageMaxHeight = typeArray.getDimensionPixelSize(attr, -1); 
    •                 mImg.setMaxHeight(imageMaxHeight); 
    •                 break
    •             case R.styleable.ImgTextBtn_ImgDrawMaxWidth: 
    •                 int imageMaxWidth = typeArray.getDimensionPixelSize(attr, -1); 
    •                 mImg.setMaxWidth(imageMaxWidth); 
    •                 break
    •             case R.styleable.ImgTextBtn_TVText: 
    •                 mTV.setText(typeArray.getText(attr)); 
    •                 break
    •             case R.styleable.ImgTextBtn_TVTextSize: 
    •                 mTV.setTextSize(typeArray.getDimensionPixelSize(attr, 15)); 
    •                 break
    •             } 
    •         } 
    •         typeArray.recycle(); 
    •     }  
    •      
    • <span style="color: rgb(255, 0, 0);">    @Override 
    •     publicvoid refreshDrawableState() { 
    •         // TODO Auto-generated method stub 
    •         super.refreshDrawableState(); 
    •         //------------接下来处理联动效果,关键代码,请认真看------------------- 
    •         //------------ ImageView控件的联动刷新 ------------------- 
    •         Drawable imgDrawable = mImg.getBackground(); //获取drawable资源 
    •         Log.d(TAG, "drawable = " + imgDrawable); 
    •         if (imgDrawable != null && imgDrawable.isStateful()) { 
    •             //关键中的关键,根据当前状态设置drawable的状态,本来应该是LinearLayout的getDrawableState()状态, 
    •             //但是现在是实现联动效果,而且获取的ImageView的getDrawState()结果不对。 
    •             imgDrawable.setState(this.getDrawableState());  
    •         } 
    •          
    •         //------------- TextView的联动刷新, 抱歉, 无法刷新 ------------------ 
    •         //这块代码很快写出来了,但是写出来后发现,颜色总是停留在最后一次的颜色上,后面再点击都无法改变颜色了, 
    •         //才恍然大悟,mTV.setTextColor()是设置TextView内部的ColorStateList对象的,这样会清掉原先的 
    •         //res/color/colorSelector.xml里的设置,导致只有一种颜色值。应该赋值给TextView内部的private int mCurTextColor; 
    •         //可惜没有并设置mCurTextColor值的接口,不知到使用反射能否做到,有兴趣朋友可以一试。 
    •         //既然Text的color是靠TextPaint刷出来的,那么是否可以改变TextPaint的颜色值呢?发现有接口getPaint可以获取到TextPaint, 
    •         //但是设置了color值之后,还是不行,哦,原来在onDraw()函数中,重新设置了颜色值,所以白设了。 
    •         //总而言之,联动刷新颜色是不行滴,只能设一个颜色(对于我目前来讲功能已经是足够了) 哈哈,讲的够详细吧~~ 
    •         ColorStateList mTextColor = mTV.getTextColors(); 
    •          
    •         int color = mTextColor.getColorForState(this.getDrawableState(), 0); 
    •         if (mTV.getCurrentTextColor() != color) { 
    •             mTV.getPaint().setColor(color); 
    • //          mTV.setTextColor(color); 
    •             mTV.invalidate(); 
    •         } 
    •          
    •         //-----------如果有个Button的话就可以在这里设置改变,效果同上,略--------------- 
    • //        Drawable btnDrawable = mBtn.getBackground(); 
    • //      Log.d(TAG, "drawable = " + btnDrawable); 
    • //      if (btnDrawable != null && btnDrawable.isStateful()) { 
    • //          btnDrawable.setState(this.getDrawableState()); 
    • //      } 
    • //       
    • //      ColorStateList mTextColor2 = mBtn.getTextColors(); 
    • //      int color2 = mTextColor2.getColorForState(this.getDrawableState(), 0); 
    • //        if (mBtn.getCurrentTextColor() != color2) { 
    • //          mBtn.setTextColor(color2); 
    • //        } 
    •   
    •     }</span> 
    •  
    •     /**
    •      * 设置图片资源
    •      */  
    •     publicvoid setImgViewResource(int resId) {  
    •         mImg.setImageResource(resId);  
    •     }  
    •      
    •     /**
    •      * 设置图片
    •      */  
    •     publicvoid setImgViewResource(Bitmap bitmap) {  
    •         mImg.setImageBitmap(bitmap);  
    •     }  
    •   
    •     /**
    •      * 设置显示的文字
    •      */  
    •     publicvoid setTextViewText(int resId) {  
    •         mTV.setText(resId);  
    •     }  
    •     /**
    •      * 设置显示的文字
    •      */  
    •     publicvoid setTextViewText(String text) {  
    •         mTV.setText(text);  
    •     }  
    •   

    第三步:在value/下面定义一个attrs.xml文件,内容如下: 

    • <?xmlversion="1.0"encoding="utf-8"?> 
    • <resources> 
    •     <declare-styleablename="ImgTextBtn"> 
    •         <attrname="ImgDraw"format="reference"></attr> 
    •         <attrname="ImgDrawWidth"format="dimension"></attr> 
    •         <attrname="ImgDrawHeight"format="dimension"></attr> 
    •         <attrname="ImgDrawMinWidth"format="dimension"></attr> 
    •         <attrname="ImgDrawMinHeight"format="dimension"></attr> 
    •         <attrname="ImgDrawMaxWidth"format="dimension"></attr> 
    •         <attrname="ImgDrawMaxHeight"format="dimension"></attr> 
    •          
    •         <attrname="TVText"format="reference|string"></attr> 
    •         <attrname="TVTextSize"format="dimension"></attr> 
    •         <attrname="TVTextColor"format="reference|color"></attr> 
    •     </declare-styleable> 
    •      
    • </resources> 

    第四步:直接在布局中使用

    • <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android" 
    • //CustomAttrs为自定义属性,com.example.testdrawable为包名
    •     xmlns:CustomAttrs="http://schemas.android.com/apk/res/com.example.testdrawable" 
    •     android:layout_width="match_parent" 
    •     android:layout_height="match_parent"> 
    •  
    •     <com.widget.ImgTextBtn 
    •         android:id="@+id/imageTextButton1" 
    •         android:layout_width="match_parent" 
    •         android:layout_height="wrap_content" 
    •         android:orientation="vertical" 
    •         android:layout_above="@+id/textView1" 
    •         android:layout_centerHorizontal="true" 
    •         android:layout_marginBottom="35dp" 
    •         android:background="@drawable/preference_round_rect_light_blue" 
    •         CustomAttrs:TVText="@string/hello_world" 
    •         CustomAttrs:TVTextSize="@dimen/dimens_Padding_normal" 
    •         CustomAttrs:ImgDraw="@drawable/test_btn_selector"> 
    •     </com.widget.ImgTextBtn> 
    •  
    • </RelativeLayout>
  • 相关阅读:
    TCP/IP三次握手四次挥手
    注解(JDK1.5之后)
    枚举(JDK1.5之后)
    局部内部类
    非静态内部类
    静态内部类
    匿名内部类
    接口
    根父类:java.lang.Object
    native关键字
  • 原文地址:https://www.cnblogs.com/xiao-xu/p/3438736.html
Copyright © 2020-2023  润新知