一、Custom View

1、view的继承关系

view继承关系.png

2、Android 如何绘制试图层次

当activity获取焦点时,它必须提供layout层次的根节点,然后android 系统开始视图的绘制过程。绘制是从layout的根节点开始的,按照从上往下的顺序,父元素优先子元素。

绘制的两个过程:

measuring pass:实现measure(int,int)方法,顺序也是从上往下,每个view保存它自己的测量值

layout pass:实现layout(int,int,int,int)方法,顺序从上往下,在这个阶段每个layout manager负责他们各自所有子元素的位置,通过上一步测量的值

测量和绘制过程是交替进行的,layout manager可能运行 measure pass 若干次。例如 linearlayout需要支持weight属性,relativelayout需要测量子节点多次才能确定约束关系。

view或activity可以再次触发测量和绘制过程。通过 requestLayout()

在测量和布局计算完成后,视图就开始绘制自己。这个操作通过invalidate()触发。

3、view 截屏

每个view都支持创建当前显示状态的图片。

# Build the Drawing Cache

view.buildDrawingCache();

# Create Bitmap

Bitmap cache = view.getDrawingCache();

# Save Bitmap

saveBitmap(cache);

view.destroyDrawingCache();

二、自定义view

1、创建自定义view

通过继承view或它的子类,可以创建自定义view

通过onDraw()方法绘制视图,如果需要重新绘制,调用invalidate()触发onDraw()

如果定义自己的view,确保参考ViewConfiguration 类,它包含了一些常亮定义

2、测量

必须调用 setMeasuredDimenstion(int,int)设置结果

3、定义自定义 layout managers

通过继承ViewGroup

自定义layout manager 可以重写 onMeasure() 和 onLayout(),并且计算孩子元素的测量结果

测量孩子元素的大小通过measureChildWithMargins();

三、生命周期

一个视图会在它依附到一个已依附到window的布局结构时显示。

onAttachedToWindow() ,当window可以时调用

onDetachedFromWindow(),当视图从父元素中移除时调用(父元素必须依附到window)。例如当

activity被回收(finish()方法被调用)或者视图在listview中被回收。该方法可以用来停止动画和清理资源

四、定义自定义属性

xmlns:tools="http://schemas.android.com/tools"

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"

>

android:layout_width="match_parent"

android:layout_height="?android:attr/listPreferredItemHeight"

custom:titleText="Background color"

custom:valueColor="@android:color/holo_green_light"

/>

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

}

}

对于自定义属性中的format的值及其含义如下:

format属性值:reference 、color、boolean、dimension、float、integer、string、fraction、enum、flag

reference:参考某一资源ID。

(1)属性定义:

(2)属性使用:

android:layout_width = "42dip"

android:layout_height = "42dip"

android:background = "@drawable/图片ID"

/>

color:颜色值。

(1)属性定义:

(2)属性使用:

android:layout_width = "42dip"

android:layout_height = "42dip"

android:textColor = "#00FF00"

/>

boolean:布尔值。

(1)属性定义:

(2)属性使用:

android:layout_width = "42dip"

android:layout_height = "42dip"

android:focusable = "true"

/>

dimension:尺寸值。

(1)属性定义:

(2)属性使用:

android:layout_width = "42dip"

android:layout_height = "42dip"

/>

float:浮点值。

(1)属性定义:

(2)属性使用:

android:fromAlpha = "1.0"

android:toAlpha = "0.7"

/>

integer:整型值。

(1)属性定义:

(2)属性使用:

xmlns:android = "http://schemas.android.com/apk/res/android"

android:drawable = "@drawable/图片ID"

android:pivotX = "50%"

android:pivotY = "50%"

android:framesCount = "12"

android:frameDuration = "100"

/>

string:字符串。

(1)属性定义:

(2)属性使用:

android:layout_width = "fill_parent"

android:layout_height = "fill_parent"

android:apiKey = "0jOkQ80oD1JL9C6HAja99uGXCRiS2CGjKO_bc_g"

/>

fraction:百分数。

(1)属性定义:

(2)属性使用:

xmlns:android = "http://schemas.android.com/apk/res/android"

android:interpolator = "@anim/动画ID"

android:fromDegrees = "0"

