Android 自定义控件,继承控件,组合控件

自定义控件——初识自定义控件 本文出自 “阿敏其人” 简书博客,转载或引用请注明出处。开发的时候,因为业务需求或者封装需要,我们会进行自定义控件。 说在前面,本篇涉及到一些东西 * onMeasure * onLayout * onDraw * MeasureSpec (32位二进制数,头两位模式(Mode),后两位大小(Size)) * onFinishInflate * ViewGr 阅读详情

一、自绘控件

自绘控件的意思就是,这个View上所展现的内容全部都是我们自己绘制出来的。绘制的代码是写在onDraw()方法中的,

下面我们准备来自定义一个计数器View,这个View可以响应用户的点击事件,并自动记录一共点击了多少次。新建一个CounterView继承自View,代码如下所示:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class CounterView extends View implements OnClickListener {  
  2.   
  3.     private Paint mPaint;  
  4.       
  5.     private Rect mBounds;  
  6.   
  7.     private int mCount;  
  8.       
  9.     public CounterView(Context context, AttributeSet attrs) {  
  10.         super(context, attrs);  
  11.         mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
  12.         mBounds = new Rect();  
  13.         setOnClickListener(this);  
  14.     }  
  15.   
  16.     @Override  
  17.     protected void onDraw(Canvas canvas) {  
  18.         super.onDraw(canvas);  
  19.         mPaint.setColor(Color.BLUE);  
  20.         canvas.drawRect(0, 0, getWidth(), getHeight(), mPaint);  
  21.         mPaint.setColor(Color.YELLOW);  
  22.         mPaint.setTextSize(30);  
  23.         String text = String.valueOf(mCount);  
  24.         mPaint.getTextBounds(text, 0, text.length(), mBounds);  
  25.         float textWidth = mBounds.width();  
  26.         float textHeight = mBounds.height();  
  27.         canvas.drawText(text, getWidth() / 2 - textWidth / 2, getHeight() / 2  
  28.                 + textHeight / 2, mPaint);  
  29.     }  
  30.   
  31.     @Override  
  32.     public void onClick(View v) {  
  33.         mCount++;  
  34.         invalidate();  
  35.     }  
  36.   
  37. }  
可以看到,首先我们在CounterView的构造函数中初始化了一些数据,并给这个View的本身注册了点击事件,这样当CounterView被点击的时候,onClick()方法就会得到调用。而onClick()方法中的逻辑就更加简单了,只是对mCount这个计数器加1,然后调用invalidate()方法。通过  Android视图状态及重绘流程分析,带你一步步深入了解View(三)  这篇文章的学习我们都已经知道,调用invalidate()方法会导致视图进行重绘,因此onDraw()方法在稍后就将会得到调用。

既然CounterView是一个自绘视图,那么最主要的逻辑当然就是写在onDraw()方法里的了,下面我们就来仔细看一下。这里首先是将Paint画笔设置为蓝色,然后调用Canvas的drawRect()方法绘制了一个矩形,这个矩形也就可以当作是CounterView的背景图吧。接着将画笔设置为黄色,准备在背景上面绘制当前的计数,注意这里先是调用了getTextBounds()方法来获取到文字的宽度和高度,然后调用了drawText()方法去进行绘制就可以了。

这样,一个自定义的View就已经完成了,并且目前这个CounterView是具备自动计数功能的。那么剩下的问题就是如何让这个View在界面上显示出来了,其实这也非常简单,我们只需要像使用普通的控件一样来使用CounterView就可以了。比如在布局文件中加入如下代码:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:layout_width="match_parent"  
  3.     android:layout_height="match_parent" >  
  4.   
  5.     <com.example.customview.CounterView  
  6.         android:layout_width="100dp"  
  7.         android:layout_height="100dp"  
  8.         android:layout_centerInParent="true" />  
  9.   
  10. </RelativeLayout>  
可以看到,这里我们将CounterView放入了一个RelativeLayout中,然后可以像使用普通控件来给CounterView指定各种属性,比如通过layout_width和layout_height来指定CounterView的宽高,通过android:layout_centerInParent来指定它在布局里居中显示。只不过需要注意,自定义的View在使用的时候一定要写出完整的包名,不然系统将无法找到这个View。

