自定义View <0> 继承现有的控件

自定义类继承view实现自定义控件 自定义类继承view实现自定义控件,demo 立即下载

自定义View的 第一种形式继承现有的UI控件:实现特定功能,例如事件拦截,重新绘制。(继承某个控件,例如EditText,需要两个构造方法)

0:自定义View的步骤和使用:

继承View或者View的子类
声明构造方法
View(Context c) 这个构造方法在代码中创建控件的时候使用
View(Context ct,AttributeSet set)这个构造在布局xml文件中创建控件的时候自动的调用,如果自定义控件没有这个构造方法,就会抱错。报错地址:http://blog.youkuaiyun.com/rodulf/article/details/50915600,这个含有AttributeSet 的构造方法,应用于布局创建控件,这个AttribteSet attrs 就是XML里面的属性,通过这个属性传给控件,不然控件怎么知道高度时多少,宽度是多少,


1:继承已有的控件的方式
    如果要拦截,就重写onInterceptTouchEvent

    如果要重新绘制,那么就是重写onDraw()方法,onDraw方法是一个回调方法,当Android 要显示当前的控件到屏幕上的时候,就会回调这个方法,让控件自己把自己长什么样子画到屏幕上
canvas就是画布的意思,当控件在画布上面画完之后,最后由系统贴到屏幕上,记住是贴到屏幕上面的
如果上面的onDraw里面删除了super.onDraw(canvas)的话,是不会显示的,调整控件的显示:通过空间的onDraw 方法来修改,super.onDraw(canvas) 代表原有的空间显示方式;
canvas.drawArc可以用来画饼图
        canvas.drawBitmap();可以切图,按照等比切,drawBitmap还可以用来做穿衣和试衣的软件 。

/!!! 记住了一定不能在onDraw方法里面进行对象的创建,这样非常影响性能。

2:



+++++++++++

1: 游戏,股票,涂鸦
2:办公统计,柱状统计。
3: 电子书
4:听力测试


像大神一样写代码
-----------------------------------------
提升的地方:-----------------------------
-----------------------------------------
内置的UI空间和布局无法满足需求的时候,就需要进行外观,操作都是自定义的一些控件,
这个时候就要进行自定义View


-----------------------------------------
自定义View 的方式:
1)继承现有的UI空间:实现特定功能
2)将多个空间组合,形成新的自定义View:瀑布流,Radio动态指示器
3)完全自定义回执:自己来话出来外观,自己实现事件


自定义View 的步骤和使用:
1:继承View 或者View 的子类
2:申明构造方法
3:View(Context c)这个构造在代码中创建空间的时候使用
4:View(Context ct,AttributeSet set)这个构造在布局xml 文件中创建空间的时候自动调用。
如果自定义空间没有博啊汗带有AttributeSet的参数的构造方法,就会报异常。








新建一个CusomerView1


创建一个包widget
新建一个java类SimpleView




public class SimpleView extends EditText {


    /**
     * 任何控件,只有一个参数的构造方法,应用于代码创建控件
     * 例如 ImageView imageView = new ImageView(context);
     * @param context
     */
    public SimpleView(Context context) {
        super(context);
    }


    /**
     * 包含AttributeSet 的构造方法,应用于在布局文件中加载控件的情况。
     * AttributeSet 实际上就是包含了布局中的XML指定的属性;通过这个属性传给空间。
     * 这个方法在布局中创建空间的时候,是必须要调用和存在的,不然会抛出异常。
     * @param context
     * @param atts
     */
    public SimpleView(Context context,AttributeSet atts){
        super(context,atts);
    }
}




main 的xml


<!--包含自定义空间或者第三方控件或者Android Support 中的空间
    都可以通过类的全路劲来包含
    -->
    <com.kodulf.customerview1.widget.SimpleView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="#EE3344"
        android:hint="请输入您的内容"/>






修改:
public class SimpleView extends LinearLayout {




<com.kodulf.customerview1.widget.SimpleView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <TextView
            android:text="自定义View 里面添加一个View"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            />
        </com.kodulf.customerview1.widget.SimpleView>




在修改
public class SimpleView extends LinearLayout {




