OnOff触摸效果实现

本文介绍了一个自定义的Android布局——XYLayout,通过触摸事件实现两种视图(OnView和OffView)之间的动态切换,并详细展示了相关Java代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为了 实现这种效果。关键代码如下:

 xyLayout = new XYLayout(this);
  llp = new LinearLayout.LayoutParams(100, 30);
  xyLayout.setBackgroundDrawable(new TwoColorRoundRectDrawable(Color
    .argb(255, 230, 230, 230), Color.argb(255, 230, 230, 230)));
  this.addContentView(xyLayout, llp);
  onview = new OnView(this);
  xyLayout.addView(onview);
  xyLayout.setOnTouchListener(new OnTouchListener() {

   @Override
   public boolean onTouch(View v, MotionEvent event) {
    onview = new OnView(OnOffViewDemo.this);
    offview = new OffView(OnOffViewDemo.this);
    if (i % 2 != 0) {

     xyLayout.removeAllViews();
     xyLayout.addView(onview);
    } else {

     xyLayout.removeAllViews();
     xyLayout.addView(offview);
    }
    i++;
    return false;
   }
  });

 

xyLayout.java如下:

package cn.bmy;

import java.util.HashMap;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

public class XYLayout extends ViewGroup {
 private HashMap<String, Object> propMap = new HashMap<String, Object>();

 public XYLayout(Context context) {
  super(context);
 }

 public XYLayout(Context context, AttributeSet attrs) {
  super(context, attrs);
 }

