关于安卓里面的自定义View大概总结起来我把它们分为三个类型来说,即 自绘组件,组合控件,继承控件,下面我结合实例给大家具体分析下这三种自定义View的实现流程。
(一)自绘组件
我个人理解这个才算得上是真正意义上的自定义组件,里面的视图完全是通过自身的onDrwa方法绘制出来的,下面实例为,自定义View绘制试图,当用户点击时可以更改视图背景。
/** * 自绘控件 * Created by xiedong on 2017/3/10. */ public class MyOwnView extends View implements View.OnClickListener{ private Paint mPaint; private Rect mRect; private int colors []={Color.RED,Color.BLUE,Color.GREEN}; private int i=0; public MyOwnView(Context context) { super(context); initView(); } public MyOwnView(Context context, AttributeSet attrs) { super(context, attrs); initView(); } public MyOwnView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(); } private void initView() { mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mRect = new Rect(); setOnClickListener(this); //实现自身点击事件 } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setColor(colors[i%colors.length]); canvas.drawRect(0,0,getWidth(),getHeight(),mPaint); float textWidth = mRect.width(); float textHeight = mRect.height(); mPaint.setColor(Color.WHITE); mPaint.setTextSize(30); canvas.drawText("点击可变颜色",getWidth()/4, getHeight()/2 + textHeight/2,mPaint); } @Override public void onClick(View v) { i++; invalidate(); //通知重新绘制布局 } } 在布局中引用: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_my_view" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.project.view.MyViewActivity"> <com.example.project.view.MyOwnView android:layout_gravity="center" android:layout_width="180dp" android:layout_height="180dp" /> </LinearLayout>这种自定义View使用起来也比较简单,由于没有过多的逻辑实现,可以在xml文件中使用,也可以在java代码中new
(二)组合控件
顾名思义,就是将一些控件组合起来重新定义View,方便对View的重用,我贴上一个利用组合控件实现TitleBar的案例。
布局文件如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="40dp" android:orientation="horizontal" android:background="#440000ff" > <ImageView android:id="@+id/title_btn" android:layout_width="70dp" android:layout_height="match_parent" android:src="@android:drawable/arrow_down_float" /> <TextView android:id="@+id/title_text" android:layout_width="match_parent" android:layout_height="match_parent" android:textSize="20sp" android:gravity="center" android:text="标题" /> </LinearLayout> 自定义VIew的java代码: /** * 使用组合方式完成自定义View * Created by xiedong on 2017/3/10. */ public class TitleView extends LinearLayout{ private ImageView titleBtn; private TextView titleText; private Context mContext; public TitleView(Context context) { super(context); this.mContext = context; initView(); } public TitleView(Context context, AttributeSet attrs) { super(context, attrs); this.mContext = context; initView(); } public TitleView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.mContext = context; initView(); } private void initView() { // View view = View.inflate(mContext,R.layout.titleview_layout,this); LayoutInflater.from(mContext).inflate(R.layout.titleview_layout,this); titleBtn = (ImageView) findViewById(R.id.title_btn); titleText = (TextView) findViewById(R.id.title_text); } /** * 设置左上角箭头的监听事件 * @param listener */ public void setLeftButtonListener(OnClickListener listener){ titleBtn.setOnClickListener(listener); } //设置标题 public void setTitleText(String title){ titleText.setText(title); } }在功能代码中设置自定义view的点击事件跟title上的标题
title = (TitleView) findViewById(R.id.title); title.setLeftButtonListener(new View.OnClickListener() { @Override public void onClick(View v) { System.out.println("-------------按钮被点击————————————"); } }); title.setTitleText("自定义TitleBar");(三)继承控件
这种方式就是继承已有的控件,在保留原先的功能基础上实现自己特有的新功能。
/** * Created by xiedong on 2017/3/10. */ public class MyButton extends Button { private Context mContext; public MyButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.mContext = context; // 接收上下文参数 } public MyButton(Context context) { super(context); this.mContext = context; } public MyButton(Context context, AttributeSet attrs) { super(context, attrs); this.mContext = context; } private MyOnClickListener listener; public void setMyOnClickListener(MyOnClickListener listener){ this.listener = listener; } public interface MyOnClickListener{ void myClick( ); } @Override public boolean onTouchEvent(MotionEvent event) { if(event.getAction()==MotionEvent.ACTION_DOWN) { //判断用户点击事件为Down时,注册点击事件 listener.myClick(); } return true; } }布局代码:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.project.MainActivity"> <com.example.project.view.MyButton android:id="@+id/my_btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/ed_content" /> </RelativeLayout>使用此自定义View
mButton = (MyButton) findViewById(R.id.my_btn); mButton.setMyOnClickListener(new MyButton.MyOnClickListener() { @Override public void myClick() { System.out.println("_------------d---------"); } });
