Android界面编程之一 View组件

本文深入探讨了Android应用中UI组件与容器组件的使用,详细解释了View类的XML属性及其作用,并展示了如何使用XML布局文件控制界面。同时,介绍了如何在Java代码与XML布局文件之间混合控制UI界面,以及如何自定义组件。并通过实例代码说明了实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


2.1.1 视图组件与容器组件
Android应用的绝大部分UI组件都放在android.widget包及其子包、android.view包及其子包中,Android应用的所有UI组件都继承了View类
View类还有一个重要子类:ViewGroup,但ViewGroup通常作为其他组件使用。Android采用了“组合器”设计模式来设计View和ViewGroup:ViewGroup是View子类,因此ViewGroup也可被当成View使用。ViewGroup除了可以包含普通View组件外,还可以再次包含ViewGroup

View类的XML属性

android:alpha   

设置透明度
android:background  


android:clickable

是否可激发单击事件
android:contentDescription

设置该组件的主要描述信息
android:drawingCacheQuality

所使用的绘制缓存的质量
android:fadeScrollbars

当不使用该组件的滚动条时,组件是否淡出滚动条
android:fadingEdge

设置滚动该组件时边界是否使用淡出效果
android:fadingEdgeLength


android:focusable


android:focusableInTouchMode


android:id


android:isScrollContainer

设置该组件是作为可滚动容器使用
android:keepScreenOn

是否会强制手机屏幕一直打开
android:longClickable

是否可响应长单击事件
android:minHeight


android:minWidth


android:nextFocusDown

设置焦点在该组件上,且按下键时获得焦点的组件ID
android:nextFocusLeft


android:nextFocusRight


android:nextFocusUp


android:onClick


android:padding

在组件四周设置填充区域
android:paddingBottom


android:paddingLeft


android:paddingRight


android:paddingTop


android:rotation

设置该组件旋转角度
android:rotationX

绕X轴旋转角度
android:rotationY


android:saveEnabled

如果设置为false,那么当该组件被冻结时,不会保存它的状态
android:scaleX

设置该组件在水平方向的缩放比
android:scaleY


android:scrollX

初始化后的水平滚动偏移
android:scrollY


android:scrollbarAlwaysDrawHorizontalTrack

是否总是显示水平滚动条的轨道
android:scrollbarAlwaysDrawVerticalTrack


android:scrollbarDefaultDelayBeforeFade

设置滚动条在淡出隐藏之前延迟多少毫秒
android:scrollbarFadeDuration

淡出隐藏过程需要多少秒
android:scrollbarSize

设置滚动条的宽度和水平滚动条的高度
android:scrollbarStyle

设置滚动条的风格和位置:
insideOverlay
insideInset
outsideOverlay
outsideInset
android:scrollbarThumbVertical

设置该组件的垂直滚动条的滑块对应的Drawable对象
android:scrollbarTrackHorizontal


android:scrollbarTrackVertical


android:scrollbars

定义该组件滚动时显示几个滚动条
none
horizontal
vertical
android:soundEffectsEnable


android:tag

字符串tag,findViewWithTag()查找该组件
android:transformPivotX

设置该组件旋转时旋转中心的X坐标
android:transformPivotY


android:translationX

X方向上的位移
android:translationY


android:visibility

是否可见

ViewGroup继承了View类,当然也可以当成普通View来使用,但ViewGroup主要还是当成容器类使用。但由于ViewGroup是一个抽象类,实际使用中总是使用ViewGroup的子类来作为容器,例如各种布局管理器
ViewGroup容器控制其子组件的分布依赖于ViewGroup.LayoutParams、ViewGroup.MarginLayoutParams两个内部类。这两个内部类都提供了一些xml属性,ViewGroup容器中的子组件可以指定这些xml属性。

android:layout_height
支持的属性值:
fill_parent
match_parent
wrap_content
android:layout_width

为组件指定了高度与宽度,为何还要设置布局高度与布局宽度?
Android组件的大小不仅受它实际的宽度、高度控制,还受它的布局高度与布局宽度控制。
例如,设置一个组件的宽度为30如果将它的布局宽度设为match_parent,那么该组件的宽度将被“拉宽”到占满它所在的父容器;若设为wrap_content,那么该组件的宽度才会是30px。
下表显示了ViewGroup.MarginLayoutParams用于控制子组件周围页边距,其所支持的xml属性有

android:layout_marginBottom


android:layout_marginLeft


android:layout_marginRight


android:layout_marginTop




2.1.2 使用xml布局文件控制UI界面
Android使用xml布局文件来控制视图,这样可以将视图控制逻辑从Java代码中分离出来,从而更好的解耦,体现mvc原则。

