您的位置:首页 > 其它

自定义图文控件ImageTextView

2015-12-22 23:30 429 查看
前言:

在App开发过程中,有时候需要使用图片和文字搭配使用,特别是自定义BottomBar导航条的时候,为了统一样式,自定义一个图文控件会带来很大的方便。如下图所示:





我主要分为四种样式,水平和垂直、红点提示和数字提示。2*2=4

原型如下:




该ImageTextView继承于LinearLayout,你可以把它当做一个具有图文属性的线性布局,在线性布局下面有一个RelativeLayout(显示图片和提示信息)和一个TextView(显示标题),它能支持RelativeLayout和TextView垂直和水平两个方向布局,在RelativeLayout下面是一个ImageView(图片)和一个ImageView(小红点时显示)/TextView(数字提示时显示)。下面是垂直方向的布局的详细设计,而水平方向的话,只需要把TextView移动到RelativeLayout的右边:



这里通过两种方式来使用图文控件ImageTextView:

1. 在xml布局中引入ImageTextView

2.在Java代码中创建ImageTextView

1.第一种方式:在xml布局中引入ImageTextView

1.1 直接看imagetextView.xml,该布局对应于上面布局的详细设计

[code]<LinearLayout
    android:id="@+id/imagetextview_layout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="vertical">
    <LinearLayout
        android:id="@+id/lL_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="vertical">
        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
            <ImageView
                android:id="@+id/image"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true" />
            <ImageView
                android:id="@+id/renewalImg"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentTop="true"
                android:layout_toRightOf="@id/image"
                android:background="@drawable/icon_dot"
                android:visibility="gone"/>
            <TextView
                android:id="@+id/renewalTv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:layout_alignParentTop="true"
                android:layout_toRightOf="@id/image"
                android:background="@drawable/icon_dot10"
                android:textColor="#ffffff"
                android:visibility="gone"/>
        </RelativeLayout>
        <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="8dp"/>
    </LinearLayout>
</LinearLayout>


这里右上的小控件用到了drawable文件下的icon_dot.xml和icon_dot10.xml作为背景资源,就是右上小红点.代码如下:

icon_dot.xml:

[code]<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" >
    <size
        android:width="5dp"
        android:height="5dp"/>
    <solid android:color="#fffc4545"/>
</shape>


icon_dot10.xml:

[code]<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" >
    <size
        android:width="10dp"
        android:height="10dp"/>
    <solid android:color="#fffc4545"/>
</shape>


1.2 然后在需要使用图文控件的activity_main.xml布局中引用ImageTextView

[code]<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <LinearLayout
        android:id="@+id/itv_ll"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center"
        android:orientation="horizontal" >
        <com.example.imagetextview.ImageTextView
            android:id="@+id/main_home"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:src="@drawable/icon_bm_home_home_nor"
            android:text="首页"
            android:textColor="#000000" />
        <com.example.imagetextview.ImageTextView
            android:id="@+id/main_shopping"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:orientation="horizontal"
            android:src="@drawable/icon_bm_home_shopping_nor"
            android:text="购物车"
            android:textColor="#000000" />
    </LinearLayout>
</LinearLayout>


在ImageTextView中使用了一些自定义的属性,需要在drawable文件下的attrs.xml中设置自定义属性,以便在ImageTextView中的构造方法里获得属性值。

[code]<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ImageTextView">
    <attr name="android:text" />
    <attr name="android:textColor" />
    <attr name="android:textSize" />
    <attr name="android:background" />
    <attr name="android:src" />
    <attr name="android:orientation"/>
</declare-styleable>
</resources>


1.3 下面来看ImageTextView中使用xml引用时调用的构造方法,主要是获取xml中的属性,并设置到控件上。