 public XYLayout(Context context, AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);
 }

 public void setProperty(String property, Object value) {
  propMap.put(property, value);
 }

 public Object getProperty(String property) {
  return propMap.get(property);
 }

 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  int count = getChildCount();

  int maxHeight = 0;
  int maxWidth = 0;

  int specwidth = MeasureSpec.getSize(widthMeasureSpec);
  int specheight = MeasureSpec.getSize(heightMeasureSpec);

  // Find out how big everyone wants to be
  measureChildren(widthMeasureSpec, heightMeasureSpec);

  // Find rightmost and bottom-most child
  for (int i = 0; i < count; i++) {
   View child = getChildAt(i);
   if (child.getVisibility() != GONE) {
    int childRight;
    int childBottom;

    XYLayout.LayoutParams lp = (XYLayout.LayoutParams) child
      .getLayoutParams();
    if (lp.x == LayoutParams.LEFT) {
     childRight = child.getMeasuredWidth();
     maxWidth = Math.max(maxWidth, childRight);
    } else if (lp.x == LayoutParams.CENTER) {
     childRight = (child.getMeasuredWidth() / 2)
       + (specwidth / 2);
     maxWidth = Math.max(maxWidth, childRight);
    } else if (lp.x == LayoutParams.RIGHT) {
     childRight = specwidth;
     maxWidth = Math.max(maxWidth, childRight);
    } else {
     childRight = lp.x + child.getMeasuredWidth();
     maxWidth = Math.max(maxWidth, childRight);
    }
    if (lp.y == LayoutParams.TOP) {
     childBottom = child.getMeasuredHeight();
     maxHeight = Math.max(maxHeight, childBottom);
    } else if (lp.y == LayoutParams.CENTER) {
     childBottom = (child.getMeasuredHeight() / 2)
       + (specheight / 2);
     maxHeight = Math.max(maxHeight, childBottom);
    } else if (lp.y == LayoutParams.BOTTOM) {
     childBottom = specheight;
     maxHeight = Math.max(maxHeight, childBottom);
    } else {
     childBottom = lp.y + child.getMeasuredHeight();
     maxHeight = Math.max(maxHeight, childBottom);
    }
   }
  }

  // Account for padding too
  maxWidth += getPaddingLeft() + getPaddingRight();
  maxHeight += getPaddingTop() + getPaddingBottom();

  // Check against minimum height and width
  maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
  maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());

  setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
    resolveSize(maxHeight, heightMeasureSpec));
 }

 /**
  * Returns a set of layout parameters with a width of
  * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT}, a height of
  * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} and with the
  * coordinates (0, 0).
  */
 protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
  return new LayoutParams(LayoutParams.WRAP_CONTENT,
    LayoutParams.WRAP_CONTENT, 0, 0);
 }

 protected void onLayout(boolean changed, int l, int t, int r, int b) {
  int count = getChildCount();

  int width = Math.abs(r - l) - getPaddingLeft() - getPaddingRight();
  int height = Math.abs(b - t) - getPaddingTop() - getPaddingBottom();

  for (int i = 0; i < count; i++) {
   View child = getChildAt(i);
   if (child.getVisibility() != GONE) {

    XYLayout.LayoutParams lp = (XYLayout.LayoutParams) child
      .getLayoutParams();
    int childWidth = child.getMeasuredWidth();
    int childHeight = child.getMeasuredHeight();
    if (lp.x == LayoutParams.LEFT && lp.y == LayoutParams.TOP) {
     int childLeft = getPaddingLeft();
     int childTop = getPaddingTop();
     child.layout(childLeft, childTop,
       childLeft + child.getMeasuredWidth(), childTop
         + child.getMeasuredHeight());
    } else if (lp.x == LayoutParams.CENTER
      && lp.y == LayoutParams.TOP) {
     int childLeft = getPaddingLeft() + (width - childWidth) / 2;
     int childTop = getPaddingTop();
     child.layout(childLeft, childTop,
       childLeft + child.getMeasuredWidth(), childTop
         + child.getMeasuredHeight());
    } else if (lp.x == LayoutParams.RIGHT
      && lp.y == LayoutParams.TOP) {
     int childLeft = getPaddingLeft() + width - childWidth;
     int childTop = getPaddingTop();
     child.layout(childLeft, childTop,
       childLeft + child.getMeasuredWidth(), childTop
         + child.getMeasuredHeight());
    } else if (lp.x == LayoutParams.LEFT
      && lp.y == LayoutParams.CENTER) {
     int childLeft = getPaddingLeft();
     int childTop = getPaddingTop() + (height - childHeight / 2);
     child.layout(childLeft, childTop,
       childLeft + child.getMeasuredWidth(), childTop
         + child.getMeasuredHeight());
    } else if (lp.x == LayoutParams.CENTER
      && lp.y == LayoutParams.CENTER) {
     int childLeft = getPaddingLeft() + (width - childWidth) / 2;
     int childTop = getPaddingTop() + (height - childHeight) / 2;
     child.layout(childLeft, childTop,
       childLeft + child.getMeasuredWidth(), childTop
         + child.getMeasuredHeight());
    } else if (lp.x == LayoutParams.RIGHT
      && lp.y == LayoutParams.CENTER) {
     int childLeft = getPaddingLeft() + width - childWidth;
     int childTop = getPaddingTop() + (height - childHeight) / 2;
     child.layout(childLeft, childTop,
       childLeft + child.getMeasuredWidth(), childTop
         + child.getMeasuredHeight());
    } else if (lp.x == LayoutParams.LEFT
      && lp.y == LayoutParams.BOTTOM) {
     int childLeft = getPaddingLeft();
     int childTop = getPaddingTop() + height - childHeight;
     child.layout(childLeft, childTop,
       childLeft + child.getMeasuredWidth(), childTop
         + child.getMeasuredHeight());
    } else if (lp.x == LayoutParams.CENTER
      && lp.y == LayoutParams.BOTTOM) {
     int childLeft = getPaddingLeft() + (width - childWidth) / 2;
     int childTop = getPaddingTop() + height - childHeight;
     child.layout(childLeft, childTop,
       childLeft + child.getMeasuredWidth(), childTop
         + child.getMeasuredHeight());
    } else if (lp.x == LayoutParams.RIGHT
      && lp.y == LayoutParams.BOTTOM) {
     int childLeft = getPaddingLeft() + width - childWidth;
     int childTop = getPaddingTop() + height - childHeight;
     child.layout(childLeft, childTop,
       childLeft + child.getMeasuredWidth(), childTop
         + child.getMeasuredHeight());
    } else {
     int childLeft = getPaddingLeft() + lp.x;
     int childTop = getPaddingTop() + lp.y;
     child.layout(childLeft, childTop,
       childLeft + child.getMeasuredWidth(), childTop
         + child.getMeasuredHeight());
    }

   }
  }
 }

 public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
  return new XYLayout.LayoutParams(getContext(), attrs);
 }

 // Override to allow type-checking of LayoutParams.
 protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
  return p instanceof XYLayout.LayoutParams;
 }

 protected ViewGroup.LayoutParams generateLayoutParams(
   ViewGroup.LayoutParams p) {
  return new LayoutParams(p);
 }

 /**
  * Per-child layout information associated with AbsoluteLayout. See
  * {@link android.R.styleable#AbsoluteLayout_Layout Absolute Layout
  * Attributes} for a list of all child view attributes that this class
  * supports.
  */
 public static class LayoutParams extends ViewGroup.LayoutParams {
  public static final int LEFT = -31302;
  public static final int RIGHT = -31301;
  public static final int CENTER = -31300;
  public static final int TOP = -31329;
  public static final int BOTTOM = -31328;
  /**
   * The horizontal, or X, location of the child within the view group.
   */
  public int x;
  /**
   * The vertical, or Y, location of the child within the view group.
   */
  public int y;

  /**
   * Creates a new set of layout parameters with the specified width,
   * height and location.
   *
   * @param width
   *            the width, either {@link #FILL_PARENT},
   *            {@link #WRAP_CONTENT} or a fixed size in pixels
   * @param height
   *            the height, either {@link #FILL_PARENT},
   *            {@link #WRAP_CONTENT} or a fixed size in pixels
   * @param x
   *            the X location of the child
   * @param y
   *            the Y location of the child
   */
  public LayoutParams(int width, int height, int x, int y) {
   super(width, height);
   this.x = x;
   this.y = y;
  }

  /**
   * Creates a new set of layout parameters. The values are extracted from
   * the supplied attributes set and context. The XML attributes mapped to
   * this set of layout parameters are:
   *
   * <ul>
   * <li><code>layout_x</code>: the X location of the child</li>
   * <li><code>layout_y</code>: the Y location of the child</li>
   * <li>All the XML attributes from
   * {@link android.view.ViewGroup.LayoutParams}</li>
   * </ul>
   *
   * @param c
   *            the application environment
   * @param attrs
   *            the set of attributes from which to extract the layout
   *            parameters values
   */
  public LayoutParams(Context c, AttributeSet attrs) {
   super(c, attrs);
   x = Integer.parseInt(attrs.getAttributeValue(null, "layout_x"));
   y = Integer.parseInt(attrs.getAttributeValue(null, "layout_y"));
  }

  /**
   * {@inheritDoc}
   */
  public LayoutParams(ViewGroup.LayoutParams source) {
   super(source);
  }

  public String debug(String output) {
   return output + "Absolute.LayoutParams={width="
     + Integer.toString(width) + ", height="
     + Integer.toString(height) + " x=" + x + " y=" + y + "}";
  }
 }
}

