第一步:定义一个有图片和文本的布局:
- <?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>