android自定义控件的一个思路-入门

转自:http://blog.sina.com.cn/s/blog_691051e10101a3by.html

很多时候没有我们需要使用的控件,或者控件并不美观。比如这个滑动开关,这是android之后的版本才提供的控件,新版本并不提供,这个时候就需要我们自定义控件了。

一个2个主要类,OnChangedListener,SlipButton

SlipButton代码如下

package com.appipv6.android.slipbutton;

import com.appipv.onoff.R;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Canvas;

import android.graphics.Matrix;

import android.graphics.Paint;

import android.graphics.Rect;

import android.util.AttributeSet;

import android.view.MotionEvent;

import android.view.View;

import android.view.View.OnTouchListener;

public class SlipButton extends View implements OnTouchListener

{

//当前按钮状态

private boolean nowChoose=false;

//用户是否在滑动

private boolean onSlip=false;

//按下时的X,当时的X

private float downX,nowX;

//打开和关闭状态下的,游标的Rect

private Rect btn_On,btn_Off;

private boolean isChgLsnOn =false;

private OnChangedListener ChgLsn;

private Bitmap bg_on,bg_off,slip_btn;

public SlipButton(Context context)

{

super(context);

// TODO Auto-generated constructor stub

init();

}

public SlipButton(Context context, AttributeSet attrs)

{

super(context, attrs);

// TODO Auto-generated constructor stub

init();

}

public SlipButton(Context context, AttributeSet attrs, int defStyle)

{

super(context, attrs, defStyle);

// TODO Auto-generated constructor stub

init();

}

private void init()

{

// TODO Auto-generated method stub

bg_on=BitmapFactory.decodeResource(getResources(), R.drawable.on);

bg_off=BitmapFactory.decodeResource(getResources(), R.drawable.off);

slip_btn=BitmapFactory.decodeResource(getResources(), R.drawable.my_btn);

int tmp=bg_off.getWidth()/2;

btn_On=new Rect(tmp, 0, slip_btn.getWidth()+tmp, slip_btn.getHeight());

btn_Off=new Rect(bg_off.getWidth()-tmp-slip_btn.getWidth(), 0, bg_off.getWidth()-tmp, slip_btn.getHeight());

setOnTouchListener(this);

}

@Override

protected void onDraw(Canvas canvas)

{

// TODO Auto-generated method stub

super.onDraw(canvas);

Matrix matrix=new Matrix();

Paint paint=new Paint();

float x;

if(onSlip)

{

if(nowX>=bg_on.getWidth())

{

x=bg_on.getWidth()-slip_btn.getWidth()/2;

}else{

x=nowX-slip_btn.getWidth()/2;

}

}else{

if(nowChoose)

{

x=btn_On.left;

}else{

x=btn_Off.left;

}

}

if(nowX<(bg_on.getWidth()/2))

{

canvas.drawBitmap(bg_off, matrix, paint);

}else{

canvas.drawBitmap(bg_on, matrix, paint);

}

if(x<0)

{

x=0;

}else if(x>bg_on.getWidth()-slip_btn.getWidth())

{

x=bg_on.getWidth()-slip_btn.getWidth();

}

canvas.drawBitmap(slip_btn, x, 0,paint);

}

public boolean onTouch(View v, MotionEvent event)

{

// TODO Auto-generated method stub

switch (event.getAction())

{

case MotionEvent.ACTION_MOVE:

nowX=event.getX();

break;

case MotionEvent.ACTION_DOWN:

if(event.getX()>bg_on.getWidth() || event.getY()>bg_on.getHeight())

{

return false;

}

onSlip=true;

downX=event.getX();

nowX=downX;

break;

case MotionEvent.ACTION_UP:

onSlip=false;

boolean lastChoose=nowChoose;

if(event.getX()>=(bg_on.getWidth()/2))

{

nowChoose=true;

}else{

nowChoose=false;

}

if(isChgLsnOn&&(lastChoose!=nowChoose))

{

ChgLsn.OnChanged(nowChoose);

}

break;

default:

break;

}

invalidate();

return true;

}

public void setOnChangeListener(OnChangedListener l)

{

isChgLsnOn=true;

ChgLsn=l;

}

public boolean isNowChoose()

{

return nowChoose;

}

public void setNowChoose(boolean nowChoose)

{

this.nowChoose = nowChoose;

nowX=btn_On.left;

invalidate();

}

}

OnChangedListener代码如下

public interface OnChangedListener

{

abstract void OnChanged(boolean CheckState);

}

主Activity代码如下

package com.appipv.onoff;

import com.appipv6.android.slipbutton.OnChangedListener;

import com.appipv6.android.slipbutton.SlipButton;

import android.app.Activity;

import android.os.Bundle;

import android.widget.Toast;

public class OnOffActivity extends Activity

{

private SlipButton slipButton1;

@Override

public void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

SlipButton slipButton = (SlipButton) findViewById(R.id.slipButton1);

slipButton.setNowChoose(true);

slipButton1 = (SlipButton) findViewById(R.id.slipButton2);

slipButton.setOnChangeListener(new OnChangedListener()

{

public void OnChanged(boolean CheckState)

{

// TODO Auto-generated method stub

String s;

if(slipButton1.isNowChoose())

{

s="Button2打开了...";

}else{

s="Button2关闭了...";

}

if (CheckState)

Toast.makeText(OnOffActivity.this, "Button1打开了..."+s,

Toast.LENGTH_SHORT).show();

else

Toast.makeText(OnOffActivity.this, "Button1关闭了..."+s,

Toast.LENGTH_SHORT).show();

}

});

}

}

布局文件代码如下

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical"

android:background="@drawable/back"

>

<com.appipv6.android.slipbutton.SlipButton

android:id="@+id/slipButton1"

android:layout_width="wrap_content"

