自定义图文控件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:
这里右上的小控件用到了drawable文件下的icon_dot.xml和icon_dot10.xml作为背景资源,就是右上小红点.代码如下:
icon_dot.xml:
icon_dot10.xml:
1.2 然后在需要使用图文控件的activity_main.xml布局中引用ImageTextView
在ImageTextView中使用了一些自定义的属性,需要在drawable文件下的attrs.xml中设置自定义属性,以便在ImageTextView中的构造方法里获得属性值。
1.3 下面来看ImageTextView中使用xml引用时调用的构造方法,主要是获取xml中的属性,并设置到控件上。
1.4 然后在MainActivity.java中像普通控件一样去得到ImageTextView,并使用它就可以了。
2.2 然后在MainActivity.java中使用它
下面是效果图:
注意:这里用到了dip转成px的转换工具类MetricUtil,附录中有。
4.2 activity_main.xml
4.3 ImageTextView.java
4.4 imagetextview.xml
4.5 MetricUtil.java
在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
相关文章推荐
- 给班里同学布置的一道题目……虽然做的人并不算多。
- 响应式布局(三更)
- 12.未公开的Oracle数据库秘密笔记——10046事件和扩展SQL跟踪
- Android 支付宝和微信支付集成
- Unique Paths
- 2015/12/22:指针-函数-数组随笔
- 2015/12/22:指针-函数-数组随笔
- 2015/12/22:指针-函数-数组随笔
- POJ1026 Cipher
- (九十四)函数和二维数组
- Mac 安装 Redis
- 查找qt生成的exe软件需要的动态库.以及打包
- 现实中的IO和带宽
- toolbar easyui
- !!的使用
- git 常用操作一览图
- 多态与虚函数编程题 #2(C++程序设计第6周)
- 再议Swift操作符重载
- Winform自定义无边框窗体
- js 猜数字游戏