1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Android自定义控件(二) 滑动开关

Android自定义控件(二) 滑动开关

时间:2024-01-13 19:37:06

相关推荐

Android自定义控件(二) 滑动开关

Android自定义控件是作为一名优秀的Android攻城狮必不可少的技能,为了进一步认识自定义控件,层次递进的学习,今天给大家以案例(滑动开关案例)的形式说明自定义控件的使用(案例UI图片取自网上图库,在此致谢图片分享者)。

首先晒上案例效果图

一、回顾一下自定义控件是什么?

1.自定义控件实现很简单,我们可以将他分为两大类:

(1)通过组合原生的控件,加上一些特殊动画的组合来达到自定义的需求

(2)定义一个类继承View,或者还可以继承ViewGroup

2.View和ViewGroup的区别:

ViewGroup里面可以添加自己的孩子(LinearLayout、FrameLayout、TableLayout、RelativeLayout、AbsoluteLayout这几大布局都继承ViewGroup)

二、滑动开关案例下面将以代码+注释的形式详解,直接看代码感觉更爽一些

1.定义一个类ToggleView,继承View

package com.example.toggleview;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;public class ToggleView extends View {private Bitmap switch_background;private Bitmap slide_button_background;private boolean toggleCurrentState = false; //当前开关的状态private boolean isSliding = false; //默认不滑动private int downX;private OnToggleStateChangeListener mToggleStateChangeListener;//直接new 初始化的时候调用public ToggleView(Context context) {super(context);}public ToggleView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}//在布局里面使用的时候调用public ToggleView(Context context, AttributeSet attrs) {super(context, attrs);String namespace = "/apk/res/com.example.toggleview";int switchBackground = attrs.getAttributeResourceValue(namespace, "switchBackground", -1);int slidingBackground = attrs.getAttributeResourceValue(namespace, "slidingBackground", -1);//设置开关的状态toggleCurrentState = attrs.getAttributeBooleanValue(namespace, "toggleState", false);//设置 开关的背景 setToggleBackground(switchBackground);//设置滑动块的背景 setToggleSlidBackGround(slidingBackground);}//设置开关背景public void setToggleBackground(int switchBackground) {switch_background = BitmapFactory.decodeResource(getResources(), switchBackground);}//设置开关的滑动块public void setToggleSlidBackGround(int slideButtonBackground) {slide_button_background = BitmapFactory.decodeResource(getResources(),slideButtonBackground);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {//测量当前viwe的宽和高 setMeasuredDimension(switch_background.getWidth(), switch_background.getHeight());}//绘制内容 被绘制到了当前控件上@Overrideprotected void onDraw(Canvas canvas) {//[1]画开关的背景 canvas.drawBitmap(switch_background, 0, 0, null);if (isSliding) {//[2]根据当前dwonX 画滑动块 int left = downX - slide_button_background.getWidth()/2;//[2.1]对边界进行处理int rightAlgin = switch_background.getWidth() - slide_button_background.getWidth();if (left<0) {left = 0;}else if (left > rightAlgin) {left = rightAlgin;}canvas.drawBitmap(slide_button_background, left, 0, null);}else {//不是滑动状态 根据 当前开关的状态 画 //[2]画滑动块背景if (toggleCurrentState) {//开关打开状态int left = switch_background.getWidth() - slide_button_background.getWidth();canvas.drawBitmap(slide_button_background, left, 0,null);}else {//开关关闭canvas.drawBitmap(slide_button_background, 0, 0,null);}}super.onDraw(canvas);}@Overridepublic boolean onTouchEvent(MotionEvent event) {int action = event.getAction();switch (action) {case MotionEvent.ACTION_DOWN: //按下//[1]获取手指触摸的位置isSliding = true;downX = (int) event.getX(); break;case MotionEvent.ACTION_MOVE: //移动 downX = (int) event.getX();break;case MotionEvent.ACTION_UP: //抬起downX = (int) event.getX();//[0]手指抬起 处于不是滑动状态isSliding = false;//[1]获取开关背景一半 int center = switch_background.getWidth()/2;boolean state = downX > center;//[1.1]开关的状态没有发生改变的时候 不触发我们写回调事件if (toggleCurrentState!=state) {toggleCurrentState = state;//[2]触发我们定义的回调方法if (mToggleStateChangeListener!=null) {mToggleStateChangeListener.onToggleState(toggleCurrentState);}}break;}//当前view 会进行重绘 会调用onDrawinvalidate();//让当前控件处理事件return true;}//设置开关的状态public void setToggleState(boolean b) {toggleCurrentState = b;}//设置开关改变的监听 public void setOnToggleStateLinstener(OnToggleStateChangeListener listen){mToggleStateChangeListener = listen;}//开关滑动接口public interface OnToggleStateChangeListener{public void onToggleState(boolean state);}}

2.在布局文件中将其定义出来

res/layout/activity_main.xml

<RelativeLayout xmlns:android="/apk/res/android"xmlns:example="/apk/res/com.example.toggleview"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center" ><com.example.toggleview.ToggleViewandroid:id="@+id/toggleView1"android:layout_width="wrap_content"android:layout_height="wrap_content"example:slidingBackground="@drawable/slide_button_background"example:switchBackground="@drawable/switch_background"example:toggleState="true" /></RelativeLayout>

res/values/attrs.xml

<?xml version="1.0" encoding="utf-8"?><resources><declare-styleable name="toggleview"><attr name="switchBackground" format="reference" /><attr name="slidingBackground" format="reference" /><attr name="toggleState" format="boolean" /></declare-styleable></resources>

3.在MainActivity中找到我们自己定义的开关控件设置相关属性和监听事件

package com.example.toggleview;import com.example.toggleview.ToggleView.OnToggleStateChangeListener;import android.os.Bundle;import android.app.Activity;import android.widget.Toast;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//[1]找到我们自己定义的开关控件 ToggleView toggleView = (ToggleView) findViewById(R.id.toggleView1);//[2]设置开关的背景 //toggleView.setToggleBackground(R.drawable.switch_background);//[3]设置开关的滑动块 //toggleView.setToggleSlidBackGround(R.drawable.slide_button_background);//[4]设置开关的状态 //toggleView.setToggleState(false);//[5]设置一个开关状态的监听 toggleView.setOnToggleStateLinstener(new OnToggleStateChangeListener() {@Overridepublic void onToggleState(boolean state) {if (state) {Toast.makeText(getApplicationContext(), "开", 0).show();//TODO }else{Toast.makeText(getApplicationContext(), "关", 0).show();}}});}}

案例到这里就基本上大功告成了

项目源码,点击下载

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。