   <com.kodulf.customerview1.widget.SimpleView
            android:layout_width="match_parent"
            android:layout_height="_match_parent"
            android:background="#EE3344"/>




早上第二课
----------------------------------------------
----------------------------------------------
新建NotePad java 
shift+F6 修改名字




/**
 * 自定义View 案例1:继承已有空间的方式,实现记事本输入界面:
 */
public class NotePadView extends EditText{
    public NotePadView(Context context){
        //super(context);
        //通常,一个参数的构造,可以调用自身两个参数的
        this(context,null);
    }
    public NotePadView(Context context, AttributeSet attrs){
        super(context,attrs);
    }
}-------------------------------------------------------


重写onDraw()方法


去韩国,按照某个图片去话,这个图片就是onDraw();




    /**
     * 这个方法是一个回调方法,当Android 要显示当前控件到屏幕上的时候
     * 就会调用这个额方法啊,让控件自己把自己长什么样子画到屏幕上
     *
     * @param canvas Canvas 相当于一个画布,当空间在画布上面画完之后,最后由系统贴到屏幕上
     *               记住是贴到屏幕上的。
     */
    @Override
    protected void onDraw(Canvas canvas) {
        
        super.onDraw(canvas);
        //TODO: 绘制内容:


    }


如果上面的onDraw里面删除了super.onDraw(canvas)的话,是不会显示的


调整控件的显示:通过空间的onDraw 方法来修改
super.onDraw(canvas) 代表原有的空间显示方式;
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
drawArc()还可以画饼图,drawBitmap还可以切图,按照等比切,
                        //drawBitmap穿衣试衣的软件,还可以
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//android 代码当中,所有的和尺寸,坐标相关的单位,都是像素px
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


Carvas 绘制的时候,都需要设置Paint,


/!!!!注意android 控件的onDraw方法,是进制创建任何对象的;


光标显示一次,创建一次,所以不允许创建任何对象。


设置成员变量Paint


/**
     * 用于控制画线的样式;
     * 通常不要再onDraw创建,
     * 需要创建一个单独的初始化方法,
     */
    private Paint linePaint;






    /**
     * 用于初始化绘制时使用的各种对象数据;
     * @param context
     * @param set
     */
private void init(Context context,AttributeSet set){
            linePaint = new Paint();
linePaint.setColor(Color.RED);
    }


然后再在构造方法调用;
public NotePadView(Context context, AttributeSet attrs){
        super(context, attrs);
        init(context,attrs);
    }




更新:


protected void onDraw(Canvas canvas) {
        //对于已有空间而言,super.onDraw 代表原有内容的显示;
        super.onDraw(canvas);
        //TODO: 绘制内容:只要使用Canvase的绘制,就可以实现显示了;
        //Android 控件中,自身的左上角永远是(0,0)
        //右下角 就是(width,height)坐标轴
        //android 的整个屏幕,也是左上角(0,0)
        //android 代码当中,所有的和尺寸,坐标相关的单位,都是像素px
        //从(startX,startY)到(endX,endY)
        //!!!!注意android 控件的onDraw方法,是进制创建任何对象的;
        canvas.drawLine(
                0,//startX
                50,//startY
                200,//endX
                50,
        linePaint);//endY


                //drawArc()还可以画饼图,drawBitmap还可以切图,按照等比切,
                        //drawBitmap穿衣试衣的软件,还可以




    }


更新:
以空间的宽度来画:


        //继承已有空间:充分利用以后空间的方法和属性,完成功能
        //1.获取控件的宽度,
        int width =getWidth();
        canvas.drawLine(0,50,width,50,linePaint);




更新:
        //继承已有空间:充分利用以后空间的方法和属性,完成功能
        //1.获取控件的宽度,
        int width =getWidth();


        //2.对于EditText子类而言,需要获取一行的文本的高度,
        //因为可以设置textSize,通过 getLineHeight();来得到
        int lineHeight = getLineHeight();


        canvas.drawLine(0, lineHeight, width, lineHeight, linePaint);


这个时候会出现,会出现线在字体上面


解决方法如下:
android:background="#FFF"
//3. 在绘制的时候,需要考虑一个空间内部的padding 信息
        // 默认的情况下EditText包含顶部Padding






空间绘制的时候的注意事项:
1:需要考虑空间自身的padding,padding 影响了计算坐标的位置


更新:
//1.获取控件的宽度,
        int width =getWidth();