android:toDegrees = "360"

android:pivotX = "200%"

android:pivotY = "300%"

android:duration = "5000"

android:repeatMode = "restart"

android:repeatCount = "infinite"

/>

enum:枚举值。

(1)属性定义:

(2)属性使用:

xmlns:android = "http://schemas.android.com/apk/res/android"

android:orientation = "vertical"

android:layout_width = "fill_parent"

android:layout_height = "fill_parent">

flag:位或运算。

(1)属性定义:

(2)属性使用:

android:name = ".StyleAndThemeActivity"

android:label = "@string/app_name"

android:windowSoftInputMode = "stateUnspecified |stateUnchanged | stateHidden">

特别要注意:

属性定义时可以指定多种类型值。

(1)属性定义:

(2)属性使用:

android:layout_width = "42dip"

android:layout_height = "42dip"

android:background = "@drawable/图片ID|#00FF00"

/>

下面说说AttributeSet与TypedArray在自定义控件中的作用:

AttributeSet的作用就是在控件进行初始化的时候,解析布局文件中该控件的属性(key eg:background)与该值(value eg:@drawable/icon)的信息封装在AttributeSet中,传递给该控件(View)的构造函数。对于非Android自带的属性,在View类中处理时是无法识别的,因此需要我们自己解析。所以这就要用到另外一个类TypedArray。在AttributeSet中我们有属性名称,有属性值,但是控件如何知道哪个属性代表什么意思呢?这个工作就由TypedArray来做了。TypedArray对象封装了/values/attrs.xml中的styleable里定义的每个属性的类型信息,通过TypedArray我们就可以知道AttributeSet中封装的值到底是干什么的了,从而可以对这些数据进行应用。

AttributeSet就相当于一盒糖,TypedArray就相当于这盒糖上的标签说明,告诉用户每个糖的口味等。这盒糖有什么口味是由用户自己的styleable文件里面的内容来决定的。

五、练习

在 res/values下创建文件attrs.xml

xmlns:tools="http://schemas.android.com/tools"

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"

android:showDividers="middle"

android:divider="?android:attr/listDivider"

tools:context=".MainActivity" >

android:id="@+id/view1"

android:layout_width="match_parent"

android:layout_height="?android:attr/listPreferredItemHeight"

android:background="?android:selectableItemBackground"

android:onClick="onClicked"

custom:titleText="Background color"

custom:valueColor="@android:color/holo_green_light"

/>

android:id="@+id/view2"

android:layout_width="match_parent"

android:layout_height="?android:attr/listPreferredItemHeight"

android:background="?android:selectableItemBackground"

android:onClick="onClicked"

custom:titleText="Foreground color"

custom:valueColor="@android:color/holo_orange_dark"

/>

创建布局view_color_options.xml

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:layout_centerVertical="true"

android:layout_marginLeft="16dp"

android:textSize="18sp"

/>

android:layout_width="26dp"

android:layout_height="26dp"

android:layout_centerVertical="true"

android:layout_marginLeft="16dp"

android:layout_marginRight="16dp"

/>

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginRight="16dp"

android:layout_centerVertical="true"

android:visibility="gone"

/>

package com.vogella.android.customview.compoundview;

import com.vogella.android.view.compoundview.R;

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 LinearLayout {

private View mValue;

private ImageView mImage;

public ColorOptionsView(Context context, AttributeSet attrs) {

super(context, attrs);

TypedArray a = context.obtainStyledAttributes(attrs,

R.styleable.ColorOptionsView, 0, 0);

String titleText = a.getString(R.styleable.ColorOptionsView_titleText);

int valueColor = a.getColor(R.styleable.ColorOptionsView_valueColor,

android.R.color.holo_blue_light);

a.recycle();

setOrientation(LinearLayout.HORIZONTAL);

setGravity(Gravity.CENTER_VERTICAL);

LayoutInflater inflater = (LayoutInflater) context

.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

inflater.inflate(R.layout.view_color_options, this, true);

TextView title = (TextView) getChildAt(0);

title.setText(titleText);

mValue = getChildAt(1);

mValue.setBackgroundColor(valueColor);

mImage = (ImageView) getChildAt(2);

}

public ColorOptionsView(Context context) {

this(context, null);

}

public void setValueColor(int color) {

mValue.setBackgroundColor(color);

}

public void setImageVisible(boolean visible) {

mImage.setVisibility(visible ? View.VISIBLE : View.GONE);

}

}