好了,就是这么简单,接下来我们可以运行一下程序,并不停地点击CounterView,效果如下图所示。


怎么样?是不是感觉自定义View也并不是什么高级的技术,简单几行代码就可以实现了。当然了,这个CounterView功能非常简陋,只有一个计数功能,因此只需几行代码就足够了,当你需要绘制比较复杂的View时,还是需要很多技巧的。

二、组合控件

组合控件的意思就是,我们并不需要自己去绘制视图上显示的内容,而只是用系统原生的控件就好了,但我们可以将几个系统原生的控件组合到一起,这样创建出的控件就被称为组合控件。

举个例子来说,标题栏就是个很常见的组合控件,很多界面的头部都会放置一个标题栏,标题栏上会有个返回按钮和标题,点击按钮后就可以返回到上一个界面。那么下面我们就来尝试去实现这样一个标题栏控件。

新建一个title.xml布局文件,代码如下所示:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="50dp"  
  5.     android:background="#ffcb05" >  
  6.   
  7.     <Button  
  8.         android:id="@+id/button_left"  
  9.         android:layout_width="60dp"  
  10.         android:layout_height="40dp"  
  11.         android:layout_centerVertical="true"  
  12.         android:layout_marginLeft="5dp"  
  13.         android:background="@drawable/back_button"  
  14.         android:text="Back"  
  15.         android:textColor="#fff" />  
  16.   
  17.     <TextView  
  18.         android:id="@+id/title_text"  
  19.         android:layout_width="wrap_content"  
  20.         android:layout_height="wrap_content"  
  21.         android:layout_centerInParent="true"  
  22.         android:text="This is Title"  
  23.         android:textColor="#fff"  
  24.         android:textSize="20sp" />  
  25.   
  26. </RelativeLayout>  

在这个布局文件中,我们首先定义了一个RelativeLayout作为背景布局,然后在这个布局里定义了一个Button和一个TextView,Button就是标题栏中的返回按钮,TextView就是标题栏中的显示的文字。

接下来创建一个TitleView继承自FrameLayout,代码如下所示:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class TitleView extends FrameLayout {  
  2.   
  3.     private Button leftButton;  
  4.   
  5.     private TextView titleText;  
  6.   
  7.     public TitleView(Context context, AttributeSet attrs) {  
  8.         super(context, attrs);  
  9.         LayoutInflater.from(context).inflate(R.layout.title, this);  
  10.         titleText = (TextView) findViewById(R.id.title_text);  
  11.         leftButton = (Button) findViewById(R.id.button_left);  
  12.         leftButton.setOnClickListener(new OnClickListener() {  
  13.             @Override  
  14.             public void onClick(View v) {  
  15.                 ((Activity) getContext()).finish();  
  16.             }  
  17.         });  
  18.     }  
  19.   
  20.     public void setTitleText(String text) {  
  21.         titleText.setText(text);  
  22.     }  
  23.   
  24.     public void setLeftButtonText(String text) {  
  25.         leftButton.setText(text);  
  26.     }  
  27.   
  28.     public void setLeftButtonListener(OnClickListener l) {  
  29.         leftButton.setOnClickListener(l);  
  30.     }  
  31.   
  32. }  
TitleView中的代码非常简单,在TitleView的构建方法中,我们调用了LayoutInflater的inflate()方法来加载刚刚定义的title.xml布局,这部分内容我们已经在  Android LayoutInflater原理分析,带你一步步深入了解View(一)  这篇文章中学习过了。

接下来调用findViewById()方法获取到了返回按钮的实例,然后在它的onClick事件中调用finish()方法来关闭当前的Activity,也就相当于实现返回功能了。

另外,为了让TitleView有更强地扩展性,我们还提供了setTitleText()、setLeftButtonText()、setLeftButtonListener()等方法,分别用于设置标题栏上的文字、返回按钮上的文字、以及返回按钮的点击事件。

到了这里,一个自定义的标题栏就完成了,那么下面又到了如何引用这个自定义View的部分,其实方法基本都是相同的,在布局文件中添加如下代码:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.     <com.example.customview.TitleView  
  7.         android:id="@+id/title_view"  
  8.         android:layout_width="match_parent"  
  9.         android:layout_height="wrap_content" >  
  10.     </com.example.customview.TitleView>  
  11.   
  12. </RelativeLayout>  