        //2.对于EditText子类而言,需要获取一行的文本的高度,
        //因为可以设置textSize,通过 getLineHeight();来得到
        int lineHeight = getLineHeight();
        //3. 在绘制的时候,需要考虑一个空间内部的padding 信息
        // 默认的情况下EditText包含顶部Padding
        //设置android:background="#FFF" 可以解决
        int paddingTop = getPaddingTop();


        canvas.drawLine(0, lineHeight+paddingTop, width, lineHeight+paddingTop, linePaint);
   


更新:


        //4。根据行数来绘制线段,
        //获取当当前输入框,实际内容的行数,
        int lineCount = getLineCount();
        for(int i=0;i<lineCount;i++){
            canvas.drawLine(0,paddingTop+lineHeight*(i+1),width,paddingTop+lineHeight*(i+1),linePaint);
        }


UPDATE:
int lineCount = getLineCount();
        for(int i=0;i<lineCount;i++){
            int lineY = paddingTop + lineHeight * (i + 1);
            canvas.drawLine(0, lineY,width, lineY,linePaint);
        }


更新:


//5. 获取高度,来第一次绘制的时候就绘制整个屏幕,需要减去paddingtop 和padding bottom
        int height = getHeight();
        //获取padding bottom 计算实际内容高度
        int paddingBottom = getPaddingBottom();
        int num = (height - paddingBottom - paddingTop)/lineHeight;
        int lineCount = getLineCount();
        lineCount = Math.max(lineCount,num);


        for(int i=0;i<lineCount;i++){
            int lineY = paddingTop + lineHeight * (i + 1);
            canvas.drawLine(0, lineY,width, lineY,linePaint);
        }




下午:
------------------------------------------------------------
------------------------------------------------------------
在onDraw方法,不允许创建对象:


在onDraw方法,里面打印Log。


这个方法什么也不动,它每隔0.5秒绘制一次。
和光标的闪烁一样的频率。


如果在这里面
new int[1024*1024] 
移动的时候也会分配,所以这个会让程序非常非常慢。


所以不要再onDraw方法创建对象。


Android 自己的操作系统,正式的绘制的频率是16ms绘制一次。


每一个控件都有自己的绘制频率。


例如EditText 0.5s一次。它用在光标的闪烁。


--------------------------------------------------------------
--------------------------------------------------------------


自定义的属性


我们想要加入
lineColor="#0F0" 


这个时候需要我们自己添加:


在values 文件夹,添加一个values 文件叫做attr.xml


btw:
format 的num 可以用来形容orientation 这样的属性


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!--自定义属性的声明-->