package com.vogella.android.customview.compoundview;

import com.vogella.android.view.compoundview.R;

import android.app.Activity;

import android.os.Bundle;

import android.view.Menu;

import android.view.View;

import android.widget.Toast;

public class MainActivity extends Activity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.activity_main, menu);

return true;

}

public void onClicked(View view) {

String text = view.getId() == R.id.view1 ? "Background" : "Foreground";

Toast.makeText(this, text, Toast.LENGTH_SHORT).show();

}

}

-----------------------华丽的分割线---------------------

最后附上ViewConfiguration 类的源码

import android.app.AppGlobals;

import android.content.Context;

import android.content.res.Configuration;

import android.content.res.Resources;

import android.graphics.Point;

import android.os.RemoteException;

import android.provider.Settings;

import android.util.DisplayMetrics;

import android.util.SparseArray;

/**

* 主要用来获取一些在UI中所使用到的标准常量,像超时、尺寸、距离

*/

public class ViewConfiguration {

/**

* 定义了水平滚动条的宽度和垂直滚动条的高度,单位是dip

*/

private static final int SCROLL_BAR_SIZE = 10;

/**

* 滚动条褪去所需要经历的时间,单位:milliseconds

*/

private static final int SCROLL_BAR_FADE_DURATION = 250;

/**

* 滚动条褪去之前的默认时间延迟,单位:milliseconds

*/

private static final int SCROLL_BAR_DEFAULT_DELAY = 300;

/**

* 定义褪去边缘的长度,单位:dip

*/

private static final int FADING_EDGE_LENGTH = 12;

/**

* 按下状态在子控件上的持续时间,单位:milliseconds

*/

private static final int PRESSED_STATE_DURATION = 64;

/**

* 定义一个按下状态转变成长按状态所需要持续的时间,单位:milliseconds

*/

private static final int DEFAULT_LONG_PRESS_TIMEOUT = 500;

/**

* 定义连续重复按键间的时间延迟,单位:milliseconds

*/

private static final int KEY_REPEAT_DELAY = 50;

/**

* 如果用户需要触发全局对话框,例如:关机,锁屏等,需要按下按钮所持续的事件,单位:milliseconds

*/

private static final int GLOBAL_ACTIONS_KEY_TIMEOUT = 500;

/**

* 定义一个触摸事件是点击还是滚动的事件间隔,如果在这个事件内没有移动,就认为这是一个点击,否则就是滚动,单位:milliseconds

*/

private static final int TAP_TIMEOUT = 180;

/**

* Defines the duration in milliseconds we will wait to see if a touch event

* is a jump tap. If the user does not complete the jump tap within this interval, it is

* considered to be a tap.

*/

private static final int JUMP_TAP_TIMEOUT = 500;

/**

* 定义双击的时间间隔,如果在这个时间内,就认为是双击

*/

private static final int DOUBLE_TAP_TIMEOUT = 300;

/**

* 定义双击最小的时间间隔

*/

private static final int DOUBLE_TAP_MIN_TIME = 40;

/**

* 定义一个触摸板触摸到释放可认为是一个点击事件而不是一个触摸移动手势的最大时间,

* 也就是说在这个时间内进行一次触摸和释放操作就可以认为是一次点击事件,单位:milliseconds

*/

private static final int HOVER_TAP_TIMEOUT = 150;

/**

* 定义一个触摸板在触摸释放之前可以移动的最大距离,

* 如果在这个距离之内就可以认为是一个点击事件,否则就是一个移动手势,单位:pixels

*/

private static final int HOVER_TAP_SLOP = 20;

/**

* 定义响应显示缩放控制的时间

*/

private static final int ZOOM_CONTROLS_TIMEOUT = 3000;

/**

* Inset in dips to look for touchable content when the user touches the edge of the screen

*/

private static final int EDGE_SLOP = 12;

/**

* 如果我们认为用户正在滚动,这里定义一个触摸事件可以滚动的距离,单位:dips

* 注意:这个值在这里定义只是作为那些没有提供上下文Context来决定密度和配置相关值的应用程序的一个备用值。

*/

private static final int TOUCH_SLOP = 8;

/**

* 定义双击事件之间可以移动的距离,单位:dips

*/

private static final int DOUBLE_TAP_TOUCH_SLOP = TOUCH_SLOP;

/**

* 定义用户尝试翻页滚动的触摸移动距离,单位:dips

*

* 注意:这个值在这里定义只是作为那些没有提供上下文Context来决定密度和配置相关值的应用程序的一个备用值。

*

*/

private static final int PAGING_TOUCH_SLOP = TOUCH_SLOP * 2;

/**

* 定义第一次点击和第二次点击可以认为是一次双击之间的距离。单位:dips

*/

private static final int DOUBLE_TAP_SLOP = 100;

/**

* Distance in dips a touch needs to be outside of a window's bounds for it to

* count as outside for purposes of dismissing the window.

*/

private static final int WINDOW_TOUCH_SLOP = 16;

/**

* 一个fling最小的速度,单位:dips/s

*/

private static final int MINIMUM_FLING_VELOCITY = 50;

/**

* 一个fling最大的速度,单位:dips/s

*/

private static final int MAXIMUM_FLING_VELOCITY = 8000;

/**

* 分发一个重复访问事件的延迟事件,单位:milliseconds

*/

private static final long SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS = 100;

/**

* The maximum size of View's drawing cache, expressed in bytes. This size

* should be at least equal to the size of the screen in ARGB888 format.

*/

@Deprecated

private static final int MAXIMUM_DRAWING_CACHE_SIZE = 480 * 800 * 4; // ARGB8888

/**

* 滚动和滑动的摩擦系数

*/

private static final float SCROLL_FRICTION = 0.015f;

/**

* Max distance in dips to overscroll for edge effects

*/

private static final int OVERSCROLL_DISTANCE = 0;

/**

* Max distance in dips to overfling for edge effects

*/

private static final int OVERFLING_DISTANCE = 6;

private final int mEdgeSlop;

private final int mFadingEdgeLength;

private final int mMinimumFlingVelocity;

private final int mMaximumFlingVelocity;

private final int mScrollbarSize;

private final int mTouchSlop;

private final int mDoubleTapTouchSlop;

private final int mPagingTouchSlop;

private final int mDoubleTapSlop;

private final int mWindowTouchSlop;

private final int mMaximumDrawingCacheSize;

private final int mOverscrollDistance;

private final int mOverflingDistance;

private final boolean mFadingMarqueeEnabled;

private boolean sHasPermanentMenuKey;

private boolean sHasPermanentMenuKeySet;

static final SparseArray sConfigurations =

new SparseArray(2);

/**

* 这个方法被废除了,使用ViewConfiguration.get(Context)}替代

*/

@Deprecated

public ViewConfiguration() {

mEdgeSlop = EDGE_SLOP;

mFadingEdgeLength = FADING_EDGE_LENGTH;

mMinimumFlingVelocity = MINIMUM_FLING_VELOCITY;

mMaximumFlingVelocity = MAXIMUM_FLING_VELOCITY;

mScrollbarSize = SCROLL_BAR_SIZE;

mTouchSlop = TOUCH_SLOP;

mDoubleTapTouchSlop = DOUBLE_TAP_TOUCH_SLOP;

mPagingTouchSlop = PAGING_TOUCH_SLOP;

mDoubleTapSlop = DOUBLE_TAP_SLOP;

mWindowTouchSlop = WINDOW_TOUCH_SLOP;

//noinspection deprecation

mMaximumDrawingCacheSize = MAXIMUM_DRAWING_CACHE_SIZE;

mOverscrollDistance = OVERSCROLL_DISTANCE;

mOverflingDistance = OVERFLING_DISTANCE;

mFadingMarqueeEnabled = true;

}

/**

* 使用给定的context来创建一个新的配置。这个配置依赖于context里面不同的参数,例如显示的尺寸或者密度

* @param context 用来初始化这个view配置的应用上下文环境

*

* @see #get(android.content.Context)

* @see android.util.DisplayMetrics

*/

private ViewConfiguration(Context context) {

final Resources res = context.getResources();

final DisplayMetrics metrics = res.getDisplayMetrics();

final Configuration config = res.getConfiguration();

final float density = metrics.density;

final float sizeAndDensity;

if (config.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_XLARGE)) {

sizeAndDensity = density * 1.5f;

} else {

sizeAndDensity = density;

}

mEdgeSlop = (int) (sizeAndDensity * EDGE_SLOP + 0.5f);

mFadingEdgeLength = (int) (sizeAndDensity * FADING_EDGE_LENGTH + 0.5f);

mMinimumFlingVelocity = (int) (density * MINIMUM_FLING_VELOCITY + 0.5f);

mMaximumFlingVelocity = (int) (density * MAXIMUM_FLING_VELOCITY + 0.5f);

mScrollbarSize = (int) (density * SCROLL_BAR_SIZE + 0.5f);

mDoubleTapSlop = (int) (sizeAndDensity * DOUBLE_TAP_SLOP + 0.5f);

mWindowTouchSlop = (int) (sizeAndDensity * WINDOW_TOUCH_SLOP + 0.5f);

// Size of the screen in bytes, in ARGB_8888 format

final WindowManager win = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);

