Android自定义View示例(零)—很简单的自定义View

简介: MainActivity如下:package cn.com;import android.app.Activity;import android.
MainActivity如下:
package cn.com;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
/**
 * Demo描述:
 * 一个非常简单的自定义View.
 * 代码中的笔记很好,便于我们对于自定义View的一个初步认识和理解
 */
public class MainActivity extends Activity {
	// 两个自定义的控件
	private SelfWidget mFirstSelfWidget;
	private SelfWidget mSecondSelfWidget;
    private Context mContext;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		mContext=this;
		mFirstSelfWidget = (SelfWidget) findViewById(R.id.first_self_widget);
		mSecondSelfWidget = (SelfWidget) findViewById(R.id.second_self_widget);

		// 给自定义组件里面的小控件设置值

		// 控件设置文字和图片
		mFirstSelfWidget.setTextViewText("One");
		mFirstSelfWidget.setImageResource(R.drawable.game1);
		mSecondSelfWidget.setTextViewText("Two");
		mSecondSelfWidget.setImageResource(R.drawable.game2);

		// 处理点击事件
		mFirstSelfWidget.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				Toast.makeText(mContext, "点击了第一个自定义组件", 0).show();
			}
		});

		// 处理点击事件
		mSecondSelfWidget.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				Toast.makeText(mContext, "点击了第二个自定义组件", 0).show();
			}
		});

	}
}

SelfWidget如下:
package cn.com;

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
//自定义组件
//错误代码:
//View view=inflater.inflate(R.layout.self_view, null);
//造成部分图片不显示
//原因:inflate(resource, root)方法中第二个参数,指定了新生成的View的parent
//即新生成的View依附于谁而显示

public class SelfWidget extends LinearLayout {
	private ImageView imageView;
	private TextView textView;

	public SelfWidget(Context context) {
		super(context);
	}

	public SelfWidget(Context context, AttributeSet attrs) {
		super(context, attrs);
		LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		// This is error code
		// View view=inflater.inflate(R.layout.self_view, null);
		
		// 给此SelfWidget填充布局
		View view = inflater.inflate(R.layout.self_view, this);
		// 找到此布局中的ImageView
		imageView = (ImageView) view.findViewById(R.id.imageView);
		// 找到此布局中的TextView
		textView = (TextView) view.findViewById(R.id.textView);
	}

	
	
	
	/**
	 * 在以下代码中,给该控件设置一些方法.
	 * 比如设置该控件的文字和图片
	 * 
	 * 以前在这里不是很理解.
	 * 其实说白了我们的自定义View,比如此处的SelfWidget它也是一个类(Class)
	 * 我们在这个类里面一样有构造方法,除了构造方法一样有其他的一些方法,比如设置某个控件
	 * 的图片文字,大小.
	 * 当我们在Activity里findViewById()找了布局中的该控件:
	 * mFirstSelfWidget = (SelfWidget) findViewById(R.id.first_self_widget);
	 * 这里的mFirstSelfWidget就是我们这里的SelfWidget类的一个实例化对象罢了.
	 * 它当然有这个类(自定义控件)里定义的各个方法.
	 * 我们直接用这个对象去调用对应的方法就修改了View的效果或者属性值.
	 * 
	 * 这个和我们以前的(类及其对象)的定义和使用没有什么区别.
	 * 不同的是,这里的类变成了一个View类,它的对象变成了一个实际的界面中控件罢了.
	 */
	
	
	
	
	/**
	 * 设置图片资源
	 */
	public void setImageResource(int resId) {
		imageView.setImageResource(resId);
	}

	/**
	 * 设置显示的文字
	 */
	public void setTextViewText(String text) {
		textView.setText(text);
		textView.setTextColor(Color.RED);

	}

}

main.xml如下:
<?xml version="1.0" encoding="utf-8"?> 
<!-- 在main中有两个组件.采用的都是自定义的组件.名字叫 cn.com.ImageButLinearLayout-->
<!-- 第一个组件的id为first_self_widget,第二个组件的id为second_self_widget-->
<!-- self_selector是一个xml文件,自定义组件的selector,点击自定义组件后图片切换-->
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="horizontal" > 
 
    <cn.com.SelfWidget
        android:id="@+id/first_self_widget" 
        android:layout_height="100dip"   
        android:layout_width="100dip" 
        android:background="@drawable/self_selector"   
     /> 
 
    <cn.com.SelfWidget
        android:id="@+id/second_self_widget" 
        android:layout_marginLeft="5dp" 
        android:layout_height="100dip"   
        android:layout_width="100dip" 
        android:background="@drawable/self_selector"   
        /> 
 
</LinearLayout> 

