栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

五、自定义控件:

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

五、自定义控件:

目录

五、自定义控件:

六、自定义控件主题theme、样式Style:

1.主题和样式

2.使用主题

3.使用样式

 清单文件中使用主题:

布局文件中使用样式:

//自定义控件之滑动移位小方快

本文章作为学习总结

尊重原创老师  参考部分前辈网络总结,如涉及版权问题,请联系。

五、自定义控件:

1.使用自定义控件,必须在布局文件中添加schemas声明,xmlns:app=http://schemas.android.com/apk/res-auto,

2.......

六、自定义控件主题theme、样式Style:

1.主题和样式

2.主题和样式的定义方法类似,都是在

2.使用主题

a)从AndroidManifest中指定,可以选择Application应用级:

    

或是Activity级:

    

b)从Java代码中指定:

public void onCreate(BundlesavedInstanceState) {

super.onCreate(savedInstanceState);

setTheme(R.style.MyTheme);

setContentView(R.layout.main); }

3.使用样式

a)从layout的xml文件中指定:

         

android:layout_width="fill_parent"           

android:layout_height="wrap_content">

b)从Java代码中指定:

public void onCreate(Bundle savedInstanceState) {   

super.onCreate(savedInstanceState);

setTheme(R.style.MyTheme);        

setContentView(R.layout.main);        

LinearLayout ll = (LinearLayout)findViewById(R.id.llMain);        

EditText et = new EditText(this, null, R.attr.myStyle);        

ll.addView(et);    }

 清单文件中使用主题:

(1)系统主题:android:theme=”@android:style/ButtonBar”

(2)自定义主题:android:theme=”@style/MyStyle”

布局文件中使用样式:

(1)系统样式:style=”@android:style/ButtonBar”

(2)自定义样式:style=”@style/ChildMyStyle”

上面都提到自定义主题,那么现在需要定制自己的主题,步骤:

(1)打开目录res/values下的styles.xml文件;

(2)添加resources的子标签:

说明:属性name指定名称ChildMyTheme,parent表示继承MyTheme的所有样式,改样式可以自定义也可以是系统的。item标签指定当前style/theme的样式,主题

item的那么属性值一定是与系统相符合的,比如字体颜色:

#0000ff。

//自定义控件之滑动移位小方快
package com.example.text1;
//自定义控件之滑动移位小方快

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.RegionIterator;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Scroller;

import androidx.annotation.Nullable;

public class SlideControl2 extends View {

    private int VIEW_HEIGHT;
    //滑动大方快的初始变量定义
    private int strokeLineColor_int;
    private int strokeCheckedSolidColor_int;
    private int strokeNoCheckedSolidColor_int;
    private int squareCheckedColor_int;
    private int squareNoCheckedColor_int;
    //
    private int squareChecked_int;
    private int squareStrokeColor_int;
    //当前按钮的开关状态
    private boolean isChecked = false;
    //圆的x轴圆心
    private float circle_x;

    private float circleEndX;
    private float circleStartX;
    private Paint mPaint;
    private Scroller mScroller;
    //边框矩形边框颜色
    private String StrokeLineColor = "#bebfc1";
    //边框矩形填充颜色
    private String StrokeSolidColor = "#00ffffff";
    //方块边框颜色
    private String SquareStrokeColor = "#abacaf";
    //方块checked填充颜色
    private String SquareCheckedColor = "#36648B";
    //方块非checked填充颜色

    private String SquareNoCheckedColor = "#668B8B";
    //    private String SquareNoCheckedColor = "#bebfc1";
    private int view_height_int;
    private int mWidth;
    private int mHeight;
    //控件内边距
    private static int PADDING = 20;
    //移动的判定距离
    private static int MOVE_DISTANCE = 50;
    //边框矩形的高
    private int strokeHeight;
    //边框矩形的半径
    private float strokeSquareRadius;
    private int centerY;
    private int centerX;
    //内部Square方块的半径
    private float squareRadius;
    //椭圆的边框宽度
    private static final int strokeLineWidth = 3;
    //圆的边框宽度
    private static final int squareStrokeWidth = 3;

    private float preX = 0;
    private boolean isMove;


    //状态改变监听
    public interface SlideControlOnCheckedListener {
        void onCheckedChangeListener(boolean isChecked);
    }

    private SlideControlOnCheckedListener mListener;


    public SlideControl2(Context context) {
        super(context);
        init(context);
    }