android:layout_height="49dp" />

<com.appipv6.android.slipbutton.SlipButton

android:id="@+id/slipButton2"

android:layout_width="wrap_content"

android:layout_height="fill_parent" />

</LinearLayout>

时间: 2024-08-01 22:27:20

android自定义控件的一个思路-入门的相关文章

Android自定义控件实现一个带文本与数字的圆形进度条

实现的效果图如下所示: 第一步:绘制下方有缺口的空心圆,称为外围大弧吧 anvas.clipRect(0, 0, mWidth, mHeight / 2 + radius - textHeight * 3 / 4); 第二步:计算绘制圆弧进度条时的起始角度,设置为外围大弧的左端点为进度值得起点,扫过的角度所占外围大弧的百分比就是进度值 第三步:绘制数字.文字.百分号 第四步:使用Handler Runnable 和DecelerateInterpolator是进度条和数字动起来 测试代码: fi

[转]Android自定义控件系列五:自定义绚丽水波纹效果

出处:http://www.2cto.com/kf/201411/353169.html 今天我们来利用Android自定义控件实现一个比较有趣的效果:滑动水波纹.先来看看最终效果图: 图一 效果还是很炫的:饭要一口口吃,路要一步步走,这里我们将整个过程分成几步来实现 一.实现单击出现水波纹单圈效果: 图二 照例来说,还是一个自定义控件,这里我们直接让这个控件撑满整个屏幕(对自定义控件不熟悉的可以参看我之前的一篇文章:Android自定义控件系列二:自定义开关按钮(一)).观察这个效果,发现应该

Android自定义控件系列五:自定义绚丽水波纹效果

尊重原创!转载请注明出处:http://blog.csdn.net/cyp331203/article/details/41114551 今天我们来利用Android自定义控件实现一个比较有趣的效果:滑动水波纹.先来看看最终效果图: 图一 效果还是很炫的:饭要一口口吃,路要一步步走,这里我们将整个过程分成几步来实现 一.实现单击出现水波纹单圈效果: 图二 照例来说,还是一个自定义控件,这里我们直接让这个控件撑满整个屏幕(对自定义控件不熟悉的可以参看我之前的一篇文章:Android自定义控件系列二

Android 自定义控件开发入门(一)

作为一个有创意的开发者,或者软件对UI设计的要求比较高,你经常会遇到安卓自带的控件无法满足你的需求的情况,这种时候,我们只能去自己去实现适合项目的控件.同时,安卓也允许你去继承已经存在的控件或者实现你自己的控件以便优化界面和创造更加丰富的用户体验. 那么怎样来创建一个新的控件呢? 这得看需求是怎样的了. 1.需要在原生控件的基本功能上进行扩展,这个时候你只需要继承并对控件进行扩展.通过重写它的事件,onDraw ,但是始终都保持都父类方法的调用.如从已有的高级控件上继承,例如继承一个TextVi

Android 自定义控件开发入门(二)

上一次我们讲了一堆实现自定义控件的理论基础,列举了View类一些可以重写的方法,我们对这些方法的重写是我们继承View类来派生自定义控件的关键 我通过一个最简单的例子给大家展示了这一个过程,无论是多么复杂的自定义控件,思路总是这样子的,但是因为我们仅仅重写了onDraw方法使得大家觉得怪怪的,作为一个控件,我们居然还要为了他的实现为其增加麻烦的监听,这就不能叫做控件了. 下面再给大家介绍一个经常重写的方法法:publicboolean onTouchEvent (MotionEvent even

Android 自定义控件开发入门 (三)

上两次我们从如何自定义控件讲起,列举了View的一些Api,说明了一些在自定义的时候,可以进行重写的方法,然后通过一个例子的两种写法向大家展示了最基本的自定义控件和我们要充分了解并积极重写View方法的精神,这次我们将继续进行学习! 现在请大家回想一下我们使用安卓原生控件时的感受,一个好的控件是可以在xml中进行各种属性的操作的,而自定义控件往往有一些特殊的需求,今天我要讲的就是安卓给自定义控件添加自定义的属性. 下面再给大家具体介绍一下如果自定义的View需要有自定义的属性我们该如何处理: 我

Android自定义控件系列七:详解onMeasure()方法中如何测量一个控件尺寸(一)

转载请注明出处:http://blog.csdn.net/cyp331203/article/details/45027641 自定义view/viewgroup要重写的几个方法:onMeasure(),onLayout(),onDraw().(不熟悉的话可以查看专栏的前几篇文章:Android自定义控件系列二:自定义开关按钮(一)). 今天的任务就是详细研究一下protected void onMeasure(int widthMeasureSpec, int heightMeasureSpe

Android自定义控件(状态提示图表) (转)

源:Android自定义控件(状态提示图表) 源:Android应用开发 [工匠若水 http://blog.csdn.net/yanbober 转载烦请注明出处,尊重分享成果] 1  背景 前面分析那么多系统源码了,也该暂停下来休息一下,趁昨晚闲着看见一个有意思的需求就操练一下分析源码后的实例演练—-自定义控件. 这个实例很适合新手入门自定义控件.先看下效果图: 横屏模式如下: 竖屏模式如下: 看见没有,这个控件完全自定义的,连文字等都是自定义的,没有任何图片等资源,就仅仅是一个小的java文

android自定义控件实现TextView按下后字体颜色改变

今天跟大家分享一下Android自定义控件入门,先介绍一个简单的效果TextView,按下改变字体颜色,后期慢慢扩展更强大的功能 直接看图片             第一张是按下后截的图,功能很简单,也很容易实现,下面来看一下如何通过重写TextView来实现 一共三个文件  TextViewM.java,MainActivity.java,activity_textview.xml TextViewM.java 1 package landptf.control; 2 3 import and