English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
まず効果画像をお見せします:
皆さんは効果画像に対してどう感じていますか?個人的にはそれなりに良いと思います、興味を持たれた方、実装コードを参照してみてください。
public class ToggleButton extends View { private SpringSystem springSystem; private Spring spring ; /** */ private float radius; /** 色を開ける*/ private int onColor = Color.parseColor("#4ebb7f"); /** 色を閉じる*/ private int offBorderColor = Color.parseColor("#dadbda"); /** グレー色*/ private int offColor = Color.parseColor("#ffffff"); /** ハンドルの色*/ private int spotColor = Color.parseColor("#ffffff"); /** 枠線の色*/ private int borderColor = offBorderColor; /** ペイント*/ private Paint paint ; /** スイッチの状態*/ private boolean toggleOn = false; /** 枠線の大きさ*/ private int borderWidth = 2; /** 垂直中心*/ private float centerY; /** ボタンの開始位置と終了位置*/ private float startX, endX; /** ハンドルのX位置の最小値と最大値*/ private float spotMinX, spotMaxX; /**ハンドルの大きさ */ private int spotSize ; /** ハンドルのX位置*/ private float spotX; /** 閉じた時の内部グレー帯の高さ*/ private float offLineWidth; /** */ private RectF rect = new RectF(); /** デフォルトでアニメーションを使用*/ private boolean defaultAnimate = true; /** デフォルトで開き状態に設定されていますか*/ private boolean isDefaultOn = false; private OnToggleChanged listener; private ToggleButton(Context context) { super(context); } public ToggleButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setup(attrs); } public ToggleButton(Context context, AttributeSet attrs) { super(context, attrs); setup(attrs); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); spring.removeListener(springListener); } public void onAttachedToWindow() { super.onAttachedToWindow(); spring.addListener(springListener); } public void setup(AttributeSet attrs) { paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setStyle(Style.FILL); paint.setStrokeCap(Cap.ROUND); springSystem = SpringSystem.create(); spring = springSystem.createSpring(); spring.setSpringConfig(SpringConfig.fromOrigamiTensionAndFriction(50, 7)); this.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { toggle(defaultAnimate); } }); TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.ToggleButton); offBorderColor = typedArray.getColor(R.styleable.ToggleButton_tbOffBorderColor, offBorderColor); onColor = typedArray.getColor(R.styleable.ToggleButton_tbOnColor, onColor); spotColor = typedArray.getColor(R.styleable.ToggleButton_tbSpotColor, spotColor); offColor = typedArray.getColor(R.styleable.ToggleButton_tbOffColor, offColor); borderWidth = typedArray.getDimensionPixelSize(R.styleable.ToggleButton_tbBorderWidth, borderWidth); defaultAnimate = typedArray.getBoolean(R.styleable.ToggleButton_tbAnimate, defaultAnimate); isDefaultOn = typedArray.getBoolean(R.styleable.ToggleButton_tbAsDefaultOn, isDefaultOn); typedArray.recycle(); borderColor = offBorderColor; if (isDefaultOn) { toggleOn(); } } public void toggle() { toggle(true); } public void toggle(boolean animate) { toggleOn = !toggleOn; takeEffect(animate); if(listener != null){ listener.onToggle(toggleOn); } } public void toggleOn() { setToggleOn(); if(listener != null){ listener.onToggle(toggleOn); } } public void toggleOff() { setToggleOff(); if(listener != null){ listener.onToggle(toggleOn); } } /** * 表示を開いたスタイルに設定し、toggleイベントを発生させません */ public void setToggleOn() { setToggleOn(true); } /** * @param animate asd */ public void setToggleOn(boolean animate){ toggleOn = true; takeEffect(animate); } /** * 表示を閉じたスタイルに設定し、toggleイベントを発生させません */ public void setToggleOff() { setToggleOff(true); } public void setToggleOff(boolean animate) { toggleOn = false; takeEffect(animate); } private void takeEffect(boolean animate) { if(animate) { spring.setEndValue(toggleOn ? 1 : 0); } else { //ここにはspringが呼び出されていないため、spring内の現在の値が変更されていません。ここで現在の値を設定し、両方の現在の値を同期する必要があります。 spring.setCurrentValue(toggleOn ? 1 : 0); calculateEffect(toggleOn ? 1 : 0); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int widthMode = MeasureSpec.getMode(widthMeasureSpec); final int heightMode = MeasureSpec.getMode(heightMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); Resources r = Resources.getSystem(); if(widthMode == MeasureSpec.UNSPECIFIED || widthMode == MeasureSpec.AT_MOST){ widthSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, r.getDisplayMetrics()); widthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY); } if(heightMode == MeasureSpec.UNSPECIFIED || heightSize == MeasureSpec.AT_MOST){ heightSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, r.getDisplayMetrics()); heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); 最終的なint width = getWidth(); 最終的なint height = getHeight(); radius = Math.min(width, height) * 0.5f; centerY = radius; startX = radius; endX = width - radius; spotMinX = startX + borderWidth; spotMaxX = endX - borderWidth; spotSize = height - 4 * borderWidth; spotX = toggleOn ? spotMaxX : spotMinX; offLineWidth = 0; } SimpleSpringListener springListener = new SimpleSpringListener(){ @Override public void onSpringUpdate(Spring spring) { 最終的なdouble value = spring.getCurrentValue(); calculateEffect(value); } }; private int clamp(int value, int low, int high) { return Math.min(Math.max(value, low), high); } @Override public void draw(Canvas canvas) { // rect.set(0, 0, getWidth(), getHeight()); paint.setColor(borderColor); canvas.drawRoundRect(rect, radius, radius, paint); if(offLineWidth > 0){ 最終的なfloat cy = offLineWidth * 0.5f; rect.set(spotX - cy, centerY - cy, endX + cy, centerY + cy); paint.setColor(offColor); canvas.drawRoundRect(rect, cy, cy, paint); } rect.set(spotX - 1 - radius, centerY - radius, spotX + 1.1f + radius, centerY + radius); paint.setColor(borderColor); canvas.drawRoundRect(rect, radius, radius, paint); final float spotR = spotSize * 0.5f; rect.set(spotX - spotR, centerY - spotR, spotX + spotR, centerY + spotR); paint.setColor(spotColor); canvas.drawRoundRect(rect, spotR, spotR, paint); } /** * @param value */ private void calculateEffect(final double value) { final float mapToggleX = (float) SpringUtil.mapValueFromRangeToRange(value, 0, 1, spotMinX, spotMaxX); spotX = mapToggleX; float mapOffLineWidth = (float) SpringUtil.mapValueFromRangeToRange(1 - value, 0, 1, 10, spotSize); offLineWidth = mapOffLineWidth; final int fb = Color.blue(onColor); final int fr = Color.red(onColor); final int fg = Color.green(onColor); final int tb = Color.blue(offBorderColor); final int tr = Color.red(offBorderColor); final int tg = Color.green(offBorderColor); int sb = (int) SpringUtil.mapValueFromRangeToRange(1 - value, 0, 1, fb, tb); int sr = (int) SpringUtil.mapValueFromRangeToRange(1 - value, 0, 1, fr, tr); int sg = (int) SpringUtil.mapValueFromRangeToRange(1 - value, 0, 1, fg, tg); sb = clamp(sb, 0, 255); sr = clamp(sr, 0, 255); sg = clamp(sg, 0, 255); borderColor = Color.rgb(sr, sg, sb); postInvalidate(); } /** * @author ThinkPad * */ public interface OnToggleChanged{ /** * @param on = = */ public void onToggle(boolean on); } public void setOnToggleChanged(OnToggleChanged onToggleChanged) { listener = onToggleChanged; } public boolean isAnimate() { return defaultAnimate; } public void setAnimate(boolean animate) { this.defaultAnimate = animate; } }
忘れずにカスタム属性:attrs.xml
<?xml version="1.0" encoding="utf-8"?>; <resources> <declare-styleable name="ToggleButton"> <attr name="tbBorderWidth" format="dimension"/> <attr name="tbOffBorderColor" format="reference|color"/> <attr name="tbOffColor" format="reference|color"/> <attr name="tbOnColor" format="reference|color"/> <attr name="tbSpotColor" format="reference|color"/> <attr name="tbAnimate" format="reference|boolean"/> <attr name="tbAsDefaultOn" format="reference|boolean">/> </declare-styleable> </resources>
main.xml
<?xml version="1.0" encoding="utf-8"?>; <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:toggle="http://schemas.android.com/apk/res-auto" android:orientation="vertical" > <LinearLayout android:layout_marginTop="10dp" android:layout_width="match_parent" android:gravity="center_horizontal" android:layout_height="wrap_content"> <com.example.ekikousei.view.ToggleButton android:id="@"+id/mToggleButton01" android:layout_width="54dp" android:layout_height="30dp"> </com.example.ekikousei.view.ToggleButton> </LinearLayout> <LinearLayout android:layout_marginTop="10dp" android:layout_width="match_parent" android:gravity="center_horizontal" android:layout_height="wrap_content"> <com.example.ekikousei.view.ToggleButton android:id="@"+id/mToggleButton02" android:layout_width="54dp" android:layout_height="30dp" toggle:tbBorderWidth="2dp" toggle:tbOffBorderColor="#000" toggle:tbOffColor="#ddd" toggle:tbOnColor="#f00" toggle:tbSpotColor="#00f"> </com.example.ekikousei.view.ToggleButton> </LinearLayout> </LinearLayout>
Maintivity
public class MainActivity extends Activity { private ToggleButton mToggleButton01; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mToggleButton01 = (ToggleButton) findViewById(R.id.mToggleButton01); mToggleButton01.setOnToggleChanged(new ToggleButton.OnToggleChanged() { @Override public void onToggle(boolean on) { if (on) { Toast.makeText(MainActivity.this, "打开", Toast.LENGTH_SHORT).show(); }else { Toast.makeText(MainActivity.this, "默认关闭", Toast.LENGTH_SHORT).show(); } } }); } }
猛戳这里:studio点击下载
以上所述是小编给大家介绍的Android 之仿苹果IOS6开关按钮,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对呐喊教程网站的支持!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:notice#oldtoolbag.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。