    public SlideControl2(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public SlideControl2(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }


    //是否是大方块 初始状态false
    private boolean isBigSquare = false;


    
    public void setBigSquareModel(int strokeLineColor, int strokeCheckedSolidColor,
                                  int strokeNoCheckedSoliderColor, int squareCheckedColor,
                                  int squareNoCheckedColor) {
        isBigSquare = true;
        strokeLineColor_int = strokeLineColor;
        strokeCheckedSolidColor_int = strokeCheckedSolidColor;
        strokeNoCheckedSolidColor_int = squareNoCheckedColor;
        squareCheckedColor_int = squareCheckedColor;
        squareNoCheckedColor_int = squareNoCheckedColor;
        invalidate();
    }

    
    public void setOnCheckedListener(SlideControlOnCheckedListener listener) {
        this.mListener = listener;
    }

    
    public void setChecked(boolean checked) {
        this.isChecked = checked;
        if (isChecked) {
            circle_x = circleEndX;
        } else {
            circle_x = circleStartX;
        }
        invalidate();
    }

    private void init(Context context) {
        setEnabled(true);
        setClickable(true);
        mPaint = new Paint();
        mScroller = new Scroller(context);
        view_height_int = dip2px(context, VIEW_HEIGHT);
        strokeLineColor_int = Color.parseColor(StrokeLineColor);
        strokeNoCheckedSolidColor_int = Color.parseColor(StrokeSolidColor);
        squareStrokeColor_int = Color.parseColor(SquareStrokeColor);
        squareChecked_int = Color.parseColor(SquareCheckedColor);
        squareNoCheckedColor_int = Color.parseColor(SquareNoCheckedColor);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);

        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        //a.当控件的layout_width或layout_height指定为wrap_content时,为AT_MOST
        //b.当控件的layout_width或layout_height指定为match_parent或具体数值时,为EXACTLY
        //处理wrap-content
        if (heightMode == MeasureSpec.AT_MOST) {
            //如果是wrap_content
            heightSize = view_height_int;
        }
        if (widthMode == MeasureSpec.AT_MOST) {
            widthSize = heightSize * 2;
        }
        setMeasuredDimension(widthSize, heightSize);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = w;
        mHeight = h;
        if (isBigSquare) {
            PADDING = h / 10;
            ;
        } else {
            PADDING = h / 15;
        }
        MOVE_DISTANCE = mWidth / 100;
        //边框矩形的高
        strokeHeight = h - PADDING * 2;
        //边框矩形的半径
        strokeSquareRadius = strokeHeight / 2;
        centerY = mHeight / 2;
        //内部方块的半径
        if (isBigSquare) {
            squareRadius = strokeSquareRadius + PADDING;
        } else {
            squareRadius = strokeSquareRadius - PADDING * 2;
        }
        Log.i("TAG", "mHeight:" + mHeight + "   strokeCircleRadius: " + strokeSquareRadius);
        //内部圆的x轴起始坐标
        circleStartX = PADDING + strokeSquareRadius;
        //内部圆的x轴终点坐标
        circleEndX = mWidth - circleStartX;
        if (isChecked) {
            circle_x = circleEndX;
        } else {
            circle_x = circleStartX;
        }
        //控件的中线
        centerX = mWidth / 2;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawRect(canvas);
        drawSquare(canvas);
    }

    //画边框矩形
    private void drawRect(Canvas canvas) {
        mPaint.reset();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);

        if (isBigSquare && isChecked) {
            mPaint.setColor(strokeCheckedSolidColor_int);
        } else {
            mPaint.setColor(strokeNoCheckedSolidColor_int);
        }
        //画填充
        canvas.drawRoundRect(PADDING, PADDING, mWidth - PADDING, mHeight - PADDING,
                strokeSquareRadius, strokeSquareRadius, mPaint);

