1:DisplayMetrics Display 获取屏幕的基本信息
DisplayMetrics displayMetrics=new DisplayMetrics(); Display display=getWindowManager().getDefaultDisplay(); display.getMetrics(displayMetrics); Log.d(TAG, "onClick: densityDpi=="+displayMetrics.densityDpi+"--density=="+displayMetrics.density+ "--heightPixels=="+displayMetrics.heightPixels+ "--widthPixels=="+displayMetrics.widthPixels+"--xdpi=="+displayMetrics.xdpi+ "-ydpi=="+displayMetrics.ydpi+"--=="+displayMetrics.scaledDensity);
2:keyEvent
//对应的键值,KeyEvent.KEYCODE_DPAD_LEFT;
keyEvent.getKeyCode();
//对应那种操作 按下或者抬起 KeyEvent.ACTION_DOWN;
keyEvent.getAction(); //获取按键事件触发的次数 keyEvent.getRepeatCount(); //不准确 keyEvent.isLongPress(); 长按事件执行的流程:
长按事件执行顺序为先执行down事件getrepeatcount一直增加(判断是否为长按事件,只需要判断getrepeatcount是否大于零)
直到最后按键起来事件变为up事件getrepeatcount为0activity里面dispatchKeyEvent相关逻辑,
event.dispatch(this, decor != null ? decor.getKeyDispatcherState() : null, this);这个时候我们将activity自身
class Activity extends ContextThemeWrapper implements KeyEvent.Callback, activity自身实现了keyevent的callback回调接口 所以 在activity里面可以得到这些回调方法public boolean dispatchKeyEvent(KeyEvent event) {
onUserInteraction(); // Let action bars open menus in response to the menu key prioritized over // the window handling it if (event.getKeyCode() == KeyEvent.KEYCODE_MENU && mActionBar != null && mActionBar.onMenuKeyEvent(event)) { return true; } Window win = getWindow(); if (win.superDispatchKeyEvent(event)) { return true; } View decor = mDecor; if (decor == null) decor = win.getDecorView(); return event.dispatch(this, decor != null ? decor.getKeyDispatcherState() : null, this); }view同样如此:view除了可以回调实现的值按键信息,还可以通过主动监听的方式实现及
but.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { return false; } });
3:LayoutInflater.Factory
实现换肤效果:主题切换
http://blog.youkuaiyun.com/llew2011/article/details/51287391
4:SurfaceHolder 是一个接口
SurfaceHolder.Callback
surfaceviewTextureView
GLSurfaceView
SurfaceTexture
5: ViewTreeObserver
ViewTreeObserver 注册一个观察者来监听视图树,当视图树的布局、视图树的焦点、视图树将要绘制、
视图树滚动等发生改变时,ViewTreeObserver都会收到通知,ViewTreeObserver不能被实例化,可以调用
View.getViewTreeObserver()来获得。
视图树滚动等发生改变时,ViewTreeObserver都会收到通知,ViewTreeObserver不能被实例化,可以调用
View.getViewTreeObserver()来获得。
通过ViewTreeObserver .addOnPreDrawListener来获得宽高,在执行onDraw之前已经执行了
onLayout()和onMeasure(),可以得到宽高了,当获得正确的宽高后,请移除这个观察者,
否则回调会多次执行
ViewTreeObserver observer=view.getViewTreeObserver();
//注册观察者,监听变化
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override public boolean onPreDraw()
{
if(observer.isAlive()){ observer.removeOnDrawListener(this);
}
//获得宽高
int viewWidth=view.getMeasuredWidth();
int viewHeight=view.getMeasuredHeight();
return true; } });
6:Context获取各种系统服务:
public abstract Object getSystemService(@ServiceName @NonNull String name);
WINDOW_SERVICE = "window";
windowManager= (WindowManager) getSystemService(Context.WINDOW_SERVICE);
7: Window PhoneWindow
每一个Activity都包含一个Window对象,Window对象通常由PhoneWindow实现PhoneWindow:将Decoriew设置为整个应用窗口的根View。是Window的实现类。它是Android中的最基本的窗口系统,每个Activity 均会创建一个PhoneWindow对象,是Activity和整个View系统交互的接口。DecorView:顶层视图,将要显示的具体内容呈现在PhoneWindow上.
DecorView是当前Activity所有View的祖先,它并不会向用户呈现任何东西,它主要有如下几个功能,可能不全:
DecorView是当前Activity所有View的祖先,它并不会向用户呈现任何东西,它主要有如下几个功能,可能不全:
- A. Dispatch ViewRoot分发来的key、touch、trackball等外部事件;
- B. DecorView有一个直接的子View,我们称之为System Layout,这个View是从系统的Layout.xml中解析出的,
- 它包含当前UI的风格,如是否带title、是否带process bar等。可以称这些属性为Window decorations。
- C. 作为PhoneWindow与ViewRoot之间的桥梁,ViewRoot通过DecorView设置窗口属性。
- //可以这样获取 View view = getWindow().getDecorView();
- DecorView只有一个子元素为LinearLayout。代表整个Window界面,包含通知栏,标题栏,内容显示栏三块区域。
- DecorView里面TitleView:标题,可以设置requestWindowFeature(Window.FEATURE_NO_TITLE)
- 取消掉ContentView:是一个id为content的FrameLayout。
- 我们平常在Activity使用的setContentView就是设置在这里,也就是在FrameLayout上
ViewGroup viewone= (ViewGroup) getWindow().getDecorView(); Log.d(TAG, "onCreate: getChildCount=="+viewone.getChildCount()); ViewGroup viewThree= (ViewGroup) viewone.getChildAt(0); if(viewThree instanceof LinearLayout){ Log.d(TAG, "onCreate: LinearLayout"); } Log.d(TAG, "onCreate: getChildCount=="+viewThree.getChildCount()); ViewGroup viewfour= (ViewGroup) viewThree.getChildAt(1); if(viewfour instanceof FrameLayout){ Log.d(TAG, "onCreate: FrameLayout"); } // 就是我们setContentView使用的view View viewTwo= findViewById(android.R.id.content); if(viewTwo instanceof FrameLayout){ Log.d(TAG, "onCreate: FrameLayout"); } if(viewTwo.equals(viewfour)){ Log.d(TAG, "onCreate: 同一个对象"); } // D/MainActivity: onCreate: getChildCount==1 // /MainActivity: onCreate: LinearLayout // D/MainActivity: onCreate: getChildCount==2 // D/MainActivity: onCreate: FrameLayout // D/MainActivity: onCreate: FrameLayout // D/MainActivity: onCreate: 同一个对象关键看Window的实现类PhoneWindow
setContentView源码简单介绍:
getWindow().setContentView(layoutResID);
installDecor();
创建decorview 获取我们设置的feature 就是为什么我们需要在setContentView之前
调用设置feature的api
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
Window是一个抽象类,提供了各种窗口操作的方法,比如设置背景标题ContentView等等PhoneWindow则是Window的唯一实现类,它里面实现了各种添加背景主题ContentView的方法,内部通过DecorView来添加顶级视图每一个Activity上面都有一个Window,可以通过getWindow获取DecorView,顶级视图,继承与FramentLayout,setContentView则是添加在它里面的@id/content里setContentView里面创建了DecorView,根据Theme,Feature添加了对应的布局文件当setContentView设置显示后会回调Activity的onContentChanged方法
KeyEvent.Callback
就是一个接口 系统class实现这个接口 进行相关回调。9:
OnKeyListener
10:Window.Callback
public boolean dispatchKeyEvent(KeyEvent event);
public boolean dispatchKeyShortcutEvent(KeyEvent event);
public boolean dispatchTouchEvent(MotionEvent event);
public boolean dispatchTrackballEvent(MotionEvent event);
public boolean dispatchGenericMotionEvent(MotionEvent event);
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event);
@Nullable public View onCreatePanelView(int featureId);
public boolean onCreatePanelMenu(int featureId, Menu menu);
public void onWindowAttributesChanged(WindowManager.LayoutParams attrs);
public void onContentChanged();
public void onWindowFocusChanged(boolean hasFocus);
public void onAttachedToWindow();
public void onDetachedFromWindow();
11:
VelocityTracker
//获取一个VelocityTracker对象, 用完后记得回收//回收后代表你不需要使用了,系统将此对象在此分配到其他请求者
static public VelocityTracker obtain();
public void recycle();
//计算当前速度, 其中units是单位表示, 1代表px/毫秒, 1000代表px/秒, ..
//maxVelocity此次计算速度你想要的最大值
public void computeCurrentVelocity(int units, float maxVelocity);
//经过一次computeCurrentVelocity后你就可以用一下几个方法获取此次计算的值
//id是touch event触摸点的ID, 来为多点触控标识,有这个标识在计算时可以忽略
//其他触点干扰,当然干扰肯定是有的
public float getXVelocity();
public float getYVelocity();
public float getXVelocity(int id);
public float getYVelocity(int id);
使用步骤:
声明
private VelocityTracker mVelocityTracker;
初始化
private void init() { mVelocityTracker = VelocityTracker.obtain(); }
在onTouchEvent的开头添加滑动事件
public boolean onTouchEvent(MotionEvent event) { mVelocityTracker.addMovement(event); ... }
在onTouchEvent的MotionEvent.ACTION_UP中使用
case MotionEvent.ACTION_UP: {
int scrollX = getScrollX();
int scrollToChildIndex = scrollX / mChildWidth;
mVelocityTracker.computeCurrentVelocity(1000);
float xVelocity = mVelocityTracker.getXVelocity();
if (Math.abs(xVelocity) >= 50) {
mChildIndex = xVelocity > 0 ? mChildIndex - 1 : mChildIndex + 1;
} else {
mChildIndex = (scrollX + mChildWidth / 2) / mChildWidth;
}
mChildIndex = Math.max(0, Math.min(mChildIndex, mChildrenSize - 1));
int dx = mChildIndex * mChildWidth - scrollX;
smoothScrollBy(dx, 0);
mVelocityTracker.clear();
break;
}
在onDetachedFromWindow中回收
@Override
protected void onDetachedFromWindow() {
mVelocityTracker.recycle();
super.onDetachedFromWindow();
}
Configuration configuration=getResources().getConfiguration();