final Display display = win.getDefaultDisplay();

final Point size = new Point();

display.getRealSize(size);

mMaximumDrawingCacheSize = 4 * size.x * size.y;

mOverscrollDistance = (int) (sizeAndDensity * OVERSCROLL_DISTANCE + 0.5f);

mOverflingDistance = (int) (sizeAndDensity * OVERFLING_DISTANCE + 0.5f);

if (!sHasPermanentMenuKeySet) {

IWindowManager wm = WindowManagerGlobal.getWindowManagerService();

try {

sHasPermanentMenuKey = !wm.hasNavigationBar();

sHasPermanentMenuKeySet = true;

} catch (RemoteException ex) {

sHasPermanentMenuKey = false;

}

}

mFadingMarqueeEnabled = res.getBoolean(

com.android.internal.R.bool.config_ui_enableFadingMarquee);

mTouchSlop = res.getDimensionPixelSize(

com.android.internal.R.dimen.config_viewConfigurationTouchSlop);

mPagingTouchSlop = mTouchSlop * 2;

mDoubleTapTouchSlop = mTouchSlop;

}

/**

* 跟上面一个函数一样,只不过上面一个是创建一个ViewConfiguration对象,这里是直接通过这个静态方法返回一个对象

*/

public static ViewConfiguration get(Context context) {

final DisplayMetrics metrics = context.getResources().getDisplayMetrics();

final int density = (int) (100.0f * metrics.density);

ViewConfiguration configuration = sConfigurations.get(density);

if (configuration == null) {

configuration = new ViewConfiguration(context);

sConfigurations.put(density, configuration);

}

return configuration;

}

