ViewGroup自定义控件

1. 简单的控件 View

Imageview Button TextView 共同的父类 View;

2. 控件的容器 ViewGroup

一个容器可以存放多个view对象,并且按照定义的规则去排列这些孩子;

RelativeLayout ,LinearLayout 共同的父类是ViewGroup

如下图:

自定义控件:

1.onDraw() 重要的方法,用于画自定义控件的效果;

2.一般把画图所需要的工具如都放在onCreate初始化

new Matrix();

new Paint();

View

View自定义控件下的两个构造方法:

//如果采用的是xml布局资源文件 创建view对象,使用两个参数的构造方法.
setContentView(R.layout.activity_main);
//代码方式new出来view对象,使用的是一个参数的构造方法.
MyView myview = new MyView(this);

ViewGroup

ViewGroup的下的构造方法也与View作用一样;

注意:

在控件显示到界面之前,必须要先去计算孩子的宽高;

上下兼容可以使用ViewPager 导用v4包;

ViewGroup重要方法:

OnMeasure()

都是爹调用孩子,

1.用于测量ViewGroup里面,孩子view的宽度和高度;

2.子类如果需要控制自己大小时复写;

注意:

1.measure()后才可以getMeasuredWidth()

2.如果OnMeasure没有调用super.onMeasure()就需要调用下面这句话:

setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);

// measure(100,200)//父容器调用孩子的

// 参数:widthMeasureSpec,heightMeasureSpec

// 父容器测量孩子时,会给宽高值进来,让孩子自己按照这个宽高布局

// int mode = MeasureSpec.getMode(widthMeasureSpec);//获得模式

// int size = MeasureSpec.getSize(widthMeasureSpec);//获得size

// widthMeasureSpec:组成

// 由 32位的二进制码组成的:0101010110....

// 头两位表示的是模式:

// 1. UNSPECIFIED : 未指定的

// 2. EXACTLY:精确的

// 3.AT_MOST:最大

// 后面的30位表示的是 大小 :010101--->

onLayout()

1.onMeasure方法对控件测量完后调用,用于控制孩子的显示位置;

2. ViewGroup下的onLayout是用于管理它的孩子的,所以ViewGroup会强制子类去复写;而View是没有孩子的,因此复写它也没用(View下的onLayout是空的,不会);

scrollBy()

从当前位置进行移动,每次移动会参照当前坐标而增量;(移动的是手机窗体)

scrollTo()

参照左上角坐标(0,0)进行移动;每次移动都会根据顶点坐标,下次移动还是会根据顶点坐标(0,0)进行移动;(移动的是手机窗体)

注意:左菜单与主页是不会移动的,每次移动的是手机窗体;

ViewGroup分析图:

实例代码如下:

package com.bobo.viewgroup;

import android.content.Context;

import android.graphics.Color;

import android.util.AttributeSet;

import android.view.MotionEvent;

import android.view.ViewGroup;

import android.widget.LinearLayout;

public class MyGroupView extends ViewGroup {

private LinearLayout left;

private LinearLayout middle;

private LinearLayout right;

private int measuredWidth;

private int measuredHeight;

/**

*使用XML配置文件显示界面的时候调用

*/

public MyGroupView(Context context, AttributeSet attrs) {

super(context, attrs);

initView(context);

}

/**

*使用代码显示界面的时候调用

*/

public MyGroupView(Context context) {

super(context);

initView(context);

}

// 初始化界面

private void initView(Context context) {

// 给出孩子的宽高

left = new LinearLayout(context);

left.setBackgroundColor(Color.BLUE);

left.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,

LayoutParams.MATCH_PARENT));

middle = new LinearLayout(context);

middle.setBackgroundColor(Color.RED);

middle.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,

LayoutParams.MATCH_PARENT));

right = new LinearLayout(context);

right.setBackgroundColor(Color.GREEN);

right.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,

LayoutParams.MATCH_PARENT));

// 添加孩子到ViewGroup

this.addView(left);

this.addView(middle);

this.addView(right);

}

// 显示界面之前一定要去测量孩子的宽高

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

// 测量孩子的宽高

left.measure(widthMeasureSpec, heightMeasureSpec);

middle.measure(widthMeasureSpec, heightMeasureSpec);

right.measure(widthMeasureSpec, heightMeasureSpec);

// 获取测量后的宽高(注意只有 先measure才可以getMeasuredWidth)

measuredWidth = left.getMeasuredWidth();

measuredHeight = left.getMeasuredHeight();

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

}

// 控制孩子的显示位置

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

left.layout(-measuredWidth, 0, 0, measuredHeight);

middle.layout(0, 0, measuredWidth, measuredHeight);

right.layout(measuredWidth, 0, measuredWidth * 2, measuredHeight);

}

int startX;

@Override

public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

startX = (int) event.getRawX();

break;

case MotionEvent.ACTION_MOVE:

int newX = (int) event.getRawX();

int dx = newX - startX;

// 相对当前位置进行移动

scrollBy(-dx, 0);

// 重新获取当前位置

startX = (int) event.getRawX();

invalidate();//更新

break;

case MotionEvent.ACTION_UP:

