`
lovehong0306
  • 浏览: 12187 次
  • 性别: Icon_minigender_1
  • 来自: 石家庄
社区版块
存档分类
最新评论

自定义图文并茂的Button

阅读更多

文章出处:http://gundumw100.iteye.com/blog/689615

 

anroid内置了Button和ImageButton,但是没有提供既能显示图片又能显示文字的button。 
这里我自定义了一个ImageTextButton 
其中了XML文件中使用了自定义属性custom:icon="@drawable/icon" 
下面是ImageTextButton源码: 

 

import android.content.Context;  
import android.graphics.Bitmap;  
import android.graphics.BitmapFactory;  
import android.graphics.Canvas;  
import android.util.AttributeSet;  
import android.widget.Button;  
  
public class ImageTextButton extends Button {  
    private final String namespace =  "http://www.iteye.com/custom";  
    private int resourceId =0;  
    private Bitmap bitmap;  
    public ImageTextButton(Context context, AttributeSet attrs) {  
        super(context, attrs);  
        // TODO Auto-generated constructor stub  
        setClickable(true);  
        //默认使用R.drawable.icon这张图片  
        resourceId = attrs.getAttributeResourceValue(namespace, "icon", R.drawable.icon);  
        bitmap = BitmapFactory.decodeResource(getResources(), resourceId);  
    }  
    @Override  
    protected void onDraw(Canvas canvas) {  
        // TODO Auto-generated method stub  
        //图片顶部居中显示  
        int x=(this.getMeasuredWidth()-bitmap.getWidth())>>1;  
        int y=0;  
        canvas.drawBitmap(bitmap, x, y, null);   
        //坐标需要转换,因为默认情况下Button中的文字居中显示  
        //这里需要让文字在底部显示  
        canvas.translate(0, (this.getMeasuredHeight()>>1)-(int)this.getTextSize());  
          
        super.onDraw(canvas);  
    }  
  
    public void setIcon(Bitmap bitmap){  
        this.bitmap=bitmap;  
                invalidate();  
    }  
    public void setIcon(int resourceId){  
        this.bitmap=BitmapFactory.decodeResource(getResources(), resourceId);  
                invalidate();  
    }  
}  

 

 

<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:custom="http://www.iteye.com/custom"  
    android:orientation="vertical"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent"  
    >  
  
    <com.wt.app.ImageTextButton   
    android:text="OK"  
    custom:icon="@drawable/icon"  
    android:id="@+id/button_0"   
    android:layout_width="80dip"   
    android:layout_height="80dip"  
    />  
    <com.wt.app.ImageTextButton   
    android:text="OK"  
    custom:icon="@drawable/icon"  
    android:id="@+id/button_1"   
    android:layout_width="80dip"   
    android:layout_height="100dip"  
    android:textSize="30dip"  
    android:textColor="#ff0000"  
    />  
      
    <com.wt.app.ImageTextButton   
    android:text="OK"  
    custom:icon="@drawable/icon"  
    android:id="@+id/button_2"   
    android:layout_width="200dip"   
    android:layout_height="200dip"  
    android:textSize="30dip"  
    />  
     
</LinearLayout>

 


 


另一种实现: 

 

import android.content.Context;  
import android.graphics.Bitmap;  
import android.graphics.BitmapFactory;  
import android.graphics.Canvas;  
import android.graphics.Color;  
import android.graphics.Paint;  
import android.graphics.Rect;  
import android.view.MotionEvent;  
import android.view.View;  
   
public class ImageTextButton extends View{  
   
private final static int WIDTH_PADDING = 8;  
private final static int HEIGHT_PADDING = 10;  
private final static int SPACE = 10;  
private final String label;  
private final int imageResId;  
private final Bitmap image;  
private int fontWidth;  
private int fontHeight;  
   
public ImageTextButton(final Context c,int rid,String text){  
super(c);  
this.label = text;  
this.imageResId = rid;  
this.image = BitmapFactory.decodeResource(c.getResources(),imageResId);  
setFocusable(true);  
setClickable(true);  
getFontWidthAndHeight();  
}  
   
private void getFontWidthAndHeight(){  
Paint pFont = new Paint();   
Rect rect = new Rect();   
pFont.getTextBounds("信 ", 0, 1, rect);   
this.fontHeight = rect.height();  
this.fontWidth = rect.width();  
}  
   
private int getTextWidth(String text){  
return text.length()*this.fontWidth;  
}  
   
@Override  
protected void onFocusChanged(boolean gainFocus, int direction,  
Rect previouslyFocusedRect) {  
if (gainFocus == true){  
this.setBackgroundColor(Color.rgb(255, 165, 0));  
}  
else{  
this.setBackgroundColor(Color.alpha(0));  
}  
}  
   
@Override  
protected void onDraw(Canvas canvas) {  
Paint textPaint = new Paint();  
textPaint.setColor(Color.WHITE);  
canvas.drawBitmap(image, WIDTH_PADDING / 2, HEIGHT_PADDING / 2, null);  
canvas.drawText(label, (image.getWidth()-getTextWidth(label)/2)/ 2, (HEIGHT_PADDING / 2) +  
image.getHeight() + 8+SPACE, textPaint);  
}  
   
@Override  
public boolean onTouchEvent(MotionEvent event) {  
int action = event.getAction();  
switch(action){  
case MotionEvent.ACTION_DOWN:  
case MotionEvent.ACTION_MOVE:  
this.setBackgroundColor(Color.rgb(255, 165, 0));  
break;  
case MotionEvent.ACTION_UP:  
case MotionEvent.ACTION_CANCEL:  
this.setBackgroundColor(Color.alpha(0));  
break;  
}  
   
return super.onTouchEvent(event);  
}  
   
@Override  
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
setMeasuredDimension(measureWidth(widthMeasureSpec),measureHeight(heightMeasureSpec));  
}  
   
private int measureWidth(int measureSpec){  
int preferred = image.getWidth() * 2;  
return getMeasurement(measureSpec, preferred);  
}  
private int measureHeight(int measureSpec){  
   int preferred = image.getHeight()+this.fontHeight+SPACE*2;  
   return getMeasurement(measureSpec, preferred);  
}  
   
private int getMeasurement(int measureSpec, int preferred){  
  int specSize = MeasureSpec.getSize(measureSpec);  
int measurement = 0;  
switch(MeasureSpec.getMode(measureSpec)){  
case MeasureSpec.EXACTLY:  
measurement = specSize;  
break;  
case MeasureSpec.AT_MOST:  
measurement = Math.min(preferred, specSize);  
break;  
default:  
measurement = preferred;  
break;  
}  
return measurement;  
}  
   
public String getLabel(){  
return label;  
}    
   
public int getImageResId(){  
return imageResId;  
}  
   
}  

 


说说Android 两种为自定义组件添加属性的使用方法和区别 
http://terryblog.blog.51cto.com/1764499/414884 

Android高手进阶教程(四)之----Android 中自定义属性(attr.xml,TypedArray)的使用! 
http://blog.csdn.net/Android_Tutor/archive/2010/04/20/5508615.aspx 

linearlayout继承扩展篇 
http://wang-peng1.iteye.com/blog/576151 

另一篇:编写Android自定义按钮 
http://marshal.easymorse.com/archives/3059 

 
实现按钮,这里没有通过Button类或者子类去做派生,而是通过TextView派生出来的。在这里三个按钮是三个TextView派生类实例,中间的白线,是1px宽的白色矩形,这样就可以做出类似上面的效果。 
看布局文件: 

 

<?xml version="1.0" encoding="utf-8"?>   
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"   
    android:orientation="vertical" android:layout_width="fill_parent"  
    android:layout_height="fill_parent" android:background="@drawable/background_color">   
    <LinearLayout android:layout_width="fill_parent"   
        android:layout_height="10dip" />   
    <LinearLayout android:layout_width="fill_parent"   
        android:layout_height="40dip">   
        <com.easymorse.textbutton.TextButton   
            android:layout_width="fill_parent" android:layout_height="fill_parent"   
            android:layout_weight="1" android:text="电影"   
            android:gravity="center_vertical|center_horizontal"   
            android:background="@drawable/button" android:focusable="true" android:clickable="true"/>   
        <View android:layout_width="2px" android:layout_height="fill_parent"   
            android:background="#ffffffff" />   
        <com.easymorse.textbutton.TextButton   
            android:layout_width="fill_parent" android:layout_height="fill_parent" android:clickable="true"   
            android:layout_weight="1" android:text="电视"   
            android:gravity="center_vertical|center_horizontal"   
            android:background="@drawable/button" android:focusable="true" />   
        <View android:layout_width="2px" android:layout_height="fill_parent"   
            android:background="#ffffffff" />   
        <com.easymorse.textbutton.TextButton   
            android:layout_width="fill_parent" android:layout_height="fill_parent" android:clickable="true"   
            android:layout_weight="1" android:text="明星"   
            android:gravity="center_vertical|center_horizontal"   
            android:background="@drawable/button" android:focusable="true" />   
    </LinearLayout>   
</LinearLayout>  

 

这里需要注意的几点: 

对于布局的像素设置,一般要用dip,这样在更大或者更小的屏幕下展示可以自动适配,如果是px,是物理像素,这样在小的屏幕里面可能会显得大,在大的屏幕中显得小 
在按钮布局中要使用android:focusable="true" android:clickable="true",这样才能比如通过轨迹球聚焦到按钮上,才能用手触摸按钮的时候触发事件 
点击按钮变色,主要在android:background="@drawable/button"配置,button配置了点击事件发生后的背景色改变,而不需要编写代码 
下面来看看drawable/button.xml文件: 

 

<?xml version="1.0" encoding="utf-8"?>   
<selector xmlns:android="http://schemas.android.com/apk/res/android"   
    android:constantSize="true">   
    <item android:state_focused="true">   
        <shape>   
            <gradient android:startColor="#FFE5CF33" android:endColor="#FFF1E7A2"   
                android:angle="90.0">   
            </gradient>   
        </shape>   
    </item>   
    <item android:state_enabled="true" android:state_pressed="false">   
        <shape>   
            <gradient android:startColor="#FF1B1B1B" android:endColor="#FF969696"   
                android:angle="90.0">   
            </gradient>   
        </shape>   
    </item>   
    <item android:state_enabled="true" android:state_pressed="true">   
        <shape>   
            <gradient android:startColor="#FF000000" android:endColor="#FF474747"   
                android:angle="90.0">   
            </gradient>   
        </shape>   
    </item>   
    <item android:state_enabled="false" android:state_pressed="true">   
        <shape>   
            <gradient android:startColor="#FF000000" android:endColor="#FF474747"   
                android:angle="90.0">   
            </gradient>   
        </shape>   
    </item>   
    <item>   
        <shape>   
            <gradient android:startColor="#FF000000" android:endColor="#FF474747"   
                android:angle="90.0">   
            </gradient>   
        </shape>   
    </item>   
</selector>  

 

这个文件中定义了当条目(也就是按钮)enable和(或)pressed的情况下的背景渐近色的配置情况。 

实际上,上面介绍的部分,在不使用自定义按钮(也就是不是<com.easymorse.textbutton.TextButton而直接写<TextView…)的情况下,已经可以出现除了点击后Toast消息。 
说一下TextView的派生类,其实只是在touche按钮的时候显示提示信息: 

 

import android.content.Context;   
import android.util.AttributeSet;   
import android.view.MotionEvent;   
import android.view.View;   
import android.widget.TextView;   
import android.widget.Toast;  
  
public class TextButton extends TextView {  
  
    public TextButton(Context context) {   
        super(context);   
    }  
  
    public TextButton(Context context, AttributeSet attrs, int defStyle) {   
        super(context, attrs, defStyle);   
    }  
  
    public TextButton(final Context context, AttributeSet attrs) {   
        this(context, attrs, 0);  
  
        this.setOnTouchListener(new OnTouchListener() {  
  
            @Override   
            public boolean onTouch(View v, MotionEvent event) {   
                if (event.getAction() == MotionEvent.ACTION_CANCEL   
                        || event.getAction() == MotionEvent.ACTION_UP   
                        || event.getAction() == MotionEvent.ACTION_OUTSIDE) {   
                    Toast.makeText(context, "touched", Toast.LENGTH_SHORT).show();   
                }   
                return false;   
            }   
        });   
    }  
  
}  

 在这里主要是写了设置OnTouchListener的代码。 


这里只针对3种情况才显示提示: 

当手指从按钮抬起,ACTION_UP 
取消,ACTION_CANCEL 
手指移出按钮,ACTION_OUTSIDE 
另外,要返回false,因为返回true,系统将不会调用drawable/button.xml的效果,因为true表示自己已经处理了onTouche事件,不需要别的逻辑再处理了。 
源代码见:http://easymorse.googlecode.com/svn/tags/textButton-0.1.0/ 

 

分享到:
评论

相关推荐

    自定义Button

    在这个例子中,我们继承LinearLayout,而不是直接继承Button,这是因为LinearLayout允许我们更自由地布局子视图,例如结合ImageView和TextView,实现图文并茂的按钮。 1. **创建自定义View类** 首先,我们需要创建...

    按钮Button控件 高级界面制作技巧

    例如,可以将按钮背景设为一张图片,然后在上面叠加文本,形成图文并茂的效果。`扩展圆形按钮.gif`和`圆形按钮.gif`展示了这种设计,它们利用图形元素增加了视觉吸引力。 2. **非矩形按钮**:默认的按钮形状通常是...

    Vue组件之自定义事件的功能图解

    在本文中,我们将通过图文并茂的形式来介绍Vue组件之自定义事件的功能和使用方法。 一、项目初始化 在开始使用Vue组件自定义事件之前,我们需要初始化一个Vue项目。我们可以使用Webpack来初始化项目,命令如下: ...

    Android应用源码之6.DDMS视图和Button-IT计算机-毕业设计.zip

    5. 自定义样式:通过自定义主题或创建Drawable资源,可以改变Button的背景、角部半径、文字颜色等外观。 6. 事件传递:Button作为View的一部分,参与到触摸事件的分发机制,理解ViewGroup的onInterceptTouchEvent()...

    Android中实现图文并茂的按钮实例代码

    在Android开发中,创建图文并茂的按钮可以使用户界面更加美观、直观,提高用户体验。本文将详细介绍如何在Android中实现这种功能,通过一个简单的实例代码来展示如何将图像与文字结合到一个按钮上。 首先,我们需要...

    Android应用源码仿iPhone风格对话框示例,Jar包及源码.zip

    在Android中,可以使用`ImageView`和`TextView`组合,或者直接使用自定义的`Button`来实现图文并茂的按钮。 5. **弹出位置**:iPhone对话框通常从底部弹出,而在Android中,我们可以使用`DialogFragment`的`show()`...

    CButtonST的使用

    2. **图文并茂**:可以同时显示图标和文本,图标可以是位图或PNG格式,支持透明效果。 3. **状态变化**:支持按钮的正常、按下、悬浮、禁用等多种状态,每种状态下的外观都可以自定义。 4. **自定义颜色**:开发...

    按钮 多选按钮 窗体 的外观美化

    2. **图文并茂**:与按钮类似,CheckBox也可以添加图标,通过`CheckBox.CheckMark`和`CheckBox.Text`属性组合使用。 3. **状态变化反馈**:当CheckBox的状态改变时,可以有动画或颜色变化作为反馈,利用`...

    CButtonST_demo.rar_DEMO_图文按钮

    `CButtonST`类通过重写`OnPaint()`方法,实现了按钮的自定义绘制,可以设置按钮的背景色、边框样式、文字颜色、图片位置等,提供了高度的可定制性。 `CButtonST`的使用通常包括以下几个步骤: 1. **头文件引用**:...

    一个很不错的vb界面制作示例,小巧实用,

    5. 自定义控件:如果有自定义的控件,学习其背后的实现逻辑。 6. 响应式设计:检查界面是否适应不同的屏幕尺寸和分辨率。 总的来说,这个VB界面制作示例是一个很好的学习资源,可以帮助你理解如何使用VB创建具有...

    Delphi源码支持图片文字混排的jvrichedit..rar

    这在创建报告、文档编辑器或者任何形式需要图文并茂的应用程序时非常有用。以下是一些关于如何利用`jvRichEdit`实现图片文字混排的关键知识点: 1. **安装和使用**:首先,你需要将JVCL库添加到你的Delphi项目中。...

    强大的按钮类CButtonST实例演示和详解(附源码)

    CButtonST(Style-able Button)是一个第三方库,由程序员开发以扩展标准的CButton类的功能。它支持多种视觉样式,包括自定义颜色、边框样式、文字对齐方式、图片显示以及鼠标悬停、按下状态下的改变等。这些特性...

    Android开发教程&笔记

    这份教程结合了图文并茂的方式,使得学习过程更为直观和易懂,对于那些希望通过实践来提升理解力的开发者尤其适用。 在Android开发的世界里,了解基本的Java编程语言是必要的起点,因为Android应用主要基于Java或...

    flex+css安全手册

    这份手册通过图文并茂的方式,清晰地展示了各种使用技巧和案例,使得学习过程更为直观易懂。 在Flex中,CSS(Cascading Style Sheets)是用于控制组件外观和布局的关键工具。以下是手册中涵盖的一些核心知识点: 1...

    史上最经典的VB教程(PPT格式)

    PPT教程的优势在于其图文并茂,内容呈现清晰,逻辑结构易于理解。相比视频教程,PPT可以让人自主控制学习进度,随时查阅和回顾关键知识点,而不会因为视频的连续性而被打断。对于那些喜欢通过阅读和笔记来学习的人来...

    VB学习资料(ppt)

    5. **控件使用**:VB提供了丰富的用户界面控件,如Label、TextBox、Button、ListBox等,讲解如何在窗体上添加、布局控件,并通过属性、方法和事件来实现交互功能。 6. **事件驱动编程**:VB的核心特性之一是事件...

    CBUTTONST.rar_CButtonST

    CButtonST的全称可能是"Customized Button with Stylish Text",它提供了丰富的自定义选项,无需开发者进行复杂的代码修改,只需简单集成就能使按钮展现出独特的视觉效果。 CButtonST的特点在于其图文并茂的设计,...

    易学的初级VB ppt教程

    在VB教学中,PPT可以作为辅助工具,将复杂的编程概念以图文并茂的方式呈现,使学习过程更生动有趣。本教程通过PPT的形式,旨在以清晰明了的方式传授VB的基础知识。 【VB基础知识】 1. **界面设计**:VB提供可视化的...

    CButtonST和CMenu类

    CButtonST,全称“Styled Button”,是一个扩展的按钮类,它为标准的CButton类提供了更多的样式和功能。这个类的主要目标是提供一个更加灵活、易于定制的按钮控件,使得开发者能够轻松地创建具有不同外观和行为的...

Global site tag (gtag.js) - Google Analytics