self_view.xml如下:
<?xml version="1.0" encoding="utf-8"?> 
<!-- 自定义控件所采用的布局 -->
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="horizontal">"
 
    <ImageView 
        android:id="@+id/imageView" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_gravity="center_vertical" 
        android:paddingBottom="5dip" 
        android:paddingLeft="5dip" 
        android:paddingTop="5dip" 
    /> 
 
    <TextView 
        android:id="@+id/textView" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_gravity="center_vertical" 
        android:layout_marginLeft="8dip" 
        android:textColor="#000000" /> 
 
</LinearLayout> 

self_selector.xml如下:
<?xml version="1.0" encoding="utf-8"?> 
<!--在点击自定义组件时进行图片的切换-->
<selector xmlns:android="http://schemas.android.com/apk/res/android" >  
    <item 
        android:state_focused="true" 
        android:state_pressed="false" 
        android:drawable="@drawable/a">
    </item> 
    <item 
        android:state_pressed="true" 
        android:drawable="@drawable/b">
    </item> 
    <item 
        android:state_checked="true" 
        android:drawable="@drawable/b">        
    </item> 
    <item 
        android:state_focused="false" 
        android:state_pressed="false" 
        android:drawable="@drawable/a">
    </item> 
</selector>


相关文章
|
9天前
|
Android开发
Android面试题之自定义View注意事项
在Android开发中,自定义View主要分为四类:直接继承View重写onDraw,继承ViewGroup创建布局,扩展特定View如TextView,以及继承特定ViewGroup。实现时需注意:支持wrap_content通过onMeasure处理,支持padding需在onDraw或onMeasure/onLayout中处理。避免在View中使用Handler,使用post系列方法代替。记得在onDetachedFromWindow时停止线程和动画以防止内存泄漏。处理滑动嵌套时解决滑动冲突,并避免在onDraw中大量创建临时对象。
15 4
|
6天前
|
Android开发
Android面试题之View的invalidate方法和postInvalidate方法有什么区别
本文探讨了Android自定义View中`invalidate()`和`postInvalidate()`的区别。`invalidate()`在UI线程中刷新View,而`postInvalidate()`用于非UI线程,通过消息机制切换到UI线程执行`invalidate()`。源码分析显示,`postInvalidate()`最终调用`ViewRootImpl`的`dispatchInvalidateDelayed`,通过Handler发送消息到UI线程执行刷新。
14 1
|
12天前
|
前端开发 API Android开发
Android自定义View之Canvas一文搞定
这篇文章介绍了Android自定义View中如何使用Canvas和Paint来绘制图形。Canvas可理解为画布,用于绘制各种形状如文字、点、线、矩形、圆角矩形、圆和弧。常见API包括`drawText()`、`drawPoint()`、`drawLine()`、`drawRect()`等。文章还提到了Canvas的保存、恢复、平移和旋转方法,通过绘制钟表盘的例子展示了如何实际应用。总结关键点:Canvas与Paint结合用于图像绘制,掌握Canvas的基本绘图函数及坐标变换操作是自定义View的关键。
10 0
Android自定义View之Canvas一文搞定
|
12天前
|
消息中间件 前端开发 Android开发
Android面试题自定义View之Window、ViewRootImpl和View的三大流程
Android开发中,View的三大核心流程包括measure(测量)、layout(布局)和draw(绘制)。MeasureSpec类在测量过程中起到关键作用,它结合尺寸大小和模式(EXACTLY、AT_MOST、UNSPECIFIED)来指定View应如何测量。onMeasure方法用于自定义View的测量,布局阶段,ViewGroup调用onLayout确定子元素位置,而draw阶段按照特定顺序绘制背景、内容、子元素和装饰。整个流程始于ViewRootImpl的performTraversals,该方法触发测量、布局和绘制。
16 0
|
17天前
|
XML 数据格式
Android-自定义三角形评分控件
Android-自定义三角形评分控件
13 0
|
18天前
Android-自定义流布局标签
Android-自定义流布局标签
12 0
|
18天前
|
Android开发
Android自定义之高仿淘宝下拉刷新
Android自定义之高仿淘宝下拉刷新
17 0
|
XML Android开发 数据格式
Android自定义View示例(四)—带有动画的Dialog
MainActivity如下: package cc.testview1; import android.os.Bundle; import android.
820 0
|
Android开发 数据格式 XML
Android自定义View示例(三)—滑动控件
MainActivity如下: package cc.testview4; import cc.testview4.SlideView.SwitchChangedListener; import android.
885 0
|
前端开发 Android开发
Android自定义View示例(二)—滑动开关
MainActivity如下: package cc.testview3; import cc.testview3.SwitchView.SwitchChangedListener; import android.
987 0