[code]/**
     * 构造方法:用于在布局xml里面引用ImageTextView
     * 
     * @param context
     * @param attrs
     */
    public ImageTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        View view = LayoutInflater.from(context).inflate(
                R.layout.imagetextview, this, true);
        lL_content = (LinearLayout) view.findViewById(R.id.lL_content);
        imageView = (ImageView) view.findViewById(R.id.image);
        renewalImg = (ImageView) view.findViewById(R.id.renewalImg);
        renewalTv = (TextView) view.findViewById(R.id.renewalTv);
        textView = (TextView) view.findViewById(R.id.text);

        // 如果xml中的ImageViewText控件中的属性不为空,则取出其属性,并赋值到相应控件上
        if (attrs != null) {
            TypedArray typedArray = context.obtainStyledAttributes(attrs,
                    R.styleable.ImageTextView);
            //方向 0-水平;1-垂直。默认为1
            int orientation = typedArray.getInt(R.styleable.ImageTextView_android_orientation, 1);
            if(orientation == LinearLayout.HORIZONTAL) {    //水平布局
                lL_content.setOrientation(LinearLayout.HORIZONTAL);

            } else {    //垂直
                lL_content.setOrientation(LinearLayout.VERTICAL);
            }
            // textview内容
            CharSequence text = typedArray
                    .getText(R.styleable.ImageTextView_android_text);
            if (text != null) {
                textView.setText(text);
            }
            // textview字体颜色
            ColorStateList color = typedArray.getColorStateList(0);
            if (color != null) {
                textView.setTextColor(color);
            }
            // textview字体大小
            float testSize = typedArray.getFloat(
                    R.styleable.ImageTextView_android_textSize, 12);
            if (testSize != 0) {
                textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, testSize);
            }
            // imageview的图片资源
            Drawable drawable = typedArray
                    .getDrawable(R.styleable.ImageTextView_android_src);
            if (drawable != null) {
                imageView.setImageDrawable(drawable);
            }
            // imageview背景
            Drawable drawableBg = typedArray
                    .getDrawable(R.styleable.ImageTextView_android_background);
            if (drawableBg != null) {
                imageView.setBackgroundDrawable(drawableBg);
            }
            // 保持以后使用属性的一致性
            typedArray.recycle();
        }
        // 对ImageTextView触摸事件的监听
        this.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    imageView.setPressed(true);
                    textView.setPressed(true);
                } else if (event.getAction() == MotionEvent.ACTION_CANCEL
                        || event.getAction() == MotionEvent.ACTION_UP) {
                    imageView.setPressed(false);
                    textView.setPressed(false);
                }
                return false;
            }
        });
    }


1.4 然后在MainActivity.java中像普通控件一样去得到ImageTextView,并使用它就可以了。

[code]    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        itv_home = (ImageTextView)findViewById(R.id.main_home);
        itv_shopping =  (ImageTextView)findViewById(R.id.main_shopping);

        /**-------通过xml布局使用ImageTextView----------**/
        //主页图片和文字垂直显示,右上显示提示红点
        itv_home.setRenewalImgVisible(true);

        //购物车图片和文字水平显示,右上显示数量
        itv_shopping.setRenewalITvVisible(true);
        itv_shopping.setRenewalTv("8");
    }


2.第二种方式:Java代码中创建ImageTextView

2.1 首先来看ImageTextView中用于Java代码创建ImageTextView对象的构造方法,主要作用是生成imagetextview.xml的类似布局