这样就成功将一个标题栏控件引入到布局文件中了,运行一下程序,效果如下图所示:


现在点击一下Back按钮,就可以关闭当前的Activity了。如果你想要修改标题栏上显示的内容,或者返回按钮的默认事件,只需要在Activity中通过findViewById()方法得到TitleView的实例,然后调用setTitleText()、setLeftButtonText()、setLeftButtonListener()等方法进行设置就OK了。

三、继承控件

继承控件的意思就是,我们并不需要自己重头去实现一个控件,只需要去继承一个现有的控件,然后在这个控件上增加一些新的功能,就可以形成一个自定义的控件了。这种自定义控件的特点就是不仅能够按照我们的需求加入相应的功能,还可以保留原生控件的所有功能,

为了能够加深大家对这种自定义View方式的理解,下面我们再来编写一个新的继承控件。ListView相信每一个Android程序员都一定使用过,这次我们准备对ListView进行扩展,加入在ListView上滑动就可以显示出一个删除按钮,点击按钮就会删除相应数据的功能。

首先需要准备一个删除按钮的布局,新建delete_button.xml文件,代码如下所示:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <Button xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:id="@+id/delete_button"  
  4.     android:layout_width="wrap_content"  
  5.     android:layout_height="wrap_content"  
  6.     android:background="@drawable/delete_button" >  
  7.   
  8. </Button>  
这个布局文件很简单,只有一个按钮而已,并且我们给这个按钮指定了一张删除背景图。

接着创建MyListView继承自ListView,这就是我们自定义的View了,代码如下所示:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class MyListView extends ListView implements OnTouchListener,  
  2.         OnGestureListener {  
  3.   
  4.     private GestureDetector gestureDetector;  
  5.   
  6.     private OnDeleteListener listener;  
  7.   
  8.     private View deleteButton;  
  9.   
  10.     private ViewGroup itemLayout;  
  11.   
  12.     private int selectedItem;  
  13.   
  14.     private boolean isDeleteShown;  
  15.   
  16.     public MyListView(Context context, AttributeSet attrs) {  
  17.         super(context, attrs);  
  18.         gestureDetector = new GestureDetector(getContext(), this);  
  19.         setOnTouchListener(this);  
  20.     }  
  21.   
  22.     public void setOnDeleteListener(OnDeleteListener l) {  
  23.         listener = l;  
  24.     }  
  25.   
  26.     @Override  
  27.     public boolean onTouch(View v, MotionEvent event) {  
  28.         if (isDeleteShown) {  
  29.             itemLayout.removeView(deleteButton);  
  30.             deleteButton = null;  
  31.             isDeleteShown = false;  
  32.             return false;  
  33.         } else {  
  34.             return gestureDetector.onTouchEvent(event);  
  35.         }  
  36.     }  
  37.   
  38.     @Override  
  39.     public boolean onDown(MotionEvent e) {  
  40.         if (!isDeleteShown) {  
  41.             selectedItem = pointToPosition((int) e.getX(), (int) e.getY());  
  42.         }  
  43.         return false;  
  44.     }  
  45.   
  46.     @Override  
  47.     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,  
  48.             float velocityY) {  
  49.         if (!isDeleteShown && Math.abs(velocityX) > Math.abs(velocityY)) {  
  50.             deleteButton = LayoutInflater.from(getContext()).inflate(  
  51.                     R.layout.delete_button, null);  
  52.             deleteButton.setOnClickListener(new OnClickListener() {  
  53.                 @Override  
  54.                 public void onClick(View v) {  
  55.                     itemLayout.removeView(deleteButton);  
  56.                     deleteButton = null;  
  57.                     isDeleteShown = false;  
  58.                     listener.onDelete(selectedItem);  
  59.                 }  
  60.             });  
  61.             itemLayout = (ViewGroup) getChildAt(selectedItem  
  62.                     - getFirstVisiblePosition());  
  63.             RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(  
  64.                     LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);  
  65.             params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);  
  66.             params.addRule(RelativeLayout.CENTER_VERTICAL);  
  67.             itemLayout.addView(deleteButton, params);  
  68.             isDeleteShown = true;  
  69.         }  
  70.         return false;  
  71.     }  
  72.   
  73.     @Override  
  74.     public boolean onSingleTapUp(MotionEvent e) {  
  75.         return false;  
  76.     }  
  77.   
  78.     @Override  
  79.     public void onShowPress(MotionEvent e) {  
  80.   
  81.     }  
  82.   
  83.     @Override  
  84.     public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,  
  85.             float distanceY) {  
  86.         return false;  
  87.     }  
  88.   
  89.     @Override  
  90.     public void onLongPress(MotionEvent e) {  
  91.     }  
  92.       
  93.     public interface OnDeleteListener {  
  94.   
  95.         void onDelete(int index);  
  96.   
  97.     }  
  98.   
  99. }  
