精华内容
参与话题
问答
  • Android 自定义View (一)

    万次阅读 多人点赞 2014-04-21 15:20:04
    很多的Android入门程序猿来说对于Android自定义View,可能都是比较恐惧的,但是这又是高手进阶的必经之路,所有准备在自定义View上面花一些功夫,多写一些文章。先总结下自定义View的步骤: 1、自定义View的属性 2、...

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24252901

    很多的Android入门程序猿来说对于Android自定义View,可能都是比较恐惧的,但是这又是高手进阶的必经之路,所有准备在自定义View上面花一些功夫,多写一些文章。先总结下自定义View的步骤:

    1、自定义View的属性

    2、在View的构造方法中获得我们自定义的属性

    [ 3、重写onMesure ]

    4、重写onDraw

    我把3用[]标出了,所以说3不一定是必须的,当然了大部分情况下还是需要重写的。

    1、自定义View的属性,首先在res/values/  下建立一个attrs.xml , 在里面定义我们的属性和声明我们的整个样式。

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <attr name="titleText" format="string" />
        <attr name="titleTextColor" format="color" />
        <attr name="titleTextSize" format="dimension" />
    
        <declare-styleable name="CustomTitleView">
            <attr name="titleText" />
            <attr name="titleTextColor" />
            <attr name="titleTextSize" />
        </declare-styleable>
    
    </resources>
    我们定义了字体,字体颜色,字体大小3个属性,format是值该属性的取值类型:

    一共有:string,color,demension,integer,enum,reference,float,boolean,fraction,flag;不清楚的可以google一把。

    然后在布局中声明我们的自定义View

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:custom="http://schemas.android.com/apk/res/com.example.customview01"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <com.example.customview01.view.CustomTitleView
            android:layout_width="200dp"
            android:layout_height="100dp"
            custom:titleText="3712"
            custom:titleTextColor="#ff0000"
            custom:titleTextSize="40sp" />
    
    </RelativeLayout>

    一定要引入 xmlns:custom="http://schemas.android.com/apk/res/com.example.customview01"我们的命名空间,后面的包路径指的是项目的package

    2、在View的构造方法中,获得我们的自定义的样式

    /**
    	 * 文本
    	 */
    	private String mTitleText;
    	/**
    	 * 文本的颜色
    	 */
    	private int mTitleTextColor;
    	/**
    	 * 文本的大小
    	 */
    	private int mTitleTextSize;
    
    	/**
    	 * 绘制时控制文本绘制的范围
    	 */
    	private Rect mBound;
    	private Paint mPaint;
    
    	public CustomTitleView(Context context, AttributeSet attrs)
    	{
    		this(context, attrs, 0);
    	}
    
    	public CustomTitleView(Context context)
    	{
    		this(context, null);
    	}
    
    	/**
    	 * 获得我自定义的样式属性
    	 * 
    	 * @param context
    	 * @param attrs
    	 * @param defStyle
    	 */
    	public CustomTitleView(Context context, AttributeSet attrs, int defStyle)
    	{
    		super(context, attrs, defStyle);
    		/**
    		 * 获得我们所定义的自定义样式属性
    		 */
    		TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTitleView, defStyle, 0);
    		int n = a.getIndexCount();
    		for (int i = 0; i < n; i++)
    		{
    			int attr = a.getIndex(i);
    			switch (attr)
    			{
    			case R.styleable.CustomTitleView_titleText:
    				mTitleText = a.getString(attr);
    				break;
    			case R.styleable.CustomTitleView_titleTextColor:
    				// 默认颜色设置为黑色
    				mTitleTextColor = a.getColor(attr, Color.BLACK);
    				break;
    			case R.styleable.CustomTitleView_titleTextSize:
    				// 默认设置为16sp,TypeValue也可以把sp转化为px
    				mTitleTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
    						TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
    				break;
    
    			}
    
    		}
    		a.recycle();
    
    		/**
    		 * 获得绘制文本的宽和高
    		 */
    		mPaint = new Paint();
    		mPaint.setTextSize(mTitleTextSize);
    		// mPaint.setColor(mTitleTextColor);
    		mBound = new Rect();
    		mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound);
    
    	}

    我们重写了3个构造方法,默认的布局文件调用的是两个参数的构造方法,所以记得让所有的构造调用我们的三个参数的构造,我们在三个参数的构造中获得自定义属性。

    3、我们重写onDraw,onMesure调用系统提供的:

    @Override
    	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    	{
    		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    	}
    
    	@Override
    	protected void onDraw(Canvas canvas)
    	{
    		mPaint.setColor(Color.YELLOW);
    		canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);
    
    		mPaint.setColor(mTitleTextColor);
    		canvas.drawText(mTitleText, getWidth() / 2 - mBound.width() / 2, getHeight() / 2 + mBound.height() / 2, mPaint);
    	}
    此时的效果是:

    是不是觉得还不错,基本已经实现了自定义View。但是此时如果我们把布局文件的宽和高写成wrap_content,会发现效果并不是我们的预期:


    系统帮我们测量的高度和宽度都是MATCH_PARNET,当我们设置明确的宽度和高度时,系统帮我们测量的结果就是我们设置的结果,当我们设置为WRAP_CONTENT,或者MATCH_PARENT系统帮我们测量的结果就是MATCH_PARENT的长度。

    所以,当设置了WRAP_CONTENT时,我们需要自己进行测量,即重写onMesure方法”:

    重写之前先了解MeasureSpec的specMode,一共三种类型:

    EXACTLY:一般是设置了明确的值或者是MATCH_PARENT

    AT_MOST:表示子布局限制在一个最大值内,一般为WARP_CONTENT

    UNSPECIFIED:表示子布局想要多大就多大,很少使用

    下面是我们重写onMeasure代码:

    	@Override
    	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    	{
    		int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    		int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    		int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    		int heightSize = MeasureSpec.getSize(heightMeasureSpec);
    		int width;
    		int height ;
    		if (widthMode == MeasureSpec.EXACTLY)
    		{
    			width = widthSize;
    		} else
    		{
    			mPaint.setTextSize(mTitleTextSize);
    			mPaint.getTextBounds(mTitle, 0, mTitle.length(), mBounds);
    			float textWidth = mBounds.width();
    			int desired = (int) (getPaddingLeft() + textWidth + getPaddingRight());
    			width = desired;
    		}
    
    		if (heightMode == MeasureSpec.EXACTLY)
    		{
    			height = heightSize;
    		} else
    		{
    			mPaint.setTextSize(mTitleTextSize);
    			mPaint.getTextBounds(mTitle, 0, mTitle.length(), mBounds);
    			float textHeight = mBounds.height();
    			int desired = (int) (getPaddingTop() + textHeight + getPaddingBottom());
    			height = desired;
    		}
    		
    		
    
    		setMeasuredDimension(width, height);
    	}
    

    现在我们修改下布局文件:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:custom="http://schemas.android.com/apk/res/com.example.customview01"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <com.example.customview01.view.CustomTitleView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            custom:titleText="3712"
            android:padding="10dp"
            custom:titleTextColor="#ff0000"
            android:layout_centerInParent="true"
            custom:titleTextSize="40sp" />
    
    </RelativeLayout>

    现在的效果是:


    完全复合我们的预期,现在我们可以对高度、宽度进行随便的设置了,基本可以满足我们的需求。

    当然了,这样下来我们这个自定义View与TextView相比岂不是没什么优势,所有我们觉得给自定义View添加一个事件:

    在构造中添加:

    this.setOnClickListener(new OnClickListener()
    		{
    
    			@Override
    			public void onClick(View v)
    			{
    				mTitleText = randomText();
    				postInvalidate();
    			}
    
    		});

    private String randomText()
    	{
    		Random random = new Random();
    		Set<Integer> set = new HashSet<Integer>();
    		while (set.size() < 4)
    		{
    			int randomInt = random.nextInt(10);
    			set.add(randomInt);
    		}
    		StringBuffer sb = new StringBuffer();
    		for (Integer i : set)
    		{
    			sb.append("" + i);
    		}
    
    		return sb.toString();
    	}

    下面再来运行:


    我们添加了一个点击事件,每次让它随机生成一个4位的随机数,有兴趣的可以在onDraw中添加一点噪点,然后改写为验证码,是不是感觉很不错。


    好了,各位学习的,打酱油的留个言,顶个呗~


    源码点击此处下载






    展开全文
  • 自定义android进度条,带有进度指示,项目详情:http://blog.csdn.net/xiaanming/article/details/10298163
  • Android 自定义View (二) 进阶

    万次阅读 多人点赞 2014-04-22 11:39:25
    继续自定义View之旅,前面已经介绍过一个自定义View的基础的例子,Android 自定义View (一),如果你还对自定义View不了解可以去看看。今天给大家带来一个稍微复杂点的例子。 自定义View显示一张图片,下面包含图片...

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24300125

    继续自定义View之旅,前面已经介绍过一个自定义View的基础的例子,Android 自定义View (一)如果你还对自定义View不了解可以去看看。今天给大家带来一个稍微复杂点的例子。

    自定义View显示一张图片,下面包含图片的文本介绍,类似相片介绍什么的,不过不重要,主要是学习自定义View的用法么。

    还记得上一篇讲的4个步骤么:

    1、自定义View的属性
    2、在View的构造方法中获得我们自定义的属性
    [ 3、重写onMesure ]
    4、重写onDraw

    直接切入正题:

    1、在res/values/attr.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <attr name="titleText" format="string" />
        <attr name="titleTextSize" format="dimension" />
        <attr name="titleTextColor" format="color" />
        <attr name="image" format="reference" />
        <attr name="imageScaleType">
            <enum name="fillXY" value="0" />
            <enum name="center" value="1" />
        </attr>
    
        <declare-styleable name="CustomImageView">
            <attr name="titleText" />
            <attr name="titleTextSize" />
            <attr name="titleTextColor" />
            <attr name="image" />
            <attr name="imageScaleType" />
        </declare-styleable>
    
    </resources>

    2、在构造中获得我们的自定义属性:

    /**
    	 * 初始化所特有自定义类型
    	 * 
    	 * @param context
    	 * @param attrs
    	 * @param defStyle
    	 */
    	public CustomImageView(Context context, AttributeSet attrs, int defStyle)
    	{
    		super(context, attrs, defStyle);
    
    		TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomImageView, defStyle, 0);
    
    		int n = a.getIndexCount();
    
    		for (int i = 0; i < n; i++)
    		{
    			int attr = a.getIndex(i);
    
    			switch (attr)
    			{
    			case R.styleable.CustomImageView_image:
    				mImage = BitmapFactory.decodeResource(getResources(), a.getResourceId(attr, 0));
    				break;
    			case R.styleable.CustomImageView_imageScaleType:
    				mImageScale = a.getInt(attr, 0);
    				break;
    			case R.styleable.CustomImageView_titleText:
    				mTitle = a.getString(attr);
    				break;
    			case R.styleable.CustomImageView_titleTextColor:
    				mTextColor = a.getColor(attr, Color.BLACK);
    				break;
    			case R.styleable.CustomImageView_titleTextSize:
    				mTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
    						16, getResources().getDisplayMetrics()));
    				break;
    
    			}
    		}
    		a.recycle();
    		rect = new Rect();
    		mPaint = new Paint();
    		mTextBound = new Rect();
    		mPaint.setTextSize(mTextSize);
    		// 计算了描绘字体需要的范围
    		mPaint.getTextBounds(mTitle, 0, mTitle.length(), mTextBound);
    
    	}

    3、重写onMeasure

    	@Override
    	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    	{
    		// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    
    		/**
    		 * 设置宽度
    		 */
    		int specMode = MeasureSpec.getMode(widthMeasureSpec);
    		int specSize = MeasureSpec.getSize(widthMeasureSpec);
    
    		if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate
    		{
    			Log.e("xxx", "EXACTLY");
    			mWidth = specSize;
    		} else
    		{
    			// 由图片决定的宽
    			int desireByImg = getPaddingLeft() + getPaddingRight() + mImage.getWidth();
    			// 由字体决定的宽
    			int desireByTitle = getPaddingLeft() + getPaddingRight() + mTextBound.width();
    
    			if (specMode == MeasureSpec.AT_MOST)// wrap_content
    			{
    				int desire = Math.max(desireByImg, desireByTitle);
    				mWidth = Math.min(desire, specSize);
    				Log.e("xxx", "AT_MOST");
    			}
    		}
    
    		/***
    		 * 设置高度
    		 */
    
    		specMode = MeasureSpec.getMode(heightMeasureSpec);
    		specSize = MeasureSpec.getSize(heightMeasureSpec);
    		if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate
    		{
    			mHeight = specSize;
    		} else
    		{
    			int desire = getPaddingTop() + getPaddingBottom() + mImage.getHeight() + mTextBound.height();
    			if (specMode == MeasureSpec.AT_MOST)// wrap_content
    			{
    				mHeight = Math.min(desire, specSize);
    			}
    		}
    		setMeasuredDimension(mWidth, mHeight);
    
    	}

    4、重写onDraw

    @Override
    	protected void onDraw(Canvas canvas)
    	{
    		// super.onDraw(canvas);
    		/**
    		 * 边框
    		 */
    		mPaint.setStrokeWidth(4);
    		mPaint.setStyle(Paint.Style.STROKE);
    		mPaint.setColor(Color.CYAN);
    		canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);
    
    		rect.left = getPaddingLeft();
    		rect.right = mWidth - getPaddingRight();
    		rect.top = getPaddingTop();
    		rect.bottom = mHeight - getPaddingBottom();
    
    		mPaint.setColor(mTextColor);
    		mPaint.setStyle(Style.FILL);
    		/**
    		 * 当前设置的宽度小于字体需要的宽度,将字体改为xxx...
    		 */
    		if (mTextBound.width() > mWidth)
    		{
    			TextPaint paint = new TextPaint(mPaint);
    			String msg = TextUtils.ellipsize(mTitle, paint, (float) mWidth - getPaddingLeft() - getPaddingRight(),
    					TextUtils.TruncateAt.END).toString();
    			canvas.drawText(msg, getPaddingLeft(), mHeight - getPaddingBottom(), mPaint);
    
    		} else
    		{
    			//正常情况,将字体居中
    			canvas.drawText(mTitle, mWidth / 2 - mTextBound.width() * 1.0f / 2, mHeight - getPaddingBottom(), mPaint);
    		}
    
    		//取消使用掉的快
    		rect.bottom -= mTextBound.height();
    
    		if (mImageScale == IMAGE_SCALE_FITXY)
    		{
    			canvas.drawBitmap(mImage, null, rect, mPaint);
    		} else
    		{
    			//计算居中的矩形范围
    			rect.left = mWidth / 2 - mImage.getWidth() / 2;
    			rect.right = mWidth / 2 + mImage.getWidth() / 2;
    			rect.top = (mHeight - mTextBound.height()) / 2 - mImage.getHeight() / 2;
    			rect.bottom = (mHeight - mTextBound.height()) / 2 + mImage.getHeight() / 2;
    
    			canvas.drawBitmap(mImage, null, rect, mPaint);
    		}
    
    	}

    代码,结合注释和第一篇View的使用,应该可以看懂,不明白的留言。下面我们引入我们的自定义View:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:zhy="http://schemas.android.com/apk/res/com.zhy.customview02"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
    
        <com.zhy.customview02.view.CustomImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:padding="10dp"
            zhy:image="@drawable/ic_launcher"
            zhy:imageScaleType="center"
            zhy:titleText="hello andorid ! "
            zhy:titleTextColor="#ff0000"
            zhy:titleTextSize="30sp" />
    
        <com.zhy.customview02.view.CustomImageView
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:padding="10dp"
            zhy:image="@drawable/ic_launcher"
            zhy:imageScaleType="center"
            zhy:titleText="helloworldwelcome"
            zhy:titleTextColor="#00ff00"
            zhy:titleTextSize="20sp" />
    
        <com.zhy.customview02.view.CustomImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:padding="10dp"
            zhy:image="@drawable/lmj"
            zhy:imageScaleType="center"
            zhy:titleText="妹子~"
            zhy:titleTextColor="#ff0000"
            zhy:titleTextSize="12sp" />
    
    </LinearLayout>

    我特意让显示出现3中情况:

    1、字体的宽度大于图片,且View宽度设置为wrap_content

    2、View宽度设置为精确值,字体的长度大于此宽度

    3、图片的宽度大于字体,且View宽度设置为wrap_content

    看看显示效果:


    怎么样,对于这三种情况所展示的效果都还不错吧。


    好了,就到这里,各位看官,没事留个言,顶一个呗~


    源码点击下载




    展开全文
  • Android自定义View 自定义组合控件

    千次阅读 2014-11-13 23:09:28
    自定义组合控件: 以三国杀游戏武将为例,包括武将头像,血条,装备区 1.先定义该组合的XML文件布局 1 "1.0" encoding="utf-8"?> 2 "http://schemas.android.com/apk/res/android" 3 android:layout_width...

    自定义组合控件:

    以三国杀游戏武将为例,包括武将头像,血条,装备区

    1.先定义该组合的XML文件布局

    复制代码
     1 <?xml version="1.0" encoding="utf-8"?>
     2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     android:layout_width="wrap_content"
     4     android:layout_height="wrap_content"
     5     android:orientation="horizontal" >
     6     <LinearLayout
     7         android:layout_width="wrap_content"
     8         android:layout_height="wrap_content"
     9         android:orientation="vertical"
    10         >
    11         <ImageView
    12             android:id="@+id/touxiang"
    13             android:layout_width="80dp"
    14             android:layout_height="80dp"
    15             android:maxWidth="80dp"
    16             android:maxHeight="80dp"    
    17             >
    18         </ImageView>
    19         <ImageView
    20             android:id="@+id/blood"
    21             android:layout_width="wrap_content"
    22         android:layout_height="wrap_content"
    23             android:maxWidth="80dp"
    24             android:maxHeight="20dp"
    25             >            
    26         </ImageView>
    27         
    28     </LinearLayout>
    29     
    30     <LinearLayout
    31         android:layout_width="wrap_content"
    32         android:layout_height="wrap_content"
    33         android:orientation="vertical"
    34         android:layout_gravity="center_vertical"
    35         >
    36         <TextView
    37             android:layout_width="wrap_content"
    38             android:layout_height="wrap_content"
    39             android:text="武器"
    40             ></TextView>
    41         <TextView
    42             android:layout_width="wrap_content"
    43             android:layout_height="wrap_content"
    44             android:text="防具"
    45             ></TextView>
    46         <TextView
    47             android:layout_width="wrap_content"
    48             android:layout_height="wrap_content"
    49             android:text="+1马"
    50             ></TextView>
    51         <TextView
    52             android:layout_width="wrap_content"
    53             android:layout_height="wrap_content"
    54             android:text="-1马"
    55             ></TextView>
    56     </LinearLayout>
    57 
    58 </LinearLayout>
    复制代码

    2.自定义一个继承布局的类 

    复制代码
    public class GeneralFrame extends LinearLayout {
    
        ImageView general;
        ImageView blood;
        TextView wuqi;
        TextView fangju;
        TextView jiayima;
        TextView jianyima;
        public GeneralFrame(Context context) {
            //super(context);
            // TODO Auto-generated constructor stub
            this(context,null);
        }
        public GeneralFrame(Context context, AttributeSet attrs) {
            super(context, attrs);
            // TODO Auto-generated constructor stub
              //在构造函数中将Xml中定义的布局解析出来。   
            LayoutInflater.from(context).inflate(R.layout.generalframe, this, true);  
            general=(ImageView)findViewById(R.id.touxiang);
            blood=(ImageView)findViewById(R.id.blood);
            blood.setImageResource(R.drawable.blood);
            //wuqi=(TextView)findViewById(R.id
        }
    复制代码

    可在XML文件里调用该类

     < com.layouts.uitest.GeneralFrame
         android:layout_height="wrap_content"
          android:layout_width="wrap_content"
    />

    也可以在代码中动态添加该类

    GeneralFrame general=new GeneralFrame(this);
    general.setGeneralImage(R.drawable.diaochan);
    linear2.addView(general);

    自定义View.

    自定义类继承View 

    复制代码
    public class MyView extends View
    {
      
       public MyView (Context c,AttributeSet set)
      {
       }
       @Override
       public void onDraw(Canvas canvas)
      {
         
       }  
    }
    复制代码

    调用方法同自定义控件一样。

    自定义View的构造方法一定要选中 public MyView (Context c,AttributeSet set),系统会回调该构造方法

    展开全文
  • 自定义view是一个综合的技术体系,本说明文档不去分析一个个具体的自定义view的实现,因为自定义view五花八门,是不可能全部分析一遍的。虽然我们不能把自定义view都分析一遍,但是我们能够提取出一种思想,而面对...

      自定义view是一个综合的技术体系,本说明文档不去分析一个个具体的自定义view的实现,因为自定义view五花八门,是不可能全部分析一遍的。虽然我们不能把自定义view都分析一遍,但是我们能够提取出一种思想,而面对陌生的自定义view时,运用这个思想去快速解决问题。这种思想的描述如下:首先要掌握基本功,比如view的弹性滑动、滑动冲突、绘制原理等等,这些东西都是自定义view所必须的,尤其是那些看起来很炫的自定义view,他们往往对这些技术点的要求更高;熟练掌握基本功后,在面对新的自定义view时,要能够对其分类并选择合适的思路。另外平时还需要多积累一些自定义view相关的经验,并逐渐做到融会贯通,通过这种思想慢慢的就可以提高自定义view的水平了。

    自定义View相关类的体系

    这里写图片描述

      这个体系充分的运用了面对对象封装、继承、多态的思想,主要采用模板方法模式。我们自己自定义View逃不出对以上几个方法的运用。

    为何要进行自定义控件的学习

      实现Android现有控件不能够实现的功能,就需要采⽤⾃定义控件的⽅式;

    自定义View的步骤

    这里写图片描述

    自定义属性

    1.在res/values创建attrs.xml
    2.attrs.xml定义自定义属性
    3.布局中给特定控件制定自定义属性
    4.在控件内部获取自定义属性

    AndroidStudio自定义属性xmlns无法识别问题解决in Gradle projects,always use http://schemas.android.com/apk/res-auto

    http://blog.csdn.net/nwsuafer/article/details/42121521

    注意:
    必须重载两个构造方法,其中一个是代码创建使用的,一个是布局中引入使用的

    自定义View类型1:对现有控件进行拓展

    继承view,重写onDraw方法
    可以利用已有控件的功能实现通用的功能,自己实现特有的部分就可以了。
    可以调用控件已经存在的方法,实现功能;
    利用onDraw可以实现控件显示的样子;
    控件可以进行自定义属性的设置

    步骤
    1. 继承view或者view的子类
    2. 声明构造方法!!!
    一个参数的构造方法:在代码中使用会被调用
    两个或者三个参数的构造方法,通过layout xl文件包含控件的时候,会自定调用
    如果控件希望在layout使用,控件中必须包含两个或者3个参数的构造方法,通常两个参数的构造方法就行了,没有强制要求三个构造方法都写出来。
    3. 当构造完成,就可以直接在布局xml中,引用控件
    4. 自定义view的引用,采用<类全路径>去引用

    自定义View类型2:通过组合来实现新的控件(继承viewgroup派生特殊的layout)

    方式:将android中已有的控件,通过代码的方式,将这些控件组合在一起,实现更复杂的功能;
    常见的案例:autocompletetextview、spinner
    常见的第三方控件:瀑布流、拨号盘、侧滑菜单、水纹进度等等

    步骤:
    1. 集成viewgroup以及viewgroup的子类
    2. 构造方法的声明
    3. 初始化,其实各种效果都在初始化中实现

    自定义View类型3:重写view来实现全新的控件

    自己来实现外观,自己来写事件
    步骤:
    1. 继承view
    2. 声明构造方法:现阶段 有三种构造方法
    3. 绘制onDraw实现自己的外观
    4. 尺寸的测量:告诉父容器,自身的尺寸
    5. 可选:实现点击、手势
    6. 可选:内容的刷新、线程的支持

    自定义View的事件处理

    包括:
    View自身事件处理
    Touch事件监听器事件处理
    事件分发处理
    常用接口回调来增加自定义View的扩展性

    自定义View更新数据和刷新操作

    1.invalidate强制View刷新,调用onDraw方法,invalidate必须在主线程中执行
    2.postInvalidate强制View刷新,调用onDraw方法,postInvalidate可以在子线程执行,也可以在主线程执行

    展开全文
  • 自定义View基础 - 最易懂的自定义View原理系列(1)

    万次阅读 多人点赞 2017-02-20 11:27:07
    自定义View原理是Android开发者必须了解的基础; 在了解自定义View之前,你需要有一定的知识储备; 本文将全面解析关于自定义View中的所有知识基础。 目录1. View的分类视图View主要分为两类: 类别 解释 特点 ...
  • 自定义View自定义属性

    万次阅读 2012-04-27 12:06:26
    在Android开发中常常需要自定义View,在自定义View后,常常需要一些特别的属性,这里一并讲解如何自定义属性。 1.自定义一个View类:MyNewElement.java package com.ixgsoft.space; import android....
  • 不知不觉中,带你一步步深入了解View系列的文章已经写到第四篇了,回顾一下,我们一共学习了...现在前半部分的承诺已经如约兑现了,那么今天我就要来兑现后面部分的承诺,讲一讲自定义View的实现方法,同时这也是带
  • 网上有大量关于自定义View原理的文章,但存在一些问题:内容不全、思路不清晰、无源码分析、简单问题复杂化 等 今天,我将全面总结自定义View原理中的Layout过程,我能保证这是市面上的最全面、最清晰、最易懂的 ...
  • 网上有大量关于自定义View原理的文章,但存在一些问题:内容不全、思路不清晰、无源码分析、简单问题复杂化 等 今天,我将全面总结自定义View原理中的Draw过程,我能保证这是市面上的最全面、最清晰、最易懂的 ...
  • 我有现成的布局xml文件,现在想定义一个组合的自定义view,怎样把这个view的布局指定为一个xml文件
  • 自定义View

    千次阅读 多人点赞 2018-04-09 19:45:42
    自定义View基础篇安卓自定义View基础 - 坐标系安卓自定义View基础 - 角度弧度安卓自定义View基础 - 颜色进阶篇安卓自定义View进阶 - 分类和流程安卓自定义View进阶 - 绘制基本图形安卓自定义View进阶 - 画布操作安卓...
  • 自定义View 为什么要自定义View? 主要是Andorid系统内置的View 无法实现我们的 需求,我们需要针对我们的业务需求定制我们想要的 View.自定义View 我们大部分时候只需重写两个函数: onMeasure(),onDraw(). ...
  • 自定义了一个view,实现一个图片的移动,然后我想在view添加一个按钮,网上说是要建一个layout,然后再add。求教具体方法啊,能不能不用layout直接用view添加按钮。
  • 自定义View实现渲染

    千次阅读 2016-06-29 17:15:45
    阅读前可以先看Android自定义图表:ChartView需求:通过以上例子我们修改测试数据...有了解自定义View的同学应该清楚从一个点画到另一个点的过程中,通过Paint与canvas.drawLine()绘制一条不同颜色的线是很不容易做到
  • 自定义View的套路

    千次阅读 2017-03-13 21:33:57
    自定义View是综合的技术体系,它涉及View的层级结构、事件分发机制和View的工作原理等技术细节。自定义View的分类1.继承View重写onDraw方法 这种方法主要用于实现一些不规则的效果,需要通过绘制的方式实现,即重写...
  • 唯一能强行脱离依赖,在系统缺失必备组件或DLL受损的情况下依然能正常运行
  • Android 自定义View总结

    千次阅读 2016-03-06 01:25:33
    本篇博客只是一篇总结,自定义View往往和奇奇怪怪的需求相关。面对不断变化的需求,千万不能“死记硬背”,更重要的是要掌握自定义View的流程。 Android中每个控件都会在界面中占得一块矩形区域,这些控件大致被分为...
  • Android自定义View获取自定义属性

    万次阅读 2017-04-18 23:25:20
    今天记录一下自定义View的构造函数的使用,以及如何获取自定义属性。先看一下自定义View 的构造函数public class CustomView extends View { private static final String TAG = "CustomView";
  • 自定义View(一)自定义View的分类

    千次阅读 2016-12-21 16:27:42
    算起来,接触自定义View大半年了,可惜一直没能系统的总结一遍,好记性不如烂笔头,趁最近闲暇,我也得空坐下来好好归纳一下相关知识。  还是那句话,小女不才,入行时间短,火候尚浅,有说的不准确的地方,还请...
  • Android 自定义View (三) 圆环交替 等待效果

    万次阅读 多人点赞 2014-04-25 23:24:08
    一个朋友今天有这么个需求(下图),我觉得那自定义View来做还是很适合的,就做了下,顺便和大家分享下,对于自定义View多练没坏处么。如果你看了前两篇,那么这篇一定so easy 。 效果就这样,分析了一下,大概有...
  • Android自定义View 之自定义属性

    千次阅读 2019-03-28 16:53:15
    自定义view的起步是自定义属性,并且正确的读取属性。 在res/values/attrs.xml的文件中创建属性: <declare-styleable name="ViewDemoAttr35"> <attr name="string35" format="string"/> <attr ...
  • Android自定义View-自定义组件

    千次阅读 2018-03-05 14:35:28
    Android自定义组件 android自定义组件一般有三种实现方式: 一、组合控件:组合控件,顾名思义就是将一些小的控件组合起来形成一个新的控件,这些小的控件多是系统自带的控件。 二、自绘控件: 何为自绘控件,就是...
  • 对比自定义view和自定义viewgroup

    千次阅读 2016-03-17 18:35:12
    view 的onDraw()和ViewGroup的dispatchDraw()方法最近在研究view的整个事件过程,以及自定义view的绘制,今天突然发现还有dispatchDraw(),于是在官方api中找到了draw()方法。通常我们自定义一个view只需要先测量,...
  • Android View体系(九)自定义View

    千次阅读 2016-04-06 11:32:11
    学习了以上的文章后,接下来我们来讲讲自定义View自定义View一直被认为是高手掌握的技能,因为情况太多,想实现的效果又变化多端,但它也要遵循一定的规则,我们要讲的就是这个规则,至于那些变化多端的酷炫的效果...
  • Android自定义View的官方套路

    万次阅读 多人点赞 2016-04-12 18:44:49
    概述Android已经为我们提供了大量的View供我们使用,但是可能有时候这些组件不能满足我们的需求,这时候就需要自定义控件了。自定义控件对于初学者总是感觉是一种复杂的技术。因为里面涉及到的知识点会比较多。但是...
  • 1. 继承自View自定义一个View. 2.继承自ViewGroup(容器),自定义设置子view的位置、尺寸等,用于组合一些组件,产生一个复合组件 3.继承自已有的组件(View型 或 ViewGroup型),用于扩展现有组件的功能 ...
  • Android自定义View之LoadingLayout

    千次阅读 2017-02-23 11:27:06
    介绍上一篇博文写了一个通用的加载view,这篇在加载view的基础在包裹一层就是LoadingLayout了,主要的目的是免去每次加载时要隐藏主内容布局,然后加载成功之后显示主内容布局这些繁琐操作。如果你还不了解...
  • 自定义view增加动画效果

    千次阅读 2017-05-31 10:51:03
    通过这一周的学习总算对自定义view比较了解了。所以也想和大家分享一下自定义view的学习方法和我学习的一个过程。还是来看一下我们每篇比谈的我们的自定义view的大纲 1.自定义view单纯的用画笔绘制view(死view) ...
  • 为什么要自定义Viewandroid提供了很多控件供我们使用 但有些功能是系统所提供的实现不 了的 这时候我们就需要自定义一个View来实现我们所需要的效果. 在Android中所有的控件都直接或间接的继承自View,分View和...

空空如也

1 2 3 4 5 ... 20
收藏数 733,467
精华内容 293,386
关键字:

自定义