[code]/**
     * ImageView构造方法,用于在Java代码里创建ImageTextView对象
     * 
     * @param context
     *            上下文
     * @param vertical
     *            LinearLayout是否为垂直方向布局 true-垂直;false-水平
     */
    public ImageTextView(Context context, boolean vertical) {
        super(context);
        this.context = context;
        if (vertical) {
            setOrientation(LinearLayout.VERTICAL);
        } else {
            setOrientation(LinearLayout.HORIZONTAL);
        }
        // 设置权重
        setGravity(Gravity.CENTER);
        // 创建相对布局,用于包裹图片和图片右上冒泡图片
        RelativeLayout relativeLayout = new RelativeLayout(context);
        this.addView(relativeLayout);
        // 图片
        imageView = new ImageView(context);
        RelativeLayout.LayoutParams imageLP = new RelativeLayout.LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        imageLP.addRule(RelativeLayout.CENTER_IN_PARENT);
        imageView.setLayoutParams(imageLP);
        imageView.setId(IMAGEVIEW_ID); // 为renewalImg绑定在其
        relativeLayout.addView(imageView);
        // 右上图片
        renewalImg = new ImageView(context);
        RelativeLayout.LayoutParams renewalImgLP = new RelativeLayout.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        renewalImgLP.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        renewalImgLP.addRule(RelativeLayout.RIGHT_OF, IMAGEVIEW_ID); // 把该图片绑定在id为1的右边
        renewalImg.setLayoutParams(renewalImgLP);
        renewalImg.setBackgroundResource(R.drawable.icon_dot);
        renewalImg.setVisibility(View.GONE); // 默认为隐藏
        relativeLayout.addView(renewalImg);
        // 右上文字
        renewalTv = new TextView(context);
        RelativeLayout.LayoutParams renewalTvLP = new RelativeLayout.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        renewalTvLP.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        renewalTvLP.addRule(RelativeLayout.RIGHT_OF, IMAGEVIEW_ID); // 把该图片绑定在id为1的右边
        renewalTv.setLayoutParams(renewalTvLP);
        renewalTv.setBackgroundResource(R.drawable.icon_dot10);
        renewalTv.setVisibility(View.GONE); // 默认为隐藏
        renewalTv.setGravity(Gravity.CENTER);
        renewalTv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 8);
        renewalTv.setTextColor(Color.WHITE);
        relativeLayout.addView(renewalTv);
        // 文字
        textView = new TextView(context);
        textView.setGravity(Gravity.CENTER);
        textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12);
        this.addView(textView); // 把textView加到ImageTextView里面,即加到图片和右边图片包裹起来的相对布局的右边或者下面
    }


2.2 然后在MainActivity.java中使用它

[code]protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        itv_ll = (LinearLayout)findViewById(R.id.itv_ll);   //包裹ImageTextView的线性布局
        /**-------通过代码创建ImageView视图使用ImageTextView---------**/
        //历史记录图片和文字垂直显示,并右上显示提示红点
        ImageTextView itv_history = new ImageTextView(MainActivity.this, true);
        itv_history.setImageResource(R.drawable.icon_bm_home_history_nor);
        itv_history.setTextView("历史记录");
        itv_history.setRenewalImgVisible(true);
        itv_ll.addView(itv_history);

        //个人中心图片和文字水平显示,并右上显示提示数量
        ImageTextView itv_user = new ImageTextView(MainActivity.this, false);
        itv_user.setImageResource(R.drawable.icon_bm_home_user_nor);
        itv_user.setTextView("个人中心");
        itv_user.setRenewalITvVisible(true);
        itv_user.setRenewalTv("8");
        itv_ll.addView(itv_user);   
    }


下面是效果图:



3.ImageTextView类中的其他方法

在ImageTextView中提供了一些方法,例如设置是否显示右上角标等方法,注释很详细