break;

}

return true;

}

}

来自为知笔记(Wiz)

时间: 2024-10-14 19:24:20

ViewGroup自定义控件的相关文章

Android 自定义控件之继承ViewGroup创建新容器

欢迎大家来学习本节内容,前几节我们已经学习了其他几种自定义控件,分别是Andriod 自定义控件之音频条及 Andriod 自定义控件之创建可以复用的组合控件还没有学习的同学请先去学习下,因为本节将使用到上几节所讲述的内容. 在学习新内容之前,我们先来弄清楚两个问题:1 . 什么是ViewGroup? ViewGroup是一种容器.它包含零个或以上的View及子View. 2 . ViewGroup有什么作用? ViewGroup内部可以用来存放多个View控件,并且根据自身的测量模式,来测量V

【自定义控件】自定义ViewGroup 在ViewGroup中显示TextView

需求:在ViewGroup中显示一个TextView 1.继承ViewGroup 必须要实现其构造方法和一个onLayout方法 构造函数的处理: public CusViewGroup(Context context) { this(context, null); } public CusViewGroup(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CusViewGroup(Context

Android自定义控件之继承ViewGroup创建新容器(四)

欢迎大家来学习本节内容,前几节我们已经学习了其他几种自定义控件,分别是自定义控件之对现有控件拓展(一).自定义控件之直接继承View创建全新视图(二)及 自定义控件之创建可以复用的组合控件(三)还没有学习的同学请先去学习下,因为本节将使用到上几节所讲述的内容. 在学习新内容之前,我们先来弄清楚两个问题: 1 . 什么是ViewGroup? ViewGroup是一种容器.它包含零个或以上的View及子View. 2 . ViewGroup有什么作用? ViewGroup内部可以用来存放多个View

Android自定义控件之自定义ViewGroup实现标签云(四)

前言: 前面几篇讲了自定义控件绘制原理Android自定义控件之基本原理(一),自定义属性Android自定义控件之自定义属性(二),自定义组合控件Android自定义控件之自定义组合控件(三),常言道:“好记性不如烂笔头,光说不练假把式!!!”,作为一名学渣就是因为没有遵循这句名言才沦落于此,所以要谨遵教诲,注重理论与实践相结合,今天通过自定义ViewGroup来实现一下项目中用到的标签云. 需求背景: 公司需要实现一个知识点的标签显示,每个标签的长度未知,如下图所示 基本绘制流程: 绘制原理

[移动开发] Android自定义控件系列六:自定义ViewGroup(一)实现ViewPager效果

今天我们开始新的Android自定组件旅程,下面一个内容是如何自定义一个ViewGoup,之前我们已经通过几篇博文已经了解了自定义view的基本写法,如果有不了解的同学,可以参看下面专栏中的文章:Android自定义控件. 这次同样也是通过一个例子来说明要如何自定义一个ViewGroup,最终目标就是要实现一个类ViewPager功能的ViewGroup. 我们先来看看最终效果: 对于系统的ViewGroup我们已经是十分熟悉了,最常用的LinearLayout和RelativeLayout几乎

android 自定义控件之ViewGroup生命周期执行步骤

前言 了解ViewGroup的生命周期的执行步骤对于自己自定义ViewGroup的时候十分重要,清楚了整个流程才能对ViewGroup有更深的理解.本文从个人的总结,来阐述一下执行的顺序.执行说明 首先ViewGroup的常用的生命周期主要有:构造方法.onLayout().onFinishInflate().onMeasure().onSizeChanged(),前两种在创建ViewGroup子类的时候,必须重写.至于draw()和drawChild()是其用来绘制背景和子View用的,就不在

自定义控件(视图)56期笔记01:View 和 ViewGroup

1.View 和 ViewGroup 图解关系: 2. View 和 ViewGroup 关系和作用: (1) 关系: • 继承关系 • 组合关系 (2) 作用:      • View的作用: 提供实际的功能.      • ViewGroup的作用: 用来装孩子的,管理孩子摆放的位置,大小.

android自定义控件系列教程----继承ViewGroup实现带阻力效果的可回弹的SrollView

前沿分析: 我为什么要想实现一个这样的回弹呢?因为android都没有支持回弹效果,只有个oversroll的回弹效果,其他的时候都是edgeeffect效果,当我们在哪个地方需要这样的回弹效果我们就直接把我们的控件往这个SrollVIew里面一扔就可以了.其他的都不用管. 主要用到的类讲解: Scroller,主要来辅助我们记录动画和滑动的类,VelocityTracker用来计算滑动阀值就是快速滑动的辅助类,用到的辅助类就这两个,其他的就是测量和布局还有事件的编写了. 效果图 里面的按钮是我

自定义控件学习——防qq侧滑栏

效果 主要步骤: 1. 在xml布局里摆放内容. include    2. 在自定义ViewGroup里, 进行measure测量, layout布局    3. 响应用户的触摸事件    4. int scrollX = (int) (downX - moveX);    5. getScrollX()获取当前滚动到的位置    6. 平滑动画 先看布局 layout_left <?xml version="1.0" encoding="utf-8"?&g