现在的位置: 首页 > 综合 > 正文

Creating custom and compound Views in Android

2018年05月16日 ⁄ 综合 ⁄ 共 4806字 ⁄ 字号 评论关闭

原文地址:         http:/(删掉我)/www.vogella.com/tutorials/AndroidCustomViews/article.html#customviews  

如下是我的翻译:


1..自定义视图


1.1. Default views

Android framework提供了几个默认的视图,但开发者也可以自定义自己的视图在他们的app中。

其中基本的类是view





1.2. How Android draws the view hierarchy

一旦activity获得焦点,它必须提供给系统它的布局层次中的根节点。之后系统开始绘制。

绘制是从布局的根节点开始的。依据他们所声明的顺序,换言之,父层是先于它的子层开始绘制的,而子层先于子子层绘制(递归)...


绘制布局要经过两个层次:

1)通过测量(measuring pass)实现measure(int,
int)方法,它自上而下遍历视图层。每个视图存储它的测量。

2)通过布局(layout
pass
)实现layout(int, int, int, int),它自上而下遍历视图层。在此阶段,每个布局管理器负责定位它的所有子视图。它使用计算过的大小(在measuring
pass中
)。

注意:测量与布局这两个阶段通常一块发生。布局管理器通常会使用measuring
pass几次。


view或者activity可以调用requestLayout()来触发measure
and layout pass。

measure
and layout pass之后,视图绘制自身,通过调用view中 invalidate()方法,这个操作被触发。

1.3. Reasons for creating views

可以自定义自己的交互。

1.4. Responsibility of views

视图是负责测量,布点和绘画自己和他们的子元素(如果是一个ViewGroup)。它还负责保存自己的UI状态和处理触摸事件。

1.5. Ways of creating custom views

自定义的视图大致有两类:复合视图和定制的视图。
所以可以通过以下两种方式来创建自定义视图:
1)复合视图(Compound views
2)自定义视图(Custom views):a.继承一个已经存在的视图。b.继承视图类。


1.6. Using new views in layout files

视图可以被应用于布局文件中。你必须使用完全且规范的名称。举个例子:
<?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="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />

    <de.vogella.android.ownview.MyDrawView
        android:id="@+id/myDrawView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout> 



1.7. Create screenshots (Images) of views

每个视图类支持它当前显示图像的创建。举个例子:
<pre name="code" class="java"># Build the Drawing Cache
view.buildDrawingCache();

# Create Bitmap
Bitmap cache = view.getDrawingCache();

# Save Bitmap
saveBitmap(cache);
view.destroyDrawingCache(); 

2.复合视图

复合视图也称复合组件(Compound Components),它可以基于已有的view为viewgroup所配置。

复合视图也允许你添加自定义的api去更新,查询该视图的状态。

你可以定义一个布局文件,并将其分配给您的复合视图。在你的复合视图的实现您预定义的视图交互。你需定义一个布局文件,并继承相应的视图组类。在这个类中你可以填充(inflate)的布局文件和实施视图连接逻辑。

3. 创建自定义视图

3.1. Creating custom views

你可以通过继承view或者其子类来创建。使用onDraw()来绘制视图,在此方法中,你可用Canvas对象来执行绘制。(想画个线,圆,图...)。如果视图被重新绘制,你可以调用invalidate() 来触发调用该视图的onDraw()方法。你可以使用2D
Canvas API.去绘制视图。

3.2. Measurement

布局管理器调用视图的onMeasure()方法。该视图从布局管理器接收的布局参数。布局管理器负责决定其所有子项的大小。

视图必须调用setMeasuredDimenstion(int,
int)。

3.3. Defining custom layout managers

通过拓展ViewGroup,你可以实现自己的布局管理器。这允许你实现更加高效,或者当前android系统中尚不存在的布局管理器。
自定义布局管理器可以覆盖onMeasure()和OnLayout()方法,并指定其子项的计算。
你可以在你拓展的类中使用内部类来存储布局参数。(举个例子:LinearLayout的内部类:LinearLayout.LayoutParams

4. Life cycle

4.1. Life cycle events related to the window

视图有几个生命周期挂钩。该onAttachedToWindow()被调用一次窗口是可用的。

当视图是从其父移除(如果父连接到一个窗口)的onDetachedFromWindow()被使用。举个例子:当activity被回收,或者在ListView中的view被回收。

onDetachedFromWindow()被用作停止动画和清理资源。

4.2. Traversal life cycle events

遍历生命周期事件包括动画,测量,布置和绘制。

所有视图必须知道如何测量和布局本身。该requestLayout()方法调用告诉视图来测量和布局本身。由于这种操作可能会影响其他视图的布局。

onMeasure() 方法决定视图及其孩子的大小。在它返回前,必须通过调用setMeasuredDimension()来设置其尺寸。

onLayout() 摆放视图,其基于onMeasure() 的方法

4.3. Activity life cycle

视图不可访问activity的生命周期事件。如果视图希望得到有关这些事件,你应该在你的activity的生命周期方法调用该视图所创建一个接口。

5. Define additional attributes for your custom Views

可以为你的视图定义额外的属性。
你可以在res/values文件夹下定义属性文件attrs.xml。下面是个例子:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="ColorOptionsView">
        <attr name="titleText" format="string" localization="suggested" />
        <attr name="valueColor" format="color" />
    </declare-styleable>

</resources> 

在你的布局文件中去使用这些属性,你需要在xml首部声明他们。下面是个例子

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
<!-- define new name space for your attributes -->
    xmlns:custom="http://schemas.android.com/apk/res/com.vogella.android.view.compoundview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
>
<!-- Assume that this is your new component. It uses your new attributes -->
        <com.vogella.android.view.compoundview.ColorOptionsView
            android:layout_width="match_parent"
            android:layout_height="?android:attr/listPreferredItemHeight"
            custom:titleText="Background color"
            custom:valueColor="@android:color/holo_green_light"
             />

</LinearLayout> 

下面的示例显示了组件如何访问这些属性。

package com.vogella.android.view.compoundview;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class ColorOptionsView extends View {

  private View mValue;
  private ImageView mImage;

  public ColorOptionsView(Context context, AttributeSet attrs) {
    super(context, attrs);

    TypedArray a = context.obtainStyledAttributes(attrs,
        R.styleable.Options, 0, 0);
    String titleText = a.getString(R.styleable.Options_titleText);
    int valueColor = a.getColor(R.styleable.Options_valueColor,
        android.R.color.holo_blue_light);
    a.recycle();

    // more stuff
  }


} 

下面一些相关且比较好的文章:

http://blog.csdn.net/loongggdroid/article/details/17515113




抱歉!评论已关闭.