/**

* @return 获取水平滚动条的宽带和垂直滚动条的高度

*

* 这个函数被废除,使用getScaledScrollBarSize()来代替

*/

@Deprecated

public static int getScrollBarSize() {

return SCROLL_BAR_SIZE;

}

/**

* @return 获取水平滚动条的宽带和垂直滚动条的高度

*/

public int getScaledScrollBarSize() {

return mScrollbarSize;

}

/**

* @return 滚动条褪去的持续时间

*/

public static int getScrollBarFadeDuration() {

return SCROLL_BAR_FADE_DURATION;

}

/**

* @return 滚动条褪去的延迟时间

*/

public static int getScrollDefaultDelay() {

return SCROLL_BAR_DEFAULT_DELAY;

}

/**

* @return 褪去边缘的长度

*

* 这个方法已经废弃,用getScaledFadingEdgeLength()替代.

*/

@Deprecated

public static int getFadingEdgeLength() {

return FADING_EDGE_LENGTH;

}

/**

* @return 褪去边缘的长度,单位:pixels

*/

public int getScaledFadingEdgeLength() {

return mFadingEdgeLength;

}

/**

* @return 在子控件上按住状态的持续时间

*/

public static int getPressedStateDuration() {

return PRESSED_STATE_DURATION;

}

/**

* @return 按住状态转变为长按状态需要的时间

*/