由于代码逻辑比较简单,我就没有加注释。这里在MyListView的构造方法中创建了一个GestureDetector的实例用于监听手势,然后给MyListView注册了touch监听事件。然后在onTouch()方法中进行判断,如果删除按钮已经显示了,就将它移除掉,如果删除按钮没有显示,就使用GestureDetector来处理当前手势。

当手指按下时,会调用OnGestureListener的onDown()方法,在这里通过pointToPosition()方法来判断出当前选中的是ListView的哪一行。当手指快速滑动时,会调用onFling()方法,在这里会去加载delete_button.xml这个布局,然后将删除按钮添加到当前选中的那一行item上。注意,我们还给删除按钮添加了一个点击事件,当点击了删除按钮时就会回调onDeleteListener的onDelete()方法,在回调方法中应该去处理具体的删除操作。

好了,自定义View的功能到此就完成了,接下来我们需要看一下如何才能使用这个自定义View。首先需要创建一个ListView子项的布局文件,新建my_list_view_item.xml,代码如下所示:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:descendantFocusability="blocksDescendants"  
  6.     android:orientation="vertical" >  
  7.   
  8.     <TextView  
  9.         android:id="@+id/text_view"  
  10.         android:layout_width="wrap_content"  
  11.         android:layout_height="50dp"  
  12.         android:layout_centerVertical="true"  
  13.         android:gravity="left|center_vertical"  
  14.         android:textColor="#000" />  
  15.   
  16. </RelativeLayout>  
然后创建一个适配器MyAdapter,在这个适配器中去加载my_list_view_item布局,代码如下所示:
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class MyAdapter extends ArrayAdapter<String> {  
  2.   
  3.     public MyAdapter(Context context, int textViewResourceId, List<String> objects) {  
  4.         super(context, textViewResourceId, objects);  
  5.     }  
  6.   
  7.     @Override  
  8.     public View getView(int position, View convertView, ViewGroup parent) {  
  9.         View view;  
  10.         if (convertView == null) {  
  11.             view = LayoutInflater.from(getContext()).inflate(R.layout.my_list_view_item, null);  
  12.         } else {  
  13.             view = convertView;  
  14.         }  
  15.         TextView textView = (TextView) view.findViewById(R.id.text_view);  
  16.         textView.setText(getItem(position));  
  17.         return view;  
  18.     }  
  19.   
  20. }  
到这里就基本已经完工了,下面在程序的主布局文件里面引入MyListView这个控件,如下所示:
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.     <com.example.customview.MyListView  
  7.         android:id="@+id/my_list_view"  
  8.         android:layout_width="match_parent"  
  9.         android:layout_height="wrap_content" >  
  10.     </com.example.customview.MyListView>  
  11.   
  12. </RelativeLayout>  