    <!--name 通常推荐是类名,这样好区别
    可以认为是给某一个对应的空间声明属性
    -->
    <declare-styleable name="NotePadView">
        <!--attr代表定义的属性名称,相当于NotePadView内部支持属性定义-->
            <attr name="lineColor" format="color"/>
        <!--定义一个名称为lineHeight的属性,内容是尺寸-->
        <attr name="lineHeigth" format="dimension"/>
    </declare-styleable>
</resources>




这个时候就可以添加 app:lineColor="#0F0"


通常命名空间的名称是app,是自动生成的,实际上就是xml命名空间;


在main的xml 里面自动导入了:
xmlns:app="http://schemas.android.com/apk/res-auto"


这个时候设置还没有完全的好。


还需要在代码中获取自定义属性;


更新init 如下:
private void init(Context context,AttributeSet set){
            linePaint = new Paint();
        //linePaint.setColor(Color.RED);
        //TODO: 从AttributeSet获取属性配置,来设置横线的属性


        int lineColor = Color.RED;




        if(set!=null) {
            //获取属性集合中的lineColor属性
            //获取自定义属性操作步骤:
            //1.先获取指定的,在attrs.xml中定义的那个属性集合declare-style
            //代表的内容
            //obtainStyledAttributes(); 获取自定义属性,需要AttributeSet才可以




            TypedArray array = context.obtainStyledAttributes(
                    set,//包含了xml 中当前控件的所有属性 android:,app:这两种开头的
                    R.styleable.NotePadView//获取针对NotePadView 的所有属性。
            );
            //获取颜色属性,
            //参数一:index,就是android中自定义属性的索引,
            int color = array.getColor(
                    R.styleable.NotePadView_lineColor,//通过常量已经定义好了index了
                    Color.RED
            );
            linePaint.setColor(color);
            //TypedArray 对象在使用完之后,必须要被回收
            
float dimension = array.getDimension(R.styleable.NotePadView_lineHeigth, 5.5f);
            linePaint.setStrokeWidth(dimension);


array.recycle();
        }
}


------------------------------------------------------------
----------------------------------------------------------------
组合控件,事件分发。
组合方式的自定义View
listView 就是一个组合布局
ViewPager 也是一个组合布局
AutoComplementTextView,Spinner 也都是的。


常见的第三方控件:
1:瀑布流,
2:拨号盘
3:侧滑菜单
4:Path按钮,
5:水纹进度
6:事件滚轮


---------------------------------------------------------------------
----------------------------------------------------------------------
继承ViewGroup 以及ViewGroup 的子类


新建一个java 文件AlphaIndicator


/**
 * 通过组合的形式,实现字模选择的功能
 * 采用组合控件的形式。
 */
public class AlphaIndicator extends LinearLayout {
    public AlphaIndicator(Context context) {
        //super(context); 这个也行,下面的也行
        this(context,null);
    }


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


    private void init(Context context,AttributeSet attrs){
            //TODO:初始化各种内容和各种属性
        //1.添加A-Z 26个字母
        char ch;
        for (int i = 0; i <26; i++) {
            ch =(char)('A'+i);
            TextView  textView = new TextView(context);
            textView.setText(Character.toString(ch));
            //关于layoutParams,通过LayoutParams 可以给一个控件设置相应的布局属性,
            //控件添加到哪一种布局中,就是用这个布局的LayoutParams的对象来设置。
            //例如控件添加到LinearLayout ,那么个给这个空间设置的就是
            //LinearLayout.LayoutParams 对应的就是android:layout_xxx
            LinearLayout.LayoutParams lp = new LayoutParams(
                    //32,//像素单位的实际数值,或者是WRAP_CONTENT,MATCH_PARENT
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    0,//0高度,因为使用权重,让控件填满布局,
                    1//weight 对应layout_weight="1"
            );


            textView.setLayoutParams(lp);//设置布局参数
            //设置textSize 属性
            textView.setTextSize(TypedValue.COMPLEX_UNIT_SP,20);


            //添加进
            addView(textView);
        }


    }
}




<com.kodulf.customerview1.widget.AlphaIndicator
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="vertical"
        ></com.kodulf.customerview1.widget.AlphaIndicator>




更新完善:
//设置Android:gravity
            textView.setGravity(Gravity.CENTER);
            textView.setTextColor(Color.RED);




--------------------------------------------------------------
-----------------------------------------------------------------------


组合控件里面的事件处理


1:控件的触摸事件分为两种形式:
1)控件自身的onTouchEvent(...),控件自己来实现和处理触摸事件,是一种默认的处理
2) 给空间设置的setOnTouchListener();外部来设置触摸事件的处理【表情】可以覆盖onTouchEvent();
默认的处理;
2:通常对于自定义空间而言,可以采用onTouchEvent,外部将setOnTouchListener 留给外部代码;
3:触摸事件的类型:DOWN,MOVE,UP等,
4:ACTION_DOWN, 如果
//!!!!!如果ACTION_DOWN的状态,返回true 代表当前控件需要继续
                //执行其他状态的监控;如果返回false,或者super调用,
                //都不会再收到触摸事件了;