public static int getLongPressTimeout() {

return AppGlobals.getIntCoreSetting(Settings.Secure.LONG_PRESS_TIMEOUT,

DEFAULT_LONG_PRESS_TIMEOUT);

}

/**

* @return 重新按键时间

*/

public static int getKeyRepeatTimeout() {

return getLongPressTimeout();

}

/**

* @return 重复按键延迟时间

*/

public static int getKeyRepeatDelay() {

return KEY_REPEAT_DELAY;

}

/**

* @return 判断用户是单击还是滚动的时间,在这个时间内没有移动则是单击,否则是滚动

*/

public static int getTapTimeout() {

return TAP_TIMEOUT;

}

/**

* @return the duration in milliseconds we will wait to see if a touch event

* is a jump tap. If the user does not move within this interval, it is

* considered to be a tap.

*/

public static int getJumpTapTimeout() {

return JUMP_TAP_TIMEOUT;

}

/**

* @return 得到双击间隔时间,在这个时间内,则是双击,否则就是单击

*/

public static int getDoubleTapTimeout() {

return DOUBLE_TAP_TIMEOUT;

}

/**

* @return the minimum duration in milliseconds between the first tap's

* up event and the second tap's down event for an interaction to be considered a

* double-tap.

*

* @hide

*/

public static int getDoubleTapMinTime() {

return DOUBLE_TAP_MIN_TIME;

}

/**

* @return the maximum duration in milliseconds between a touch pad

* touch and release for a given touch to be considered a tap (click) as

* opposed to a hover movement gesture.

* @hide

*/

public static int getHoverTapTimeout() {

return HOVER_TAP_TIMEOUT;

}

/**

* @return the maximum distance in pixels that a touch pad touch can move

* before being released for it to be considered a tap (click) as opposed

* to a hover movement gesture.

* @hide

*/

public static int getHoverTapSlop() {

return HOVER_TAP_SLOP;

}

/**

* @return Inset in dips to look for touchable content when the user touches the edge of the

* screen

*

* @deprecated Use {@link #getScaledEdgeSlop()} instead.

*/

@Deprecated

public static int getEdgeSlop() {

return EDGE_SLOP;

}

/**

* @return Inset in pixels to look for touchable content when the user touches the edge of the

* screen

*/

public int getScaledEdgeSlop() {

return mEdgeSlop;

}

/**

* @return Distance in dips a touch can wander before we think the user is scrolling

*

* @deprecated Use {@link #getScaledTouchSlop()} instead.

*/

@Deprecated

public static int getTouchSlop() {

return TOUCH_SLOP;

}

/**

* @return Distance in pixels a touch can wander before we think the user is scrolling

*/

public int getScaledTouchSlop() {

return mTouchSlop;

}

/**

* @return Distance in pixels the first touch can wander before we do not consider this a

* potential double tap event

* @hide

*/

public int getScaledDoubleTapTouchSlop() {

return mDoubleTapTouchSlop;

}

/**

* @return Distance in pixels a touch can wander before we think the user is scrolling a full

* page

*/

public int getScaledPagingTouchSlop() {

return mPagingTouchSlop;

}

/**

* @return Distance in dips between the first touch and second touch to still be

* considered a double tap

* @deprecated Use {@link #getScaledDoubleTapSlop()} instead.

* @hide The only client of this should be GestureDetector, which needs this

* for clients that still use its deprecated constructor.

*/

@Deprecated

public static int getDoubleTapSlop() {

return DOUBLE_TAP_SLOP;

}

/**

* @return Distance in pixels between the first touch and second touch to still be

* considered a double tap

*/

public int getScaledDoubleTapSlop() {

return mDoubleTapSlop;

}

/**

* Interval for dispatching a recurring accessibility event in milliseconds.

* This interval guarantees that a recurring event will be send at most once

* during the {@link #getSendRecurringAccessibilityEventsInterval()} time frame.

*

* @return The delay in milliseconds.

*

* @hide

*/

public static long getSendRecurringAccessibilityEventsInterval() {

return SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS;

}

/**

* @return Distance in dips a touch must be outside the bounds of a window for it

* to be counted as outside the window for purposes of dismissing that

* window.

*

* @deprecated Use {@link #getScaledWindowTouchSlop()} instead.

*/