[code]    /**
     * 传递Drawable对象设置ImageView图片资源
     * 
     * @param drawable
     */
    public void setImageDrawable(Drawable drawable) {
        if (drawable != null) {
            imageView.setImageDrawable(drawable);
        }
    }

    /**
     * 传递ResourceId来设置ImageView的图片资源
     * 
     * @param resId
     */
    public void setImageResource(int resId) {
        imageView.setImageResource(resId);
    }

    /**
     * 传递Bitmap对象设置ImageView的图片资源
     * 
     * @param bitmap
     */
    public void setImageBitmap(Bitmap bitmap) {
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap);
        }
    }

    /**
     * 得到ImageTextView中的ImageView对象
     * 
     * @return
     */
    public ImageView getImageView() {
        return imageView;
    }

    /**
     * 得到ImageView的图片资源
     * 
     * @return Drawable对象
     */
    public Drawable getDrawable() {
        return imageView.getDrawable();
    }

    /**
     * 得到ImageView的背景图片
     * 
     * @return Drawable对象
     */
    public Drawable getBackground() {
        return imageView.getBackground();
    }

    /**
     * 显示ImageView控件
     */
    public void showImageView() {
        if (imageView.getVisibility() != View.VISIBLE) {
            imageView.setVisibility(View.VISIBLE);
        }
    }

    /**
     * 隐藏ImageView控件
     */
    public void hideImageView() {
        if (imageView.getVisibility() != View.GONE) {
            imageView.setVisibility(View.GONE);
        }
    }

    /**
     * 传递Drawable对象设置ImageView的背景图片
     * 
     * @param drawable
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    public void setBackgroundDrawable(Drawable drawable) {
        if (drawable != null) {
            imageView.setBackground(drawable);
        }
    }

    /**
     * 传递ResourceId设置ImageView的背景图片
     * 
     * @param resId
     */
    public void setBackgroundResource(int resId) {
        imageView.setBackgroundResource(resId);
    }

    /**
     * 设置右上图标是否可见
     * 
     * @param visible
     *            右上图标是否可见:true-可见;false-隐藏
     */
    public void setRenewalImgVisible(boolean visible) {
        if (visible) {
            if (renewalImg.getVisibility() != View.VISIBLE) {
                renewalImg.setVisibility(View.VISIBLE);
            }
        } else {
            if (renewalImg.getVisibility() != View.GONE) {
                renewalImg.setVisibility(View.GONE);
            }
        }
    }

    /**
     * 设置右上文字内容
     * 
     * @param text
     */
    public void setRenewalTv(String text) {
        if (text != null) {
            renewalTv.setText(text);
        }
    }

    /**
     * 得到右上TextView控件
     * 
     * @return
     */
    public TextView getRenewalTextView() {
        return renewalTv;
    }

    /**
     * 得到右上文字内容
     * 
     * @return
     */
    public String getRenewalTv() {
        return renewalTv.getText().toString();
    }

    /**
     * 设置TextView的文字
     * 
     * @param text
     */
    public void setTextView(String text) {
        if (text != null) {
            textView.setText(text);
        }
    }

    /**
     * 设置右上文字是否可见
     * 
     * @param visible
     *            右上图标是否可见:true-可见;false-隐藏
     */
    public void setRenewalITvVisible(boolean visible) {
        if (visible) {
            if (renewalTv.getVisibility() != View.VISIBLE) {
                renewalTv.setVisibility(View.VISIBLE);
            }
        } else {
            if (renewalTv.getVisibility() != View.GONE) {
                renewalTv.setVisibility(View.GONE);
            }
        }
    }

    /**
     * 设置TextView的文字大小,默认单位为dip
     * 
     * @param size
     *            文字大小
     */
    public void setTestSize(float size) {
        textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
    }

    /**
     * 带单位类型设置TextView的文字大小,默认单位为dip
     * 
     * @param size
     *            文字大小
     * @param unitType
     *            单位类型,为TypedValue中的常量。eg:dip->TypedValue.COMPLEX_UNIT_DIP
     */
    public void setTestSize(float size, int unitType) {
        textView.setTextSize(unitType, size);
    }

    /**
     * 设置TextView文字颜色
     * 
     * @param color
     */
    public void setTextColor(int color) {
        textView.setTextColor(color);
    }

    /**
     * 设置TextView的Padding
     * 
     * @param leftDip
     * @param topDip
     * @param rightDip
     * @param bottomDip
     */
    public void setTextPadding(int leftDip, int topDip, int rightDip,
            int bottomDip) {
        int leftPx = MetricUtil.dip2px(context, leftDip);
        int topPx = MetricUtil.dip2px(context, topDip);
        int rightPx = MetricUtil.dip2px(context, rightDip);
        int bottomPx = MetricUtil.dip2px(context, bottomDip);
        textView.setPadding(leftPx, topPx, rightPx, bottomPx);
    }

    /**
     * 得到ImageTextView中的TextView控件
     * 
     * @return
     */
    public TextView getTextView() {
        return textView;
    }

    /**
     * 得到TextView的文字
     * 
     * @return
     */
    public String getText() {
        return textView.getText().toString();
    }

    /**
     * 设置TextView单行显示
     */
    public void setSingleLine() {
        textView.setSingleLine();
    }