--------------------------------------------------------------------------------------




    /**
     * 空间自身处理触摸屏幕的事件
     * @param event
     * @return true 代表当前时间处理完成,芙蓉起不要再处理;false,代表芙蓉起还可以继续处理
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //action 代表触摸的操作状态。
        int action = event.getAction();
        String type="";
        switch (action){
            case MotionEvent.ACTION_DOWN:
                //所有的触摸屏幕操作都是从ACTION_DOWN开始的,也就是手指按下开始
                //!!!!!如果ACTION_DOWN的状态,返回true 代表当前控件需要继续
                //执行其他状态的监控;如果返回false,或者super调用,
                //都不会再收到触摸事件了;
                type="DOWN";
                break;
            case MotionEvent.ACTION_MOVE:
                //手指移动
                type="MOVE";
                break;
            case MotionEvent.ACTION_UP:
                type="UP";
                //手指离开屏幕
                break;
        }
        Log.d("151222MY", type);
        return super.onTouchEvent(event);
    }
上面只会显示DOWN
//!!!!!如果ACTION_DOWN的状态,返回true 代表当前控件需要继续
                //执行其他状态的监控;如果返回false,或者super调用,
                //都不会再收到触摸事件了;
--------------------------------------------------------


更新:
/**
     * 空间自身处理触摸屏幕的事件
     * @param event
     * @return true 代表当前时间处理完成,芙蓉起不要再处理;false,代表芙蓉起还可以继续处理
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
---》        boolean ret = false;
        //action 代表触摸的操作状态。
        int action = event.getAction();
        String type="";
        switch (action){
            case MotionEvent.ACTION_DOWN:
                //所有的触摸屏幕操作都是从ACTION_DOWN开始的,也就是手指按下开始
                //!!!!!如果ACTION_DOWN的状态,返回true 代表当前控件需要继续
                //执行其他状态的监控;如果返回false,或者super调用,
                //都不会再收到触摸事件了;
                type="DOWN";
---》                ret=true;
                break;
            case MotionEvent.ACTION_MOVE:
                //手指移动
                type="MOVE";
                break;
            case MotionEvent.ACTION_UP:
                type="UP";
                //手指离开屏幕
                break;
        }
        Log.d("151222MY", type);
        //return super.onTouchEvent(event);
---》        return ret;
    }






------------------------------------------------------------------------------------------
    /**
     * 使用成员变量,进行上一次选中位置的保存,
     * 便面多次选中线通的位置,
     * 因为mover的动作会执行多次。
     */