当我们在Android应用res/layout目录下定义一个主文件名任意的xml布局文件后(R.java会自动收录该布局资源),Java代码可通过如下方法在Activity中显示该视图:
setContentView(R.layout.<资源文件名>);
当在布局文件中添加多个UI组件时,都可以为该UI组件指定andorid:id属性,该属性的属性值代表该组件的唯一标识。如果希望在Java代码中访问指定UI组件,可通过如下代码来访问:
findViewById(R.id.<android.id属性值>);
一旦在程序中获得指定UI组件之后,接下来就可以代码来控制各UI组件的外观行为了,包括为UI组件绑定事件监听器等
示例代码:
public class MainActivity extends ActionBarActivity {

   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
       
        LinearLayout layout =
new LinearLayout(this);
       
super.setContentView(layout);
        layout.setOrientation(LinearLayout.
VERTICAL);
       
final TextView show = new TextView(this);
        Button bn = new Button(this);
        bn.setText(get time");
        bn.setLayoutParams(new ViewGroup.LayoutParams(
        ViewGroup.LayoutParams.
WRAP_CONTENT,
        ViewGroup.LayoutParams.
WRAP_CONTENT));
        layout.addView(show);
        layout.addView(bn);
        bn.setOnClickListener(
new OnClickListener()
        {
       
@Override
       
public void onClick(View v)
        {
        show.setText(
"Hello,Android,"+ new java.util.Date());
        }
        }
        );
    }
}
可以看出,通过代码创建UI组件都需要new出一个新的对象,无论创建哪种UI组件,都需要传入一个this参数,这是由于创建UI组件时传入一个Context参数,Context代表访问Android应用环境的全局信息的API。
Activity、Service都继承了Context,都可以直接作为Context使用

2.1.4 使用xml布局文件和Java代码混合控制UI界面
这种情形下,习惯上把变化小、行为固定的组件放在xml布局文件管理中,而那些变化较多,行为控制比较复杂的组件则交给Java
图片查看器示例代码:
public class MainActivity extends ActionBarActivity {

int[] images = new int[]{
R.drawable.
java,
R.drawable.
ee,
R.drawable.
classic};
int currentImg = 0;

@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
        setContentView(R.layout.
activity_main);
        LinearLayout main = (LinearLayout) findViewById(R.id.
root);
       
final ImageView image = new ImageView(this);
        main.addView(image);
        image.setImageResource(
images[0]);
        image.setOnClickListener(
new OnClickListener()
        {
       
@Override
       
public void onClick(View v)
        {
        image.setImageResource(
images[++currentImg % images.length]);
        }
        });
}
}
当Android系统提供的UI组件不足以满足项目需要时,开发者可以通过继承View来派生自定义组件。
派生自己的组件时,通常重写的方法如下:
构造器:重写构造器是定制View的最基本方法,当Java代码创建一个View实例,或根据xml布局文件加载并构建界面时讲需要调用该构造器。
onFinishInflate():这是一个回调方法,当应用从xml布局文件加载该组件并利用它来构建界面之后,该方法将被回调
onMeasure(int,int):检测View组件及它所包含的所有子组件的大小
onLayout(boolean,int, int, int, int):当该组件需要分配其子组件的位置、大小时,该方法就会被回调
onSizeChanged(int,int, int, int):当该组件的大小被改变时该方法被回调
onDraw(Canvas):当该组件将要绘制它的内容时回调该方法进行绘制
onKeyDown(int, KeyEvent):当按下某个键时触发该方法
onKeyUp(int, KeyEvent):当松开某个按键时触发该方法
onTrackballEvent(MotionEvent):当发生轨迹球事件时触发该方法
onTouchEvent(MotionEvent):当发生触摸屏事件时触发该方法
onWindowsFocusChanged(boolean):当组件得到、失去焦点时触发
onAttachedToWindow():当把该组件放入某个窗口时触发
onDetachedFromWindow():当把该组件从某个窗口上分离时触发
onWindowsVisibilityChanged(int):当包含该组件的窗口的可见性发生改变时触发
跟随手指滚动的小球实例代码:
file:DrawView.java
public class DrawView extends View {

   
public float currentX = 360;
   
public float currentY = 540;
   
    Paint
p = new Paint();
   
public DrawView(Context context)
    {
   
super(context);
    }
   
public DrawView(Context context, AttributeSet set)
    {
   
super(context,set);
    }
   
@Override
   
public void onDraw(Canvas canvas)
    {
   
super.onDraw(canvas);
   
p.setColor(Color.RED);
    canvas.drawCircle(
currentX, currentY, 15, p);
    }
   
   
@Override
   
public boolean onTouchEvent(MotionEvent event)
    {
   
currentX =event.getX();
   
currentY =event.getY();
    invalidate();
   
return true;
   
    }
}
file:main_activity.java
public class MainActivity extends ActionBarActivity {

@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.
activity_main);
LinearLayout root = (LinearLayout) findViewById(R.id.
root);
final DrawView draw = new DrawView(this);
//draw.setMinimumWidth(300);
//draw.setMinimumHeight(500);
root.addView(draw);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值