如何创建自定义视图
Posted
技术标签:
【中文标题】如何创建自定义视图【英文标题】:How to create Custom Views 【发布时间】:2014-03-13 00:42:20 【问题描述】:您好,如何为我的应用创建自定义视图?观察了谷歌的例子,但不能正确......如果有人知道关于这个主题的任何教程,我感谢!晚安!
【问题讨论】:
【参考方案1】:创建 View 的子类。实现三个 View 构造函数。实现 onSizeChanged() 和 onDraw()。可选择实现 onMeasure()、onLayout()、onTouchEvent() 等。
确实,您最好的方法是从骨架模板开始并对其进行扩展。这就是我一直做的:
/**
* $Id: custom.hlp,v 1.15 2013-10-24 23:20:01 falk Exp $
*
* Template.java - Template widget
*
* Author: Edward A. Falk
* efalk@users.sourceforge.net
*
* Date: May 2009
*
* This code demonstrates the creation of a custom widget,
* with some custom resources.
*
* Copy and paste this to your own class.
* Delete the parts you don't need.
*/
package com.example.template;
import android.view.View;
import android.content.Context;
import android.content.res.Resources;
import android.util.AttributeSet;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.Log;
public class Template extends View
private static final String TAG = "Template";
private Context ctx;
private Resources res;
private Paint paint;
// Some XML resources:
private int function;
private String label;
/**
* Constructor used when view is constructed in code.
*/
public Template(Context ctx)
super(ctx);
TemplateInit(ctx, null);
/**
* Constructor used when view is constructed from XML
*/
public Template(Context ctx, AttributeSet attrs)
super(ctx, attrs);
TemplateInit(ctx, attrs);
/**
* Same, with class-specific base style
*/
public Template(Context ctx, AttributeSet attrs, int defStyle)
super(ctx, attrs, defStyle);
TemplateInit(ctx, attrs);
private void TemplateInit(Context ctx, AttributeSet attrs)
// Handle whatever common initialization is appropriate for
// this widget.
this.ctx = ctx;
res = getResources();
paint = new Paint();
paint.setAntiAlias(true);
paint.setDither(false);
@Override
protected void onSizeChanged(int w, int h, int ow, int oh)
// Deal with size change
@Override
protected void onDraw(Canvas canvas)
super.onDraw(canvas);
paint.setColor(Color.BLACK);
canvas.drawText(label, x, y, paint);
/**
* Receive touch events. Leave this out if the default
* behavior is ok.
*/
@Override
public final boolean onTouchEvent(MotionEvent event)
// Return false to let some other view have it
// Return true to say we handled it
// Or let the superclass deal with it
return super.onTouchEvent(event);
/**
* Determine how large we want to be. We can skip implementing
* this method if the superclass will handle it for us.
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
int wid = View.MeasureSpec.getSize(widthMeasureSpec);
int hgt = View.MeasureSpec.getSize(heightMeasureSpec);
int wmode = View.MeasureSpec.getMode(widthMeasureSpec);
int hmode = View.MeasureSpec.getMode(heightMeasureSpec);
final int hpad = getPaddingLeft() + getPaddingRight();
final int vpad = getPaddingTop() + getPaddingBottom();
// Overview: Measure our contents plus internal padding.
// Pass this information to setMeasuredDimensions(). Whatever
// values we pass, we can assume that's what our final size
// will be. If the parent doesn't like it, it will call this
// method again, with more restrictions.
// What happens now depends on the measure spec mode. If
// it's EXACTLY, we ignore our own needs and return the
// size part of the measurespec. If the mode is UNSPECIFIED,
// we ignore the size part of the measurespec and return
// anything we want. If the mode is AT_MOST, we might return
// the lesser of our own needs and the size part of
// measurespec, or we might just treat this the same
// as EXACTLY.
// Easiest implementation is to use setMinimumWidth()/Height()
// to establish our minimum required size, and then let
// getSuggestedMinimumWidth()/Height() and getDefaultSize()
// do the heavy lifting. These may be overridden if needed,
// to customize behavior.
setMinimumWidth(hpad + yaddayadda);
setMinimumHeight(vpad + yaddayadda);
setMeasuredDimension(
getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
/**
* Parent has made final decision and is laying us out. Here
* is where we do any internal layout we need.
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
您甚至可以定义和实现自定义属性,但这很复杂,我建议不要这样做。
【讨论】:
以上是关于如何创建自定义视图的主要内容,如果未能解决你的问题,请参考以下文章