private int currentPosition = -1;
    /**
     * 空间自身处理触摸屏幕的事件
     * @param event
     * @return true 代表当前时间处理完成,芙蓉起不要再处理;false,代表芙蓉起还可以继续处理
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        boolean ret = false;
        //action 代表触摸的操作状态。
        int action = event.getAction();


        //触摸事件包含x,y
        float ex = event.getX();
        float ey = event.getY();
        //Log.d("151222MY","x:"+ex+" y:"+ey);
        //TODO:事件相对于手机屏幕的x,y如何获取


        String type="";
        switch (action){
            case MotionEvent.ACTION_DOWN:
                //所有的触摸屏幕操作都是从ACTION_DOWN开始的,也就是手指按下开始
                //!!!!!如果ACTION_DOWN的状态,返回true 代表当前控件需要继续
                //执行其他状态的监控;如果返回false,或者super调用,
                //都不会再收到触摸事件了;
                type="DOWN";
                //因为每次按下 是新的触摸事件刘晨给,那么续重位置清空,
                currentPosition=-1;
                ret=true;
                break;
            case MotionEvent.ACTION_MOVE:
                //手指移动
                type="MOVE";
                int count = getChildCount();//获取内部的控件个数,根据空间个数,找到手机放在那个位置上了
                int position =-1;
                for(int i=0;i<count;i++){
                    View view = getChildAt(i);
//                    float viewX = view.getX();
//                    float viewY = view.getY();
                    float viewX = view.getLeft();
                    float viewY = view.getTop();


                    int viewRight = view.getRight();
                    int viewBottom = view.getBottom();


                    if(ex>=viewX&&ex<=viewRight){
                        if(ey>=viewY&&ey<=viewBottom){
                           //当前点中了,这个控件
                            position=i;
                            break;
                        }
                    }
                }


                if(position>-1&&position!=currentPosition){
                   // Toast.makeText(getContext(),"选中:"+position,Toast.LENGTH_SHORT).show();
                    Log.d("151222MY","选中:"+position);
                    currentPosition=position;
                }
                break;
            case MotionEvent.ACTION_UP:
                type="UP";
                //手指离开屏幕
                break;
        }
        //Log.d("151222MY", type);
        //return super.onTouchEvent(event);
        return ret;
    }






-----------------------------------------------------------------
更新:
if(position>-1&&position!=currentPosition){
                    View v = getChildAt(position);
                    String alpha =(String)v.getTag();
                   // Toast.makeText(getContext(),"选中:"+position,Toast.LENGTH_SHORT).show();
                    //Log.d("151222MY","选中:"+position);
                    Log.d("151222MY","选中:"+alpha);
                    currentPosition=position;
                }


更新 添加textView.setTag(ch);到下面的方法中。
private void init(Context context,AttributeSet attrs){
            //TODO:初始化各种内容和各种属性
        //1.添加A-Z 26个字母
        char ch;
        for (int i = 0; i <26; i++) {
            ch =(char)('A'+i);
            TextView  textView = new TextView(context);
            textView.setText(Character.toString(ch));
            textView.setTag(ch);





PINN——加入物理约束的神经网络 【摘要】 基于物理信息的神经网络(Physics-informed Neural Network, 简称PINN),是一类用于解决有监督学习任务的神经网络,它不仅能够像传统神经网络一样学习到训练数据样本的分布规律,而且能够学习到数学方程描述的物理定律。与纯数据驱动的神经网络学习相比,PINN在训练过程中施加了物理信息约束,因而能用更少的数据样本学习到更具泛化能力的模型。本文主要解析这种神经网络以... 阅读详情

相关推荐

DM-VIO论文精读:从‘延迟边缘化’到‘位姿图BA’,手把手拆解单目VIO性能超越双目的秘密

本文深入解析DM-VIO技术如何通过延迟边缘化和位姿图BA创新,解决单目视觉惯性里程计(VIO)的尺度不可观性问题,并在精度上超越传统双目系统。文章详细介绍了延迟边缘化的双因子图结构设计、位姿图BA的多级初始化策略,以及系统级优化带来的性能提升,为VIO研究与实践提供了重要参考。

weixin_30616969的博客 427

Android 自定义View第三弹——继承控件

概述:本篇为自定义控件实现方式第二种—继承控件。在本篇中将以一个栗子来展现继承控件的实现方式。一 继承控件的定义继承已有的控件,创建新控件,保留继承的父控件的特性,并且还可以引入新特性。二 自定义继承控件的步骤1 我们需要继承一个具体的控件 比如 textView imageView 2 自定义属性 3 获取自定义属性 4 设置需要显示的ui 4 重写onDraw方法 5 处理特殊的事

做最好的自己 568

DIY T12烙铁头驱动难题:用几个电容二极管,搞定NMOS上管驱动(附Multisim仿真)

本文详细介绍了如何利用电荷泵电路解决DIY T12烙铁头驱动中的NMOS上管驱动难题。通过巧妙组合电容和二极管,构建低成本高效的升压电路,实现栅极高压驱动需求。文章包含具体电路设计、元件选型建议、实际搭建注意事项以及Multisim仿真验证,为电子爱好者提供了一套完整的解决方案。

weixin_33640562的博客 334

Android自定义控件View(二)继承控件

在前一篇博客中学习了Android自定义控件View的流程步骤和注意点,不了解的童鞋可以参考Android自定义控件View(一)。这一节开始学习自定义控件View(二)之继承系统已有的控件。我们来自定义一个圆形ImageView。RoundImageView随着Android UI效果越来越炫,很多系统自带的控件已经无法满足日常开发需求,比如很多应用的头像是圆形的,QQ头像就是圆形的图片。但是An

废墟的树的专栏 5110

基于STM32的智能垃圾分类机器人

垃圾分类是城市管理的重要环节,传统人工分拣效率低、成本高。本文设计了一款基于STM32的智能垃圾分类机器人,通过视觉识别与机械臂协同作业,实现垃圾自动分类与投放,适用于社区、公共场所等场景,可显著提升垃圾分类效率。:STM32H743(480MHz Cortex-M7,支持AI加速)本系统实现了垃圾分拣的自动化,显著提升了分类效率。OV5640摄像头(500万像素,支持JPEG输出)支持4类垃圾识别(可回收/厨余/有害/其他)问题讨论,stm32的资料领取可以私信!超声波避障(探测距离0.1-4m)

stm32d1219的博客 1820

群晖NAS下docker安装MySql

本文将一步一步讲解如何在群晖NAS的docker中启用一个MySQL容器 , 算是初学者对问题解决的一个记录.

qq_46375248的博客 5977

Android自定义View的三种方式:继承布局,继承原生控件,继承View

文章目录 简介 一、继承布局 效果图 代码实现 1.在layout文件夹中创建布局title_view.xml 2.在values文件夹中新建attrs.xml,在其中声明自定义属性 3.新建CustomTitleView文件,并重写三个构造方法 4.找到控件并获取属性 4.1.使用TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs,R.styleable.CustomTitleView,defStyleAttr,0

Howard_Liu1314的专栏 2249

电子设计实战:用MOS管手把手搭建D触发器电路(含时序分析避坑指南)

本文详细介绍了如何使用MOS管从零开始搭建D触发器电路,重点解析了建立时间和保持时间等关键时序参数对电路稳定性的影响。通过实测波形分析和避坑指南,帮助电子工程师掌握D触发器的实际搭建技巧与优化方法,提升数字电路设计的可靠性。

x1y2z的博客 1162

android自定义控件(基于原有控件,即继承自view)

今天学了如何在android中自定义控件,感觉收获挺大的,和大家分享一下。直接上代码吧,代码中有注释,很容易理解的。 package com.cwx.mytitle; import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawable.Draw

心之痕 6366

Oracle EBS与SAP数据数据切换至迁移华为MetaERP分析

Oracle EBS到华为MetaERP的数据迁移可采用“表对表复制”思路,因其模块化设计下数据模型标准化、边界清晰。核心业务对象存储在结构明确的主表中,与MetaERP模型兼容度高,便于直接映射。而SAP到MetaERP的迁移则因SAP高度优化的复杂表结构(如簇表/池表)、数据分散冗余、深度依赖配置等特点,无法简单复制,必须采用基于业务对象的迁移方法,通过视图/BAPI提取数据并进行深度转换。两种迁移的本质差异源于源系统的数据模型设计理念不同。

金牌架构师 1379

回答网友提问:Word 里如何调用 DeepSeek API?

上面的 Visual Basic 定义了名叫 DeepSeekV3 的 subroutine,同理我们可以让 Trae 再写一个调用开启了 DeepThink(R1) 模式的 DeepSeek API,步骤类似,这里不再赘述。在 Word 的 File->Options 选项里,选择 Customize Ribbon,将 Developer 标签从左侧移到右侧,然后在 Developer 标签下新建一个 Group,随便起个名称。API 调用的 response,自动填充到了 Word 里。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 275

Android 自定义控件之继承view

一.自定义控件的类型:            1.继承view            2.继承已有原生控件            3.自定义组合控件 本次要讲解的是继承自view的控件,那么除了Android系统原生的view的属性之外,我们还可以自定义控件的属性 二.自定义view控件的步骤       1.首先,在项目res/values目录下新建attrs.xml,声明属性

aurora_bessie的博客 1102

【考试大纲】中级多媒体应用设计师考试大纲

中级多媒体应用设计师考试大纲

邓邓子的博客 382

android 继承现有控件,Android 自定义View 三板斧之一——继承现有控件

通常情况下,Android实现自定义控件无非三种方式。Ⅰ、继承现有控件,对其控件的功能进行拓展。Ⅱ、将现有控件进行组合,实现功能更加强大控件。Ⅲ、重写View实现全新的控件本文重点讨论继承现有控件进行拓展实现自定义控件。这是一个非常重要的自定义控件的方法,可以站在原生控件这个巨人肩膀上,拓展自身的功能,一般来说,我们可以在ondraw方法中对原生控件进行绘制。本文将以拓展textView为例,看我...

weixin_39857211的博客 194

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Android 自定义控件

Android 自定义控件是指开发者根据项目需求,通过继承现有的控件或直接继承 View 类,定制开发的控件。与系统提供的标准控件相比,自定义控件通常具有更加个性化的样式、功能和行为,能够更好地满足特定的 UI 设计要求和用户体验需求。自定义控件可以应用于各种需求,例如:自定义按钮、图表、动画效果、复杂的布局、响应特定交互等。其核心目的是增强应用的灵活性和可定制性。这种方式通过继承 Android 系统提供的标准控件,重写其方法来实现自定义的功能或样式。

L1442760086的博客 1803

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Android 从0开始自定义控件之 自定义 View 基础实例(十)

> 转载请标明出处: [http://blog.youkuaiyun.com/airsaid/article/details/54294144](http://blog.youkuaiyun.com/airsaid/article/details/54294144) > 本文出自:[周游的博客](http://blog.youkuaiyun.com/airsaid) [TOC] # 前言 在前面的博客当中,我们学习了 View 的一

Airsaid 6927

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

android自定义view

在Android开发中有很多业务场景,原生的控件是无法满足应用,并且经常也会遇到一个UI在多处 重复使用情况,那么就需要通过自定义View的方式来实现这些UI效果。作为一个Android开发工程师自定义View属于一个必备技能。自定义View的实现方式有以下几种: 组合控件,继承控件,自绘控件详细可分为:自定义组合控件,继承系统View控件,继承系统ViewGroup,自绘View控件,自绘ViewGroup控件组合控件就是将多个控件组合成一个新的控件,可以重复使用。...

shuo277的博客 1万+

Android 自定义属性,自定义控件、自定义View以及View的常见Error

Android 自定义属性,自定义控件、自定义View 自定义属性 1 要使用 系统的属性 可以使用所继承的控件的属性 如继承的TextView 或者 View 则相关的属性都可以不用声明直接使用 2 否则 要styleable中定义 &amp;amp;amp;amp;amp;amp;lt;attr name=&amp;amp;amp;amp;amp;quot;android:text&amp;amp;amp;amp;amp;quot; /&amp;a

5ingwings(SiHao)的博客 8410

安卓开发如何实现自定义View

自定义属性需要单独写一个文件,一般放在res/values目录下,文件名命名为attrs表明是自定义属性集,这个属性就是在xml文件中进行设置的属性,类似TextView的textColortextSize这种属性</</在布局文件中使用和正常使用控件几乎没区别,不过注意自定义控件要写对应的全限定名就是我们自定义的属性了。

2401_86909484的博客 1039

android 继承现有控件,Android继承现有控件拓展实现自定义控件textView

通常情况下,android实现自定义控件无非三种方式。ⅰ、继承现有控件,对其控件的功能进行拓展。ⅱ、将现有控件进行组合,实现功能更加强大控件。ⅲ、重写view实现全新的控件本文重点讨论继承现有控件进行拓展实现自定义控件。这是一个非常重要的自定义控件的方法,可以站在原生控件这个巨人肩膀上,拓展自身的功能,一般来说,我们可以在ondraw方法中对原生控件进行绘制。本文将以拓展textview为例,看我...

weixin_28406969的博客 198

Android 自定义控件:继承View

在自定义控件中,一种类型就是继承自 View,通过画笔,从无到有画出一个符合需求的控件。在工作中,相机模块中,需要做一个点击后的聚焦框,就是通过继承 View,从无到有画出来的。 实现代码如下: package cn.zzw.customview.custom.view; import android.content.Context; import android.graphics.Can...

接受自己的普通,然后拼尽全力去与众不同 486

Android自定义控件终极指南

Android自定义控件开发指南摘要:Android应用可通过两种方式实现自定义控件:1)继承现有控件扩展功能(如TextView),适合外观修改;2)继承View类完全自定义(如仪表盘),需重写onDraw等方法。开发步骤包括:创建子类、实现构造方法、重写核心方法(onDraw/onMeasure)、添加自定义属性(通过attrs.xml)。使用时需注意wrap_content支持、性能优化和复合控件实现。官方推荐优先继承现有控件,完全自定义时需掌握Canvas绘图技术。两种方式均需在XML布局中声明完整

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 1337
上一篇: 自定义View的实现
下一篇: 自定义View<1> 多个控件进行组合形成新的自定义控件
千雅爸爸
博客等级 码龄18年 292粉丝 639原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值