@Deprecated

public static int getWindowTouchSlop() {

return WINDOW_TOUCH_SLOP;

}

/**

* @return Distance in pixels a touch must be outside the bounds of a window for it

* to be counted as outside the window for purposes of dismissing that window.

*/

public int getScaledWindowTouchSlop() {

return mWindowTouchSlop;

}

/**

* @return Minimum velocity to initiate a fling, as measured in dips per second.

*

* @deprecated Use {@link #getScaledMinimumFlingVelocity()} instead.

*/

@Deprecated

public static int getMinimumFlingVelocity() {

return MINIMUM_FLING_VELOCITY;

}

/**

* @return 得到滑动的最小速度, 以像素/每秒来进行计算

*/

public int getScaledMinimumFlingVelocity() {

return mMinimumFlingVelocity;

}

/**

* @return Maximum velocity to initiate a fling, as measured in dips per second.

*

* @deprecated Use {@link #getScaledMaximumFlingVelocity()} instead.

*/

@Deprecated

public static int getMaximumFlingVelocity() {

return MAXIMUM_FLING_VELOCITY;

}

/**

* @return 得到滑动的最大速度, 以像素/每秒来进行计算

*/

public int getScaledMaximumFlingVelocity() {

return mMaximumFlingVelocity;

}

/**

* The maximum drawing cache size expressed in bytes.

*

* @return the maximum size of View's drawing cache expressed in bytes

*

* @deprecated Use {@link #getScaledMaximumDrawingCacheSize()} instead.

*/

@Deprecated

public static int getMaximumDrawingCacheSize() {

//noinspection deprecation

return MAXIMUM_DRAWING_CACHE_SIZE;

}

/**

* The maximum drawing cache size expressed in bytes.

*

* @return the maximum size of View's drawing cache expressed in bytes

*/

public int getScaledMaximumDrawingCacheSize() {

return mMaximumDrawingCacheSize;

}

/**

* @return The maximum distance a View should overscroll by when showing edge effects (in

* pixels).

*/

public int getScaledOverscrollDistance() {

return mOverscrollDistance;

}

/**

* @return The maximum distance a View should overfling by when showing edge effects (in

* pixels).

*/

public int getScaledOverflingDistance() {

return mOverflingDistance;

}

/**

* The amount of time that the zoom controls should be

* displayed on the screen expressed in milliseconds.

*

* @return the time the zoom controls should be visible expressed

* in milliseconds.

*/

public static long getZoomControlsTimeout() {

return ZOOM_CONTROLS_TIMEOUT;

}

/**

* The amount of time a user needs to press the relevant key to bring up

* the global actions dialog.

*

* @return how long a user needs to press the relevant key to bring up

* the global actions dialog.

*/

public static long getGlobalActionKeyTimeout() {

return GLOBAL_ACTIONS_KEY_TIMEOUT;

}

/**

* The amount of friction applied to scrolls and flings.

*

* @return A scalar dimensionless value representing the coefficient of

* friction.

*/

public static float getScrollFriction() {

return SCROLL_FRICTION;

}

/**

* Report if the device has a permanent menu key available to the user.

*

*

As of Android 3.0, devices may not have a permanent menu key available.

* Apps should use the action bar to present menu options to users.

* However, there are some apps where the action bar is inappropriate

* or undesirable. This method may be used to detect if a menu key is present.

* If not, applications should provide another on-screen affordance to access

* functionality.

*

* @return true if a permanent menu key is present, false otherwise.

*/

public boolean hasPermanentMenuKey() {

return sHasPermanentMenuKey;

}

/**

* @hide

* @return Whether or not marquee should use fading edges.

*/

public boolean isFadingMarqueeEnabled() {

return mFadingMarqueeEnabled;

}

}

