实现自定义View的三种方式
Posted andy-songwei
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现自定义View的三种方式相关的知识,希望对你有一定的参考价值。
一、组合控件
组合控件,顾名思义,就是将系统原有的控件进行组合,构成一个新的控件。这种方式下,不需要开发者自己去绘制图上显示的内容,也不需要开发者重写onMeasure,onLayout,onDraw方法来实现测量、布局以及draw流程。所以,在实现自定义view的三种方式中,这一种相对比较简单。
实际开发中,标题栏就是一个比较常见的例子。因为在一个app的各个界面中,标题栏基本上是大同小异,复用率很高。所以经常会将标题栏单独做成一个自定义view,在不同的界面直接引入即可,而不用每次都把标题栏布局一遍。本节就自定义一个标题栏,包含标题和返回按钮两个控件,来介绍这种组合控件的实现方式。
1、定义标题栏布局文件
定义标题栏的布局文件custom_title_view.xml,将返回按钮和标题文本进行组合。这一步用于确定标题栏的样子,代码如下所示:
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="wrap_content" 5 android:background="@android:color/holo_orange_light"> 6 <Button 7 android:id="@+id/btn_left" 8 android:layout_width="wrap_content" 9 android:layout_height="wrap_content" 10 android:layout_centerVertical="true" 11 android:layout_marginLeft="5dp" 12 android:text="Back" 13 android:textColor="@android:color/white" /> 14 15 <TextView 16 android:id="@+id/title_tv" 17 android:layout_width="wrap_content" 18 android:layout_height="wrap_content" 19 android:layout_centerInParent="true" 20 android:text="Title" 21 android:textColor="@android:color/white" 22 android:tex
这个布局很简单,就不多说了。
2、根据给定布局实现自定义View
1 public class CustomTitleView extends FrameLayout implements View.OnClickListener 2 private View.OnClickListener mLeftOnClickListener; 3 private Button mBackBtn; 4 private TextView mTittleView; 5 6 public CustomTitleView(@NonNull Context context, @Nullable AttributeSet attrs) 7 super(context, attrs); 8 LayoutInflater.from(context).inflate(R.layout.custom_title_view, this); 9 mBackBtn = findViewById(R.id.btn_left); 10 mBackBtn.setOnClickListener(this); 11 mTittleView = findViewById(R.id.title_tv); 12 13 14 @Override 15 public void onClick(View v) 16 switch (v.getId()) 17 case R.id.btn_left: 18 if (mLeftOnClickListener != null) 19 mLeftOnClickListener.onClick(v); 20 21 break; 22 23 24 25 public void setLeftOnClickListener(View.OnClickListener leftOnClickListener) 26 mLeftOnClickListener = leftOnClickListener; 27 28 29 public void setTittle(String title) 30 mTittleView.setText(title); 31 32
为了编译理解和记忆,这里对该部分做一点说明:
(1)代码中对外提供了两个接口,一是动态设置标题,二是使用者可以自定义返回按钮的点击事件。
(2)CustomTitleView的构造函数,要选择两个参数的,选择其它参数的构造函数会报错。这一点是笔者开发机测试的结果,暂时不清楚是不是所有手机上都是这样。
(3)这里是继承的FrameLayout,但是继承LinearLayout,RelativeLayout等系统布局控件都可以。之所以要继承这些系统现成的ViewGroup,是因为这样可以不用再重写onMeasure,onLayout等,这样省事很多。由于这里是一个布局控件,要用LayoutInflater来填充,所以需要继承ViewGroup,如果继承View的直接子类,编译会不通过。所以,CustomTitleView自己就是一个容器,完全可以当成容器使用,此时CustomTitleView自身的内容会和其作为父布局添加的子控件,效果会叠加,具体的叠加效果是根据继承的容器特性决定的。
3、 在Activity的布局文件中添加CustomTitleView
在Activity的布局文件activity_custom_view_compose_demo.xml中,像使用系统控件一样使用CustomTitleView即可。前说了,CustomTitleView自己就是继承的现成的系统布局,所以它们拥有的属性特性,CustomTitleView一样拥有。
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 <com.example.demos.customviewdemo.CustomTitleView 6 android:id="@+id/customview_title" 7 android:layout_width="match_parent" 8 android:layout_height="wrap_content"> 9 </com.example.demos.customviewdemo.CustomTitleView> 10 </RelativeLayout>
4、在Activity中操作CustomTitleView
1 public class CustomViewComposeDemoActivity extends AppCompatActivity 2 3 private CustomTitleView mCustomTitleView; 4 @Override 5 protected void onCreate(Bundle savedInstanceState) 6 super.onCreate(savedInstanceState); 7 setContentView(R.layout.activity_custom_view_compose_demo); 8 mCustomTitleView = findViewById(R.id.customview_title); 9 mCustomTitleView.setTittle("This is Title"); 10 mCustomTitleView.setLeftOnClickListener(new View.OnClickListener() 11 @Override 12 public void onClick(View v) 13 finish(); 14 15 ); 16 17 18
在第8行中,获取到CustomTitleView实例,第9行设置标题文字,第10行自定义“Back”按钮点击事件。
5、效果显示
按照如上的4步,就通过组合控件完成了一个比较简单的自定义标题栏。可见,这种方式是非常简单的。
以上是关于实现自定义View的三种方式的主要内容,如果未能解决你的问题,请参考以下文章
Android常用对话框大全自定义Dialog的三种方式(Theme,PopupWindow,Dialog)