TwoColorRoundRectDrawable.java代码如下:

package cn.bmy;

import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Shader;
import android.graphics.Path.Direction;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;

public class TwoColorRoundRectDrawable extends Drawable {
 private int startcolor;
 private int endcolor;
 
 public TwoColorRoundRectDrawable(int startcolor, int endcolor){
  this.startcolor = startcolor;
  this.endcolor = endcolor;
 }

 public void draw(Canvas canvas) {
  Rect bounds = getBounds();
  Paint paint = new Paint();
  paint.setShader(new LinearGradient(bounds.left, bounds.top, bounds.left, bounds.bottom, startcolor,
    endcolor, Shader.TileMode.CLAMP));
  Path path = new Path();
  path.addRoundRect(new RectF(bounds.left, bounds.top, bounds.right, bounds.bottom),5,5,Direction.CW);

  canvas.drawPath(path, paint);
 }

 protected void onBoundsChange(Rect bounds) {

 }

 public void setAlpha(int alpha) {
  // TODO Auto-generated method stub

 }

 public void setColorFilter(ColorFilter cf) {
  // TODO Auto-generated method stub

 }

 public int getOpacity() {
  // TODO Auto-generated method stub
  return 0;
 }

}

OnView.java如下:

package cn.bmy;

import android.content.Context;
import android.graphics.Color;
import android.view.Gravity;
import android.widget.LinearLayout;
import android.widget.TextView;