android自定义view生命周期,android基础之自定义view相关推荐

  1. android自定义的生命周期,android 自定义控件之ViewGroup生命周期执行步骤(示例代码)...

    前言 了解ViewGroup的生命周期的执行步骤对于自己自定义ViewGroup的时候十分重要,清楚了整个流程才能对ViewGroup有更深的理解.本文从个人的总结,来阐述一下执行的顺序. 执行说明 ...

  2. android view销毁事件,Android View生命周期(笔记记录)

    一.View 的定义 View 就是屏幕上的一块矩形区域,我们可以在这块区域绘制我们想让用户看到的图形(负责绘制这个区域和事件的处理),View 默认是可见的. 二.View的生命周期 View生命周 ...

  3. android activity 回调函数,Android Activity的生命周期

    Activity的生命周期 Android系统根据activity的所处不同阶段对应的唤起其特定的回调函数来执行代码.activity的一系列有序的生命周期回调函数.本文将来讨论下activity各阶 ...

  4. Android 广播的生命周期

    一:Android 广播的生命周期          一个广播接收者有一个回调方法:void onReceive(Context curContext, Intent broadcastMsg).当一 ...

  5. 深入理解 Android Activity的生命周期

    深入理解 Android Activity的生命周期 2010-10-13 14:08:29|  分类: Android |  标签:周期  调用  activity  android  protec ...

  6. Android笔记 activity生命周期 Tasks and back stack回退栈

    正常打开一个应用,先后调用Activity的onCreate.onStart.onResume 正常退出一个应用,先后调用Activity的onPause.onStop.onDestroy(进程被杀死 ...

  7. 第六章 Android应用的生命周期

    应用程序的生命周期: Android系统决定一个进程生命周期的主要因素包括: 1.系统当前剩余多少可用内存--内存不足时,杀死一些进程释放内存 2.该进程对于用户的重要性--优先杀死对用户不重要的进程 ...

  8. android 横屏finish 会变竖屏,[android] Activity 的生命周期 以及 横屏竖屏切换时 Activity 的状态变化...

    生命周期 Android 系统在Activity 生命周期中加入一些钩子,我们可以在这些系统预留的钩子中做一些事情. 例举了 7 个常用的钩子:protected void onCreate(Bund ...

  9. 【Android笔记】Android MediaPlayer的生命周期

    Android MediaPlayer的生命周期 MediaPlayer的状态转换图也表征了它的生命周期,搞清楚这个图可以帮助我们在使用

最新文章

  1. MySQL性能优化、故障排查及最佳实践秘籍,阿里云数据库专家玄惭的“武功”全记录...
  2. 4-2 ADO.NET-查询和检索数据5
  3. Amazon EC2云端服务器的使用方法
  4. lpk.dll是什么
  5. ---WebCam网络摄像头10 socket
  6. 分享一批国内常用的tracker地址
  7. 第六章连接和分组查询
  8. es6 Null 传导运算符
  9. ApacheCN 所有教程/文档集已备份到 Coding
  10. CSDN写博客时设置图片显示大小
  11. wifi rssi 计算 距离_SKYLAB:蓝牙室内定位与WiFi室内定位的对比分析
  12. 打印纸张尺寸换算_纸张开本和尺寸对照表!
  13. 倾听开源Android的另类声音
  14. 关于nvidia-smi和nvidia -V即nvidia --verison的命令说明
  15. 记一次很坑很坑的报错java.lang.Exception: The class is not public.
  16. 程序员的福利:使用WebCollector爬取某美女网站上的图片
  17. 微型计算机内存容量大小一般是指什么的容量,通常说的计算机内存大小指的是什么?...
  18. 浅谈高内聚与松耦合,各人自扫门前雪,莫管他人瓦上霜
  19. TN.STN液晶屏常见问题及解决办法
  20. AR、MA、ARMA和ARIMA模型------时间序列预测

热门文章

  1. android长截屏代码,android长截屏原理及实现代码
  2. 川大和西南交大计算机考研难易度,2020考研:百所211院校报考难易度分析
  3. 深入jvm虚拟机第4版_深入理解JVM虚拟机
  4. python实现Matlab中的circshift函数
  5. 热狗树 树形dp(中国石油大学我要变强第九场)
  6. Books Queries(codeforces 1066)
  7. xshell连接服务器响应慢,Xshell 连接虚拟机很慢
  8. python 服务端性能_python 学习笔记---Locust 测试服务端性能
  9. arraylist如何检测某一元素是否为空_我们应该如何理解Java集合框架的关键知识点?...
  10. String(字符串) 比较大小 如果有A+BB+A 则AB