Android自定义View的实现方法,带你一步步深入了解View(四)

中学习过了。

下面我们准备来自定义一个计数器View,这个View可以响应用户的点击事件,并自动记录一共点击了多少次。新建一个CounterView继承自View,代码如下所示:

public class CounterView extends View implements OnClickListener {private Paint mPaint;private Rect mBounds;private int mCount;public CounterView(Context context, AttributeSet attrs) {super(context, attrs);mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mBounds = new Rect();setOnClickListener(this);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);mPaint.setColor(Color.BLUE);canvas.drawRect(0, 0, getWidth(), getHeight(), mPaint);mPaint.setColor(Color.YELLOW);mPaint.setTextSize(30);String text = String.valueOf(mCount);mPaint.getTextBounds(text, 0, text.length(), mBounds);float textWidth = mBounds.width();float textHeight = mBounds.height();canvas.drawText(text, getWidth() / 2 – textWidth / 2, getHeight() / 2+ textHeight / 2, mPaint);}@Overridepublic void onClick(View v) {mCount++;invalidate();}}可以看到,首先我们在CounterView的构造函数中初始化了一些数据,并给这个View的本身注册了点击事件,这样当CounterView被点击的时候,onClick()方法就会得到调用。而onClick()方法中的逻辑就更加简单了,只是对mCount这个计数器加1,然后调用invalidate()方法。通过 Android视图状态及重绘流程分析,带你一步步深入了解View(三)这篇文章的学习我们都已经知道,调用invalidate()方法会导致视图进行重绘,因此onDraw()方法在稍后就将会得到调用。

既然CounterView是一个自绘视图,那么最主要的逻辑当然就是写在onDraw()方法里的了,下面我们就来仔细看一下。这里首先是将Paint画笔设置为蓝色,然后调用Canvas的drawRect()方法绘制了一个矩形,这个矩形也就可以当作是CounterView的背景图吧。接着将画笔设置为黄色,准备在背景上面绘制当前的计数,注意这里先是调用了getTextBounds()方法来获取到文字的宽度和高度,然后调用了drawText()方法去进行绘制就可以了。

这样,一个自定义的View就已经完成了,并且目前这个CounterView是具备自动计数功能的。那么剩下的问题就是如何让这个View在界面上显示出来了,其实这也非常简单,我们只需要像使用普通的控件一样来使用CounterView就可以了。比如在布局文件中加入如下代码:

<RelativeLayout xmlns:android=""android:layout_width="match_parent"android:layout_height="match_parent" ><com.example.customview.CounterViewandroid:layout_width="100dp"android:layout_height="100dp"android:layout_centerInParent="true" /></RelativeLayout>可以看到,这里我们将CounterView放入了一个RelativeLayout中,然后可以像使用普通控件来给CounterView指定各种属性,比如通过layout_width和layout_height来指定CounterView的宽高,通过android:layout_centerInParent来指定它在布局里居中显示。只不过需要注意,自定义的View在使用的时候一定要写出完整的包名,不然系统将无法找到这个View。

好了,就是这么简单,接下来我们可以运行一下程序,并不停地点击CounterView,效果如下图所示。

怎么样?是不是感觉自定义View也并不是什么高级的技术,简单几行代码就可以实现了。当然了,这个CounterView功能非常简陋,只有一个计数功能,因此只需几行代码就足够了,当你需要绘制比较复杂的View时,还是需要很多技巧的。

二、组合控件

组合控件的意思就是,我们并不需要自己去绘制视图上显示的内容,而只是用系统原生的控件就好了,但我们可以将几个系统原生的控件组合到一起,这样创建出的控件就被称为组合控件。

举个例子来说,标题栏就是个很常见的组合控件,很多界面的头部都会放置一个标题栏,标题栏上会有个返回按钮和标题,点击按钮后就可以返回到上一个界面。那么下面我们就来尝试去实现这样一个标题栏控件。

新建一个title.xml布局文件,代码如下所示:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android=""android:layout_width="match_parent"android:layout_height="50dp"android:background="#ffcb05" ><Buttonandroid:id="@+id/button_left"android:layout_width="60dp"android:layout_height="40dp"android:layout_centerVertical="true"android:layout_marginLeft="5dp"android:background="@drawable/back_button"android:text="Back"android:textColor="#fff" /><TextViewandroid:id="@+id/title_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:text="This is Title"android:textColor="#fff"android:textSize="20sp" /></RelativeLayout>

在这个布局文件中,我们首先定义了一个RelativeLayout作为背景布局,然后在这个布局里定义了一个Button和一个TextView,Button就是标题栏中的返回按钮,TextView就是标题栏中的显示的文字。

接下来创建一个TitleView继承自FrameLayout,代码如下所示:

public class TitleView extends FrameLayout {private Button leftButton;private TextView titleText;public TitleView(Context context, AttributeSet attrs) {super(context, attrs);LayoutInflater.from(context).inflate(R.layout.title, this);titleText = (TextView) findViewById(R.id.title_text);leftButton = (Button) findViewById(R.id.button_left);leftButton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {((Activity) getContext()).finish();}});}public void setTitleText(String text) {titleText.setText(text);}public void setLeftButtonText(String text) {leftButton.setText(text);}public void setLeftButtonListener(OnClickListener l) {leftButton.setOnClickListener(l);}}TitleView中的代码非常简单,在TitleView的构建方法中,我们调用了LayoutInflater的inflate()方法来加载刚刚定义的title.xml布局,这部分内容我们已经在 Android LayoutInflater原理分析,带你一步步深入了解View(一)这篇文章中学习过了。

接下来调用findViewById()方法获取到了返回按钮的实例,然后在它的onClick事件中调用finish()方法来关闭当前的Activity,也就相当于实现返回功能了。

另外,为了让TitleView有更强地扩展性,我们还提供了setTitleText()、setLeftButtonText()、setLeftButtonListener()等方法,分别用于设置标题栏上的文字、返回按钮上的文字、以及返回按钮的点击事件。

美文、不要轻易用过去来衡量生活的幸与不幸!

Android自定义View的实现方法,带你一步步深入了解View(四)

相关文章:

你感兴趣的文章:

标签云: