Android 之自定义组件
1、如何在一个按钮上放上一张图片?
把按钮和图片套在一个FrameLayout中
<!-- 必须将button和ImageView分别嵌套在两个LinearLayout中才能 实现将图片放在按钮上 -->
<FrameLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
style="@style/menu_btn_style"
android:id="@+id/fan_us"
android:text="@string/mainmenu_facebook_fan_us" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginTop="13dp"
android:src="@drawable/facebookicon" />
</LinearLayout>
</FrameLayout>
2、如何自定义组件
自定义一个下划线形式的输入框
第一:确定要画多少条下划线
第二:每条线的宽度
第三:下划线的间距
(1)自定义文本输入框
package com.heima.guesswho.util;
import com.heima.android.guesswho.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.widget.EditText;
public class DashlineEditText extends EditText {
/*
* 假设下划线总长100个单位,要画7条下划线,每条下划线间距为2个单位
* 具体算法如下:
* 每条下划线的长度:(100+2)/7-2
* for(int i = 0;i<7,i++){
* 第i条线
* x1 = ((100+2)/7)*i
* y1 = getHeight()
* x2 = ((100+2)/7)*i+(100+2)/7-2
* y2 = getHeight()
* }
*
*/
private Paint linePaint = new Paint();
private int segmentCount = 8;//总共画8条分割线,可以作为默认值
private int distance = 5;//每个分割线的间距为4个单位,可以作为默认值
/*
* 从布局文件中得到对应属性的值
*/
public DashlineEditText(Context context, AttributeSet attrs) {
super(context, attrs);
setBackgroundDrawable(null);//消除文本框效果的作用
//linePaint.setColor(Color.RED);//设置画笔的颜色
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.DashLineET);
segmentCount = array.getInt(R.styleable.DashLineET_segment_count, segmentCount);//从指定属性中拿到对应的值,若没设置,则用默认值
distance = array.getInt(R.styleable.DashLineET_distance, distance);
int color = array.getInt(R.styleable.DashLineET_dashline_color, Color.RED);
linePaint.setColor(color);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int width = getWidth();//自定义控件的宽度
int height = getHeight()-3;//必须减去数才能显示出下划线
//画出每一条下划线
for(int i = 0; i < segmentCount; i++){
int oneSegmentWidth = (width+distance)/segmentCount - distance;//每条下划线的长度
int startX = (segmentCount+distance)*i ;//每条下划线的起点位置
int stopX = startX+oneSegmentWidth ;//每条下划线的终点位置
canvas.drawLine(startX, height, stopX, height, linePaint);
}
}
}
(2)布局文件
<?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">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/debug_name" />
<com.heima.guesswho.util.DashlineEditText
android:layout_width="100dp"
android:layout_height="12dp"
android:text="test" />
</LinearLayout>
定义自定义组件的属性
第一步:在string.xml文件中配置declare-styleable
<!-- 定义DashLineEditText的属性 -->
<declare-styleable
name="DashLineET">
<attr
name="segments_cnt"
format="integer" />
<attr
name="distance"
format="dimension" />
<attr
name="dashline_color"
format="color" />
<attr
name="hint_msg"
format="reference" />
<attr
name="hint_color"
format="color" />
</declare-styleable>
第二步:在自定义组件中复写构造方法,用来获取布局文件中属性的值
/*
* 从布局文件中得到对应属性的值
*/
public DashlineEditText(Context context, AttributeSet attrs) {
super(context, attrs);
setBackgroundDrawable(null);//消除文本框效果的作用
//linePaint.setColor(Color.RED);//设置画笔的颜色
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.DashLineET);
segmentCount = array.getInt(R.styleable.DashLineET_segment_count, segmentCount);//从指定属性中拿到对应的值,若没设置,则用默认值
distance = array.getInt(R.styleable.DashLineET_distance, distance);
int color = array.getInt(R.styleable.DashLineET_dashline_color, Color.RED);
linePaint.setColor(color);
}
第三步:在使用自定义组件的布局文件中加入命名空间
如xmlns:heima="http://schemas.android.com/apk/res/com.heima.android.guesswho"
heima 为我们使用属性时使用的前缀,相当于使用Android属性时要使用android前缀一样
其中com.heima.android.guesswho,为清单文件标识应用的包名
布局文件如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:heima="http://schemas.android.com/apk/res/com.heima.android.guesswho"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/debug_name" />
<com.heima.guesswho.util.DashlineEditText
android:layout_width="100dp"
android:layout_height="12dp"
heima:segment_count="10"
heima:distance="3"
android:text="test" />
</LinearLayout>
<com.heima.guesswho.util.DashlineEditText
android:layout_width="210dip"
heima:segment_count="9"
heima:distance="4dip"
heima:dashline_color="@color/font_white"
android:layout_height="wrap_content"
android:textColor="#FF0000"
android:hint="@string/input_name_prompt"
android:text="" />