最后在Activity中初始化MyListView中的数据,并处理了onDelete()方法的删除逻辑,代码如下所示:
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class MainActivity extends Activity {  
  2.   
  3.     private MyListView myListView;  
  4.   
  5.     private MyAdapter adapter;  
  6.   
  7.     private List<String> contentList = new ArrayList<String>();  
  8.   
  9.     @Override  
  10.     protected void onCreate(Bundle savedInstanceState) {  
  11.         super.onCreate(savedInstanceState);  
  12.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  13.         setContentView(R.layout.activity_main);  
  14.         initList();  
  15.         myListView = (MyListView) findViewById(R.id.my_list_view);  
  16.         myListView.setOnDeleteListener(new OnDeleteListener() {  
  17.             @Override  
  18.             public void onDelete(int index) {  
  19.                 contentList.remove(index);  
  20.                 adapter.notifyDataSetChanged();  
  21.             }  
  22.         });  
  23.         adapter = new MyAdapter(this, 0, contentList);  
  24.         myListView.setAdapter(adapter);  
  25.     }  
  26.   
  27.     private void initList() {  
  28.         contentList.add("Content Item 1");  
  29.         contentList.add("Content Item 2");  
  30.         contentList.add("Content Item 3");  
  31.         contentList.add("Content Item 4");  
  32.         contentList.add("Content Item 5");  
  33.         contentList.add("Content Item 6");  
  34.         contentList.add("Content Item 7");  
  35.         contentList.add("Content Item 8");  
  36.         contentList.add("Content Item 9");  
  37.         contentList.add("Content Item 10");  
  38.         contentList.add("Content Item 11");  
  39.         contentList.add("Content Item 12");  
  40.         contentList.add("Content Item 13");  
  41.         contentList.add("Content Item 14");  
  42.         contentList.add("Content Item 15");  
  43.         contentList.add("Content Item 16");  
  44.         contentList.add("Content Item 17");  
  45.         contentList.add("Content Item 18");  
  46.         contentList.add("Content Item 19");  
  47.         contentList.add("Content Item 20");  
  48.     }  
  49.   
  50. }  
这样就把整个例子的代码都完成了,现在运行一下程序,会看到MyListView可以像ListView一样,正常显示所有的数据,但是当你用手指在MyListView的某一行上快速滑动时,就会有一个删除按钮显示出来,如下图所示:
点击一下删除按钮就可以将第6行的数据删除了。此时的MyListView不仅保留了ListView原生的所有功能,还增加了一个滑动进行删除的功能,确实是一个不折不扣的继承控件。
到了这里,我们就把自定义View的几种实现方法全部讲完了,虽然每个例子都很简单,但是万变不离其宗,复杂的View也是由这些简单的原理堆积出来的。经过了四篇文章的学习,相信每个人对View的理解都已经较为深入了,那么带你一步步深入了解View系列的文章就到此结束,感谢大家有耐心看到最后。
android自定义view几种方式 自定义View的实现方式有以下几种:组合控件,继承控件,自绘控件 详细可分为:自定义组合控件,继承系统View控件,继承系统ViewGroup,自绘View控件,自会ViewGroup控件 1. 自定义组合控件 组合控件就是将多个控件组合成一个新的控件,可以重复使用。 1.编写布局文件 2.实现构造方法 3.初始化UI 4.提供对外的方法 5.在布局当中引用该控件 6.activity中使用 示例:中间是title的文字,左边是返回按钮,右边是一个添加按钮 //因为我们的布局采用Re. 阅读详情

相关推荐

嵌入式开发语言-C语言编程

C语言编程概述环境在Windows上构建C语言的环境安装在Mac上构建C语言的环境安装 概述 “C语言”被称为适合嵌入式系统开发的编程语言之一。 C语言在一般的编程中也是熟悉的开发语言,但实际上,如果试着使用C语言制作微型计算机的控制程序等,就必须使用与“普通的C程序”不同的使用方法。 作为一般的C语言的学习方法,使用“printf”“scanf”等标准函数的程序开发是固定的,但这些都是以UNIX和Windows等环境上的应用程序开发为前提的。 对此,没有显示器和键盘的嵌入式系统的微型计算机控制程序,该如何

编程老王 7976

深入理解Android之自定义View

自定义View、多线程、网络,被认为是Android开发者必须牢固掌握的最基础的三大基本功。而自定义View又是Android开发中特别重要的一环,很多地方都需要用到自定义View。这篇文章我就梳理一下自定义View的相关知识。 目录 (一)什么是自定义View (二)自定义组合View (三)自定义View的绘制 1. Canvas.drawXXX() Pa...

Fighting_初心的博客 1万+

IBM Storwize V3700存储维护实战:硬盘更换、电源模块热插拔与带外管理IP配置

在企业IT基础设施中,存储阵列是数据持久化的核心组件,其稳定运行直接关系到业务连续性。存储阵列通常采用RAID技术实现数据冗余,并通过热插拔、冗余电源等设计保障高可用性。带外管理则提供了独立于业务网络的硬件级监控与管理通道,是运维的关键手段。本次实战以一台IBM Storwize V3700存储阵列为例,详细记录了在业务低峰期,依据严谨的操作流程,对出现SMART预警的硬盘进行在线更换,并对有异响的冗余电源模块实施热插拔更换。针对管理界面强制要求设置VIP才能配置带外管理地址的限制,文章提供了通过SSH命令