public class OnView extends LinearLayout{
 //AppInstance appInstance;
 Context context;
 LinearLayout.LayoutParams llp;
 public OnView(Context context) {
  super(context);
  this.context = context;
  buildView();
  // TODO Auto-generated constructor stub
 }
 private void buildView() {
  LinearLayout onoffView=new LinearLayout(context);
  llp=new LinearLayout.LayoutParams(100,30);
  this.addView(onoffView,llp);
  onoffView.setBackgroundDrawable(new TwoColorRoundRectDrawable(Color.argb(255,230, 230, 230), Color.argb(255,230, 230, 230)));
  
  onoffView.setOrientation(LinearLayout.HORIZONTAL);
  
  final LinearLayout onView=new LinearLayout(context);
  llp=new LinearLayout.LayoutParams(60,30);
  onoffView.addView(onView,llp);
  onView.setBackgroundDrawable(new TwoColorRoundRectDrawable(Color.argb(255, 24, 77, 156), Color.argb(255, 115, 163, 231)));
  final TextView tvOn=new TextView(context);
  llp=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT);
  onView.addView(tvOn,llp);
  tvOn.setText("ON");
  tvOn.setTextSize(16);
  tvOn.setGravity(Gravity.CENTER);
  
  LinearLayout offView= new LinearLayout(context);
  llp=new LinearLayout.LayoutParams(40,30,1);
  onoffView.addView(offView,llp);
  offView.setBackgroundDrawable(new TwoColorRoundRectDrawable(Color.argb(255,230, 230, 230), Color.argb(255,230, 230, 230)));
  
  final TextView tvOff=new TextView(context);
  llp=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT);
  offView.addView(tvOff,llp);
  tvOff.setText("");
  tvOff.setTextSize(16);
  tvOff.setGravity(Gravity.CENTER);
  
 }
}

OffView.java代码如下:

package cn.bmy;

import android.content.Context;
import android.graphics.Color;
import android.view.Gravity;
import android.widget.LinearLayout;
import android.widget.TextView;

public class OffView extends LinearLayout{
 //AppInstance appInstance;
 Context context;
 LinearLayout.LayoutParams llp;
 public OffView(Context context) {
  super(context);
  this.context = context;
  buildView();
  // TODO Auto-generated constructor stub
 }
 private void buildView() {
  LinearLayout onoffView=new LinearLayout(context);
  llp=new LinearLayout.LayoutParams(100,30);
  this.addView(onoffView,llp);
  
  onoffView.setBackgroundDrawable(new TwoColorRoundRectDrawable(Color.argb(255,230, 230, 230), Color.argb(255,230, 230, 230)));
  onoffView.setOrientation(LinearLayout.HORIZONTAL);
  
  final LinearLayout onView=new LinearLayout(context);
  llp=new LinearLayout.LayoutParams(40,30);
  onoffView.addView(onView,llp);
  onView.setBackgroundDrawable(new TwoColorRoundRectDrawable(Color.argb(255,230, 230, 230), Color.argb(255,230, 230, 230)));
  final TextView tvOn=new TextView(context);
  llp=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT);
  onView.addView(tvOn,llp);
  tvOn.setText("");
  tvOn.setTextSize(16);
  tvOn.setGravity(Gravity.CENTER);
  
  LinearLayout offView= new LinearLayout(context);
  llp=new LinearLayout.LayoutParams(60,30);
  onoffView.addView(offView,llp);
  onoffView.setBackgroundDrawable(new TwoColorRoundRectDrawable(Color.WHITE,Color.WHITE));
  final TextView tvOff=new TextView(context);
  llp=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT);
  offView.addView(tvOff,llp);
  tvOff.setText("OFF");
  tvOff.setTextSize(16);
  tvOff.setGravity(Gravity.CENTER);
  
 }

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值