您好,如何为我的应用创建自定义视图?观察谷歌的例子,但无法做到正确...如果有人知道关于这个主题的任何教程我感谢!晚安!
答案 0 :(得分:0)
创建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)
{
}
}
您甚至可以定义和实现自定义属性,但它很复杂,我建议不要使用它。