weixin_29172963的博客 303

安卓自定义View

安卓自定义View

eos-i的博客 5250

计算机组成原理课设

计算机组成原理课程设计

qq_63306482的博客 8054

ADS 使用教程(一)Workspace, Library and Cell

简要介绍ADS的基本内容

Dirge19的博客 6610

android自定义view

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

shuo277的博客 1万+

(四)C++自制植物大战僵尸游戏启动流程

鼠标左键单机VS2022上方工具栏中进行项目启动。第一次启动项目需要编译项目中所有代码文件,编译生成需要一定的时间。不同性能的电脑需要消耗的时间差别可能较大,通常在几分钟到几十分钟之间。编译成功后会自动启动运行游戏。qi编译成功后自动启动运行游戏如下图。

尔灵尔亿的博客 2466

Android自定义控件(View)

Android系统为我们提供了许多的原生控件,但是在某些情况系统原生控件并不能很好的满足我们的需求,这时就需要用到自定义控件了,并且自定义控件还可以实现很多炫酷的效果。 按类型来划分的话,自定义控件的实现方式基本可以分为三种,自绘控件、组合控件、继承控件。 自绘控件:这个控件上所展现的内容全部都是自己绘制出来的,自己绘制不同于系统原生的控件,许多炫酷的自定义控件效...

beita08的博客 653

ML307R OpenCPU TCP使用

实现现象 平台下发数据,板子在收到数据之后,马上再发送到平台,通过串口助手可以看到已经接收到数据。ML307R TCP 是使用LWIP的标准的socket通信,具体TCP流程可以自行百度。实验目的:实现把接收的数据再发送到服务端。因为是4G,所以必须用外网的。

面朝大海春暖花开 2232

【HALCON工业视觉应用探索】02. C# + Halcon铸件毛刺机器人打磨引导:点云处理从实验室到工业现场的全流程落地

摘要:铸件毛刺的自动化打磨是机械制造领域的重要难题,其随机性(高度0.1-3mm)和复杂工况导致人工打磨效率低(3分钟/件)、工伤率高。本文基于Halcon 24.11与.NET 6,构建了一套点云处理方案:通过线激光扫描仪获取三维点云,经预处理、毛刺检测、路径规划三大模块,引导机器人完成打磨。虚拟实验测试显示,对高度>1mm的毛刺检出率达100%,定位误差±0.08mm,但工业现场受油污、粉尘影响,性能降至检出率68-75%、处理时间>45秒。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 1128

Android自定义组合控件

/用于Java文件中的构造函数//用于XML布局文件中的构造函数//获取属性值//回收获取自定义控件属性值以后一定要回收TypedArray//用于Java文件中的构造函数//用于XML布局文件中的构造函数。

m0_57150356的博客 827

STM32CubeMX之定时器输入捕获

上一章介绍了STM32定时器的PWM输出功能,定时器的几个通道除了有输出功能外,还可以做输入用,可捕获信号的上升沿或下降沿,可以用于测量信号的频率、周期、占空比等。本篇文章将介绍用STM3...

zhang062061的专栏 1337

Android高手秘笈之View的自定义