注意:这里用到了dip转成px的转换工具类MetricUtil,附录中有。

4.附录:

4.1 MainActivity.java

[code]package com.example.imagetextview;

import android.app.Activity;
import android.app.ActionBar;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.LinearLayout.LayoutParams;
import android.os.Build;

public class MainActivity extends Activity {
    private LinearLayout itv_ll;
    private ImageTextView itv_home;
    private ImageTextView itv_shopping;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        itv_home = (ImageTextView)findViewById(R.id.main_home);
        itv_shopping =  (ImageTextView)findViewById(R.id.main_shopping);

        /**-------通过xml布局使用ImageTextView----------**/
        //主页图片和文字垂直显示,右上显示提示红点
        itv_home.setRenewalImgVisible(true);

        //购物车图片和文字水平显示,右上显示数量
        itv_shopping.setRenewalITvVisible(true);
        itv_shopping.setRenewalTv("8");

        itv_ll = (LinearLayout)findViewById(R.id.itv_ll);   //包裹ImageTextView的线性布局
        /**-------通过代码创建ImageView视图使用ImageTextView---------**/
        //历史记录图片和文字垂直显示,并右上显示提示红点
        ImageTextView itv_history = new ImageTextView(MainActivity.this, true);
        itv_history.setImageResource(R.drawable.icon_bm_home_history_nor);
        itv_history.setTextView("历史记录");
        itv_history.setRenewalImgVisible(true);
        itv_ll.addView(itv_history);

        //个人中心图片和文字水平显示,并右上显示提示数量
        ImageTextView itv_user = new ImageTextView(MainActivity.this, false);
        itv_user.setImageResource(R.drawable.icon_bm_home_user_nor);
        itv_user.setTextView("个人中心");
        itv_user.setRenewalITvVisible(true);
        itv_user.setRenewalTv("8");
        itv_ll.addView(itv_user);

    }

}


4.2 activity_main.xml

[code]<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:id="@+id/itv_ll"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center"
        android:orientation="horizontal" >
        <com.example.imagetextview.ImageTextView
            android:id="@+id/main_home"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:src="@drawable/icon_bm_home_home_nor"
            android:text="首页"

            android:textColor="#000000" />
        <com.example.imagetextview.ImageTextView
            android:id="@+id/main_shopping"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:orientation="horizontal"
            android:src="@drawable/icon_bm_home_shopping_nor"
            android:text="购物车"
            android:textColor="#000000" />
    </LinearLayout>

</LinearLayout>


4.3 ImageTextView.java

[code]package com.example.imagetextview;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

/**
 * 自定义图文控件 Created by josan_tang on 2015/12/20.
 */
public class ImageTextView extends LinearLayout {
    private Context context;
    private LinearLayout lL_content;    //包裹图片和标题文字的线性布局,用于改变布局方向
    private ImageView imageView; // 图片
    private TextView textView; // 标题文字
    private ImageView renewalImg; // 更新图片 (eg:通知提示) 注:更新图片和更新文字,只能二选一
    private TextView renewalTv; // 更新内容 (eg:购物车右上的数字)
    private @android.support.annotation.IdRes
    int IMAGEVIEW_ID = 1; // 图片的id,用于与右边的图片绑定