        //画边框
        mPaint.setStrokeWidth(strokeLineWidth);
        mPaint.setColor(strokeLineColor_int);
        mPaint.setStyle(Paint.Style.STROKE);
        canvas.drawRect(PADDING, PADDING, mWidth - PADDING, mHeight - PADDING, mPaint);
    }

    //画里面的圆
    private void drawSquare(Canvas canvas) {

        mPaint.reset();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        float squareRadiusNew = squareRadius;
        if (isBigSquare) {
            squareRadiusNew -= squareStrokeWidth;
        }
        if (isChecked) {
            mPaint.setColor(squareChecked_int);
        } else {
            mPaint.setColor(squareNoCheckedColor_int);
        }
//        canvas.drawRect(PADDING, PADDING, mWidth - PADDING, (mHeight - PADDING) / 2, mPaint);
//        canvas.drawRoundRect(circle_x, circle_x * 2, (mWidth - circle_x), (mHeight - circle_x) / 8,
//                strokeSquareRadius, strokeSquareRadius, mPaint);
//        canvas.drawRect(circle_x, circle_x * 2, (mWidth - circle_x), (mHeight - circle_x) / 8, mPaint);//滑动变换颜色方块
        canvas.drawRect(circle_x - centerY + PADDING, PADDING, circle_x * 2, centerY * 2 - PADDING, mPaint);//十分正确的滑动移位小方块
//               canvas.drawCircle(circle_x, centerY, squareRadiusNew, mPaint);//滑动移位小圆

//        if (isBigSquare) {
//            //画圆的边
//            mPaint.setColor(squareStrokeColor_int);
//            mPaint.setStyle(Paint.Style.STROKE);
//            mPaint.setStrokeWidth(squareStrokeWidth);
//            canvas.drawCircle(circle_x, centerY, squareRadiusNew, mPaint);
//        }

//            Rect rect1 = new Rect(PADDING * 2, PADDING * 2, (mWidth - PADDING) , (mHeight - PADDING) / 2);
//        Rect rect1 = new Rect(PADDING * 2, PADDING * 2, centerY - PADDING , centerY - PADDING);
        //背景颜色
//            canvas.drawARGB(255, 139, 197, 186);
//        mPaint.setColor(0xff36648B);
//        mPaint.setStyle(Paint.Style.FILL);
//        mPaint.setStrokeWidth(10);
//
//        canvas.drawRect(rect1, mPaint);
//
//
//        //构造两个区域
//        Region region1 = new Region(rect1);
//
//
//        //构造一个填充画笔,将所选的区域用草绿色填充
//        Paint paint_fill = new Paint();
//        paint_fill.setColor(0xff668B8B);
//        paint_fill.setStyle(Paint.Style.FILL);
//        drawRegion(canvas, region1, paint_fill);
    }

//    //定义drawRegion()函数,将整个Region画出来
//    private void drawRegion(Canvas canvas, Region region1, Paint paint) {
//        RegionIterator iter = new RegionIterator(region1);
//        Rect r = new Rect();
//        while (iter.next(r)) {
//            canvas.drawRect(r, paint);
//        }
//    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                preX = event.getX();
                isMove = false;
                if (!isChecked) {
                    circle_x = PADDING + strokeSquareRadius;
                } else {
                    circle_x = mWidth - PADDING - strokeSquareRadius;
                }
                break;
            case MotionEvent.ACTION_MOVE:
                float move_x = event.getX();
                if (Math.abs(move_x - preX) > MOVE_DISTANCE) {
                    isMove = true;
                    if (move_x < circleStartX) {
                        circle_x = circleStartX;
                        isChecked = false;
                    } else if (move_x > circleEndX) {
                        circle_x = circleEndX;
                        isChecked = true;
                    } else {
                        circle_x = move_x;
                    }
                    invalidate();
                }
                break;
            case MotionEvent.ACTION_UP:
                if (isMove) {

                    //滑过中控线
                    if (circle_x >= centerX) {
                        //关闭(执行开启)
                        //源码:1000ms内滑向destX,效果就是慢慢滑动---scrollX起点横坐标,delta终点横坐标,1000ms时间
                        //mScroller.startScroll(scrollX,0,delta,0,1000)
                        mScroller.startScroll((int) circle_x, 0, (int) (circleEndX - circle_x), 0);
                        isChecked = true;
                    } else {
                        //开启(执行关闭)
                        mScroller.startScroll((int) circle_x, 0, (int) (circleStartX - circle_x), 0);
                        isChecked = false;
                    }
                } else {
                    //没有滑过中控线
                    if (!isChecked) {
                        //关闭(执行开启)
                        mScroller.startScroll((int) circle_x, 0, (int) (circleEndX - circle_x), 0);
                        isChecked = true;
                    } else {
                        //开启(执行关闭)
                        mScroller.startScroll((int) circle_x, 0, (int) (circleStartX - circle_x), 0);
                        isChecked = false;
                    }
                }
                if (mListener != null) {
                    mListener.onCheckedChangeListener(isChecked);
                }
                invalidate();
                break;
        }
        return super.onTouchEvent(event);
    }

    //实现弹性滑动--固定代码
    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            circle_x = mScroller.getCurrX();
            invalidate();
        }
    }

    
    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}




    

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1020274.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号