1.自定义控件都有哪几种类型? 1.1 自绘控件 自绘控件的意思就是,这个View上所展现的内容全部都是我们自己绘制出来的。绘制的代码是写在onDraw()方法中的 public class CounterView extends View implements OnClickListener { private Paint mPaint; private Rect m...

门心叼龙的专栏 2723

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Android 自定义View

Android 自定义View继承系统控件的自定义View继承View 实现自定义控件组合控件---自定义titleBar自定义ViewGroup 自定义View划分,分为三大类,第一种是自定义 View,第二种是自定义 ViewGroup,第三种是自定义组合控件。 其中自定义View又分为继承系统控件(比如TextView)和继承View两种。自定义ViewGroup也分为继承 ViewGroup 和继承系统特定的 ViewGroup(比如 RelativeLayout) 继承系统控件的自定义

a130226123的博客 157

怀旧版电脑GBC模拟器

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

Android自定义View的实现方法,带你一步步深入了解View(四)

不知不觉中,带你一步步深入了解View系列的文章已经写到第四篇了,回顾一下,我们一共学习了LayoutInflater的原理分析、视图的绘制流程、视图的状态及重绘等知识,算是把View中很多重要的知识点都涉及到了。如果你还没有看过我前面的几篇文章,建议先去阅读一下,多了解一些原理方面的东西。 之前我有承诺过,会在View这个话题上多写几篇博客,讲一讲View的工作原理,以及自定义View的方法。现在前半部分的承诺已经如约兑现了,那么今天我就要来兑现后面部分的承诺,讲一讲自定义View的实现方法,同时这也是带

郭霖的专栏 18万+

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

android view设置按钮颜色_Android 自定义View篇(四)自定义属性详解

作者:宋者为王连接:https://cnblogs.com/andy-songwei/p/10979161.html前言尽管 Android 系统提供了不少控件,但是有很多酷炫效果仍然是系统原生控件无法实现的。好在 Android 允许自定义控件,来弥补原生控件的不足。但是在很多初学者看来,自定义 View 似乎很难掌握。其中有很大一部分原因是我们平时看到的自定义 View 使用中,有多...

weixin_39616686的博客 538

Android 自定义控件

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

L1442760086的博客 1803

【朝花夕拾】Android自定义View篇之(四)自定义View的三种实现方式及自定义属性使用介绍...

前言 转载请声明,转自【https://www.cnblogs.com/andy-songwei/p/10979161.html】,谢谢! 尽管Android系统提供了不少控件,但是有很多酷炫效果仍然是系统原生控件无法实现的。好在Android允许自定义控件,来弥补原生控件的不足。但是在很多初学者看来,自定义View似乎很难掌握。其中有很大一部分原因是我们...

aw1070的博客 758

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

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

2401_86909484的博客 1039

android自定义view (UI组件)

自定义View的实现方式有以下几种: 组合控件,继承控件,自绘控件 详细可分为:自定义组合控件,继承系统View控件,继承系统ViewGroup,自绘View控件,自绘 ViewGroup控件组合控件就是将多个控件组合成一个新的控件,可以重复使用。应用场景:在项目中经常会遇到一些比较复杂的UI块需要用在多处使用,那么我们就可以通过五大布局 和基本控件组合成一个新的布局View,这样就可以方便的将该UI用在项目的不同页面中,比如一个标题 栏。...

suiyue010211的博客 484

Android自定义控件

Android自定义控件 1.组合控件。 几个现有控件,组合起来,达到使用的目的。初始化时,新布局填充到控件上。 组合控件定义一个密码输入框,右侧可以点击图标,来切换密码是显示或隐藏。 布局文件:由editText和img组成。 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    

gao2419956747的博客 347

Android自定义View系列之实战

public class CommonTitleBarLayout extends LinearLayout { public CommonTitleBarLayout(Context context) { this(context, null); } public CommonTitleBarLayout(Context context, @Nullable AttributeSet attrs) { this(context, attrs, .

sunbinkang的博客 2094

java 制作自定义控件_自定义控件的三种方式

文章转载于https://blog.youkuaiyun.com/fictionss/article/details/78285167原生控件,自己绘制和继承原生控件.1.组合原生控件将自己需要的控件组合起来变成一个新控件,如下制作常见的app页面头部.新建一个Android项目,创建一个头部布局view_top.xmlandroid:layout_width="match_parent"android:la...

weixin_39723920的博客 657

android自定义view的实现方法,Android自定义View的实现方法

一些接触Android不久的朋友对自定义View都有一丝畏惧感,总感觉这是一个比较高级的技术,但其实自定义View并不复杂,有时候只需要简单几行代码就可以完成了。如果说要按类型来划分的话,自定义View的实现方式大概可以分为三种,自绘控件、组合控件、以及继承控件。那么下面我们就来依次学习一下,每种方式分别是如何自定义View的。一、自绘控件自绘控件的意思就是,这个View上所展现的内容全部都是我们...

weixin_42355399的博客 434
上一篇: android权限大全
下一篇: android 观察者模式解析
AllynZoe
博客等级 码龄12年 17粉丝 58原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值