    /**
     * ImageView构造方法,用于在Java代码里创建ImageTextView对象
     * 
     * @param context
     *            上下文
     * @param vertical
     *            LinearLayout是否为垂直方向布局 true-垂直;false-水平
     */
    public ImageTextView(Context context, boolean vertical) {
        super(context);
        this.context = context;
        if (vertical) {
            setOrientation(LinearLayout.VERTICAL);
        } else {
            setOrientation(LinearLayout.HORIZONTAL);
        }
        // 设置权重
        setGravity(Gravity.CENTER);
        // 创建相对布局,用于包裹图片和图片右上冒泡图片
        RelativeLayout relativeLayout = new RelativeLayout(context);
        this.addView(relativeLayout);
        // 图片
        imageView = new ImageView(context);
        RelativeLayout.LayoutParams imageLP = new RelativeLayout.LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        imageLP.addRule(RelativeLayout.CENTER_IN_PARENT);
        imageView.setLayoutParams(imageLP);
        imageView.setId(IMAGEVIEW_ID); // 为renewalImg绑定在其
        relativeLayout.addView(imageView);
        // 右上图片
        renewalImg = new ImageView(context);
        RelativeLayout.LayoutParams renewalImgLP = new RelativeLayout.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        renewalImgLP.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        renewalImgLP.addRule(RelativeLayout.RIGHT_OF, IMAGEVIEW_ID); // 把该图片绑定在id为1的右边
        renewalImg.setLayoutParams(renewalImgLP);
        renewalImg.setBackgroundResource(R.drawable.icon_dot);
        renewalImg.setVisibility(View.GONE); // 默认为隐藏
        relativeLayout.addView(renewalImg);
        // 右上文字
        renewalTv = new TextView(context);
        RelativeLayout.LayoutParams renewalTvLP = new RelativeLayout.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        renewalTvLP.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        renewalTvLP.addRule(RelativeLayout.RIGHT_OF, IMAGEVIEW_ID); // 把该图片绑定在id为1的右边
        renewalTv.setLayoutParams(renewalTvLP);
        renewalTv.setBackgroundResource(R.drawable.icon_dot10);
        renewalTv.setVisibility(View.GONE); // 默认为隐藏
        renewalTv.setGravity(Gravity.CENTER);
        renewalTv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 8);
        renewalTv.setTextColor(Color.WHITE);
        relativeLayout.addView(renewalTv);
        // 文字
        textView = new TextView(context);
        textView.setGravity(Gravity.CENTER);
        textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12);
        this.addView(textView); // 把textView加到ImageTextView里面,即加到图片和右边图片包裹起来的相对布局的右边或者下面
    }

    /**
     * 构造方法:用于在布局xml里面引用ImageTextView
     * 
     * @param context
     * @param attrs
     */
    public ImageTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        View view = LayoutInflater.from(context).inflate(
                R.layout.imagetextview, this, true);
        lL_content = (LinearLayout) view.findViewById(R.id.lL_content);
        imageView = (ImageView) view.findViewById(R.id.image);
        renewalImg = (ImageView) view.findViewById(R.id.renewalImg);
        renewalTv = (TextView) view.findViewById(R.id.renewalTv);
        textView = (TextView) view.findViewById(R.id.text);

        // 如果xml中的ImageViewText控件中的属性不为空,则取出其属性,并赋值到相应控件上
        if (attrs != null) {
            TypedArray typedArray = context.obtainStyledAttributes(attrs,
                    R.styleable.ImageTextView);
            //方向 0-水平;1-垂直。默认为1
            int orientation = typedArray.getInt(R.styleable.ImageTextView_android_orientation, 1);
            if(orientation == LinearLayout.HORIZONTAL) {    //水平布局
                lL_content.setOrientation(LinearLayout.HORIZONTAL);

            } else {    //垂直
                lL_content.setOrientation(LinearLayout.VERTICAL);
            }
            // textview内容
            CharSequence text = typedArray
                    .getText(R.styleable.ImageTextView_android_text);
            if (text != null) {
                textView.setText(text);
            }
            // textview字体颜色
            ColorStateList color = typedArray.getColorStateList(0);
            if (color != null) {
                textView.setTextColor(color);
            }
            // textview字体大小
            float testSize = typedArray.getFloat(
                    R.styleable.ImageTextView_android_textSize, 12);
            if (testSize != 0) {
                textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, testSize);
            }
            // imageview的图片资源
            Drawable drawable = typedArray
                    .getDrawable(R.styleable.ImageTextView_android_src);
            if (drawable != null) {
                imageView.setImageDrawable(drawable);
            }
            // imageview背景
            Drawable drawableBg = typedArray
                    .getDrawable(R.styleable.ImageTextView_android_background);
            if (drawableBg != null) {
                imageView.setBackgroundDrawable(drawableBg);
            }
            // 保持以后使用属性的一致性
            typedArray.recycle();
        }
        // 对ImageTextView触摸事件的监听
        this.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    imageView.setPressed(true);
                    textView.setPressed(true);
                } else if (event.getAction() == MotionEvent.ACTION_CANCEL
                        || event.getAction() == MotionEvent.ACTION_UP) {
                    imageView.setPressed(false);
                    textView.setPressed(false);
                }
                return false;
            }
        });
    }

    /**
     * 传递Drawable对象设置ImageView图片资源
     * 
     * @param drawable
     */
    public void setImageDrawable(Drawable drawable) {
        if (drawable != null) {
            imageView.setImageDrawable(drawable);
        }
    }

    /**
     * 传递ResourceId来设置ImageView的图片资源
     * 
     * @param resId
     */
    public void setImageResource(int resId) {
        imageView.setImageResource(resId);
    }

    /**
     * 传递Bitmap对象设置ImageView的图片资源
     * 
     * @param bitmap
     */
    public void setImageBitmap(Bitmap bitmap) {
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap);
        }
    }

    /**
     * 得到ImageTextView中的ImageView对象
     * 
     * @return
     */
    public ImageView getImageView() {
        return imageView;
    }

    /**
     * 得到ImageView的图片资源
     * 
     * @return Drawable对象
     */
    public Drawable getDrawable() {
        return imageView.getDrawable();
    }

    /**
     * 得到ImageView的背景图片
     * 
     * @return Drawable对象
     */
    public Drawable getBackground() {
        return imageView.getBackground();
    }

    /**
     * 显示ImageView控件
     */
    public void showImageView() {
        if (imageView.getVisibility() != View.VISIBLE) {
            imageView.setVisibility(View.VISIBLE);
        }
    }

    /**
     * 隐藏ImageView控件
     */
    public void hideImageView() {
        if (imageView.getVisibility() != View.GONE) {
            imageView.setVisibility(View.GONE);
        }
    }

    /**
     * 传递Drawable对象设置ImageView的背景图片
     * 
     * @param drawable
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    public void setBackgroundDrawable(Drawable drawable) {
        if (drawable != null) {
            imageView.setBackground(drawable);
        }
    }

    /**
     * 传递ResourceId设置ImageView的背景图片
     * 
     * @param resId
     */
    public void setBackgroundResource(int resId) {
        imageView.setBackgroundResource(resId);
    }

    /**
     * 设置右上图标是否可见
     * 
     * @param visible
     *            右上图标是否可见:true-可见;false-隐藏
     */
    public void setRenewalImgVisible(boolean visible) {
        if (visible) {
            if (renewalImg.getVisibility() != View.VISIBLE) {
                renewalImg.setVisibility(View.VISIBLE);
            }
        } else {
            if (renewalImg.getVisibility() != View.GONE) {
                renewalImg.setVisibility(View.GONE);
            }
        }
    }

    /**
     * 设置右上文字内容
     * 
     * @param text
     */
    public void setRenewalTv(String text) {
        if (text != null) {
            renewalTv.setText(text);
        }
    }

    /**
     * 得到右上TextView控件
     * 
     * @return
     */
    public TextView getRenewalTextView() {
        return renewalTv;
    }

    /**
     * 得到右上文字内容
     * 
     * @return
     */
    public String getRenewalTv() {
        return renewalTv.getText().toString();
    }

    /**
     * 设置TextView的文字
     * 
     * @param text
     */
    public void setTextView(String text) {
        if (text != null) {
            textView.setText(text);
        }
    }

    /**
     * 设置右上文字是否可见
     * 
     * @param visible
     *            右上图标是否可见:true-可见;false-隐藏
     */
    public void setRenewalITvVisible(boolean visible) {
        if (visible) {
            if (renewalTv.getVisibility() != View.VISIBLE) {
                renewalTv.setVisibility(View.VISIBLE);
            }
        } else {
            if (renewalTv.getVisibility() != View.GONE) {
                renewalTv.setVisibility(View.GONE);
            }
        }
    }

    /**
     * 设置TextView的文字大小,默认单位为dip
     * 
     * @param size
     *            文字大小
     */
    public void setTestSize(float size) {
        textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
    }

    /**
     * 带单位类型设置TextView的文字大小,默认单位为dip
     * 
     * @param size
     *            文字大小
     * @param unitType
     *            单位类型,为TypedValue中的常量。eg:dip->TypedValue.COMPLEX_UNIT_DIP
     */
    public void setTestSize(float size, int unitType) {
        textView.setTextSize(unitType, size);
    }

    /**
     * 设置TextView文字颜色
     * 
     * @param color
     */
    public void setTextColor(int color) {
        textView.setTextColor(color);
    }

    /**
     * 设置TextView的Padding
     * 
     * @param leftDip
     * @param topDip
     * @param rightDip
     * @param bottomDip
     */
    public void setTextPadding(int leftDip, int topDip, int rightDip,
            int bottomDip) {
        int leftPx = MetricUtil.dip2px(context, leftDip);
        int topPx = MetricUtil.dip2px(context, topDip);
        int rightPx = MetricUtil.dip2px(context, rightDip);
        int bottomPx = MetricUtil.dip2px(context, bottomDip);
        textView.setPadding(leftPx, topPx, rightPx, bottomPx);
    }

    /**
     * 得到ImageTextView中的TextView控件
     * 
     * @return
     */
    public TextView getTextView() {
        return textView;
    }

    /**
     * 得到TextView的文字
     * 
     * @return
     */
    public String getText() {
        return textView.getText().toString();
    }

    /**
     * 设置TextView单行显示
     */
    public void setSingleLine() {
        textView.setSingleLine();
    }
}


4.4 imagetextview.xml

[code]<LinearLayout
    android:id="@+id/imagetextview_layout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="vertical">
    <LinearLayout
        android:id="@+id/lL_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="vertical">
        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
            <ImageView
                android:id="@+id/image"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true" />
            <ImageView
                android:id="@+id/renewalImg"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentTop="true"
                android:layout_toRightOf="@id/image"
                android:background="@drawable/icon_dot"
                android:visibility="gone"/>

            <TextView
                android:id="@+id/renewalTv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:layout_alignParentTop="true"
                android:layout_toRightOf="@id/image"
                android:background="@drawable/icon_dot10"
                android:textColor="#ffffff"
                android:visibility="gone"/>
        </RelativeLayout>
        <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="8dp"/>
    </LinearLayout>
</LinearLayout>


4.5 MetricUtil.java

[code]package com.example.imagetextview;

import android.content.Context;
import android.util.DisplayMetrics;

/**
 * 度量工具类,支持获取屏幕宽高、状态栏高度,px/dip等换算功能
 * Created by josan_tang on 2015/12/20.
 */
public class MetricUtil {

    /**
     * 根据手机的分辨率从dip单位转成px(像素)
     * @param context
     * @param dipValue
     * @return
     */
    public static int dip2px(Context context, float dipValue) {
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
        float scale = displayMetrics.density;
        return (int) (dipValue * scale +0.5f);
    }

    /**
     * 根据手机分辨率从px(像素)转成dp
     * @param context
     * @param pxValue
     * @return
     */
    public static int px2dip(Context context, float pxValue) {
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
        float scale = displayMetrics.density;
        return (int) (pxValue / scale + 0.5f);
    }
}


总结: 代码很简单,注释很详细,有Bug或需要完善的地方,欢迎留言,菜鸟修炼-ing.

源码下载:ImageTextView

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: