Android学习指南 — Android基础知识汇总,附答案+考点

@Override

public boolean onDown(MotionEvent e) { return false; }

@Override

public void onShowPress(MotionEvent e) { }

@Override

public boolean onSingleTapUp(MotionEvent e) { return false; }

@Override

public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { return false; }

@Override

public void onLongPress(MotionEvent e) { }

@Override

public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { return false; }

});

mGestureDetector.setOnDoubleTapListener(new OnDoubleTapListener() {

@Override

public boolean onSingleTapConfirmed(MotionEvent e) { return false; }

@Override

public boolean onDoubleTap(MotionEvent e) { return false; }

@Override

public boolean onDoubleTapEvent(MotionEvent e) { return false; }

});

// 解决长按屏幕后无法拖动的问题

mGestureDetector.setIsLongpressEnabled(false);

imageView.setOnTouchListener(new View.OnTouchListener() {

@Override

public boolean onTouch(View v, MotionEvent event) {

return mGestureDetector.onTouchEvent(event);

}

});

如果是监听滑动相关,建议在 onTouchEvent 中实现,如果要监听双击,那么就使用 GestureDectector

Scroller


弹性滑动对象,用于实现 View 的弹性滑动,Scroller 本身无法让 View 弹性滑动,需要和 View 的 computeScroll 方法配合使用。startScroll方法是无法让 View 滑动的,invalidate 会导致 View 重绘,重回后会在 draw 方法中又会去调用 computeScroll 方法,computeScroll 方法又会去向 Scroller 获取当前的 scrollX 和 scrollY,然后通过 scrollTo 方法实现滑动,接着又调用 postInvalidate 方法如此反复。

Scroller mScroller = new Scroller(mContext);

private void smoothScrollTo(int destX) {

int scrollX = getScrollX();

int delta = destX - scrollX;

// 1000ms 内滑向 destX,效果就是慢慢滑动

mScroller.startScroll(scrollX, 0 , delta, 0, 1000);

invalidate();

}

@Override

public void computeScroll() {

if (mScroller.computeScrollOffset()) {

scrollTo(mScroller.getCurrX(), mScroller.getCurrY());

postInvalidate();

}

}

View 的滑动


  • scrollTo/scrollBy

适合对 View 内容的滑动。scrollBy 实际上也是调用了 scrollTo 方法:

public void scrollTo(int x, int y) {

if (mScrollX != x || mScrollY != y) {

int oldX = mScrollX;

int oldY = mScrollY;

mScrollX = x;

mScrollY = y;

invalidateParentCaches();

onScrollChanged(mScrollX, mScrollY, oldX, oldY);

if (!awakenScrollBars()) {

postInvalidateOnAnimation();

}

}

}

public void scrollBy(int x, int y) {

scrollTo(mScrollX + x, mScrollY + y);

}

mScrollX的值等于 View 的左边缘和 View 内容左边缘在水平方向的距离,mScrollY的值等于 View 上边缘和 View 内容上边缘在竖直方向的距离。scrollTo 和 scrollBy 只能改变 View 内容的位置而不能改变 View 在布局中的位置。

  • 使用动画

操作简单,主要适用于没有交互的 View 和实现复杂的动画效果。

  • 改变布局参数 操作稍微复杂,适用于有交互的 View.

ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) view.getLayoutParams();

params.width += 100;

params.leftMargin += 100;

view.requestLayout();

//或者 view.setLayoutParams(params);

View 的事件分发


点击事件达到顶级 View(一般是一个 ViewGroup),会调用 ViewGroup 的 dispatchTouchEvent 方法,如果顶级 ViewGroup 拦截事件即 onInterceptTouchEvent 返回 true,则事件由 ViewGroup 处理,这时如果 ViewGroup 的 mOnTouchListener 被设置,则 onTouch 会被调用,否则 onTouchEvent 会被调用。也就是说如果都提供的话,onTouch 会屏蔽掉 onTouchEvent。在 onTouchEvent 中,如果设置了 mOnClickListenser,则 onClick 会被调用。如果顶级 ViewGroup 不拦截事件,则事件会传递给它所在的点击事件链上的子 View,这时子 View 的 dispatchTouchEvent 会被调用。如此循环。

  • ViewGroup 默认不拦截任何事件。ViewGroup 的 onInterceptTouchEvent 方法默认返回 false。

  • View 没有 onInterceptTouchEvent 方法,一旦有点击事件传递给它,onTouchEvent 方法就会被调用。

  • View 在可点击状态下,onTouchEvent 默认会消耗事件。

  • ACTION_DOWN 被拦截了,onInterceptTouchEvent 方法执行一次后,就会留下记号(mFirstTouchTarget == null)那么往后的 ACTION_MOVE 和 ACTION_UP 都会拦截。`

在 Activity 中获取某个 View 的宽高


  • Activity/View#onWindowFocusChanged

// 此时View已经初始化完毕

// 当Activity的窗口得到焦点和失去焦点时均会被调用一次

// 如果频繁地进行onResume和onPause,那么onWindowFocusChanged也会被频繁地调用

public void onWindowFocusChanged(boolean hasFocus) {

super.onWindowFocusChanged(hasFocus);

if (hasFocus) {

int width = view.getMeasureWidth();

int height = view.getMeasuredHeight();

}

}

  • view.post(runnable)

// 通过post可以将一个runnable投递到消息队列的尾部,// 然后等待Looper调用次runnable的时候,View也已经初

// 始化好了

protected void onStart() {

super.onStart();

view.post(new Runnable() {

@Override

public void run() {

int width = view.getMeasuredWidth();

int height = view.getMeasuredHeight();

}

});

}

  • ViewTreeObserver

// 当View树的状态发生改变或者View树内部的View的可见// 性发生改变时,onGlobalLayout方法将被回调

protected void onStart() {

super.onStart();

ViewTreeObserver observer = view.getViewTreeObserver();

observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

@SuppressWarnings(“deprecation”)

@Override

public void onGlobalLayout() {

view.getViewTreeObserver().removeGlobalOnLayoutListener(this);

int width = view.getMeasuredWidth();

int height = view.getMeasuredHeight();

}

});

}

Draw 的基本流程


// 绘制基本上可以分为六个步骤

public void draw(Canvas canvas) {

// 步骤一:绘制View的背景

drawBackground(canvas);

// 步骤二:如果需要的话,保持canvas的图层,为fading做准备

saveCount = canvas.getSaveCount();

canvas.saveLayer(left, top, right, top + length, null, flags);

// 步骤三:绘制View的内容

onDraw(canvas);

// 步骤四:绘制View的子View

dispatchDraw(canvas);

// 步骤五:如果需要的话,绘制View的fading边缘并恢复图层

canvas.drawRect(left, top, right, top + length, p);

canvas.restoreToCount(saveCount);

// 步骤六:绘制View的装饰(例如滚动条等等)

onDrawForeground(canvas)

}

自定义 View


  • 继承 View 重写 onDraw 方法

主要用于实现一些不规则的效果,静态或者动态地显示一些不规则的图形,即重写 onDraw 方法。采用这种方式需要自己支持 wrap_content,并且 padding 也需要自己处理。

  • 继承 ViewGroup 派生特殊的 Layout

主要用于实现自定义布局,采用这种方式需要合适地处理 ViewGroup 的测量、布局两个过程,并同时处理子元素的测量和布局过程。

  • 继承特定的 View

用于扩张某种已有的View的功能

  • 继承特定的 ViewGroup

用于扩张某种已有的ViewGroup的功能

进程

==

进程(Process) 是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。

当某个应用组件启动且该应用没有运行其他任何组件时,Android 系统会使用单个执行线程为应用启动新的 Linux 进程。默认情况下,同一应用的所有组件在相同的进程和线程(称为“主”线程)中运行。

各类组件元素的清单文件条目<activity><service><receiver> 和 <provider>—均支持 android:process 属性,此属性可以指定该组件应在哪个进程运行。

进程生命周期


1、前台进程

  • 托管用户正在交互的 Activity(已调用 Activity 的 onResume() 方法)

  • 托管某个 Service,后者绑定到用户正在交互的 Activity

  • 托管正在“前台”运行的 Service(服务已调用 startForeground()

  • 托管正执行一个生命周期回调的 Service(onCreate()onStart() 或 onDestroy()

  • 托管正执行其 onReceive() 方法的 BroadcastReceiver

2、可见进程

  • 托管不在前台、但仍对用户可见的 Activity(已调用其 onPause() 方法)。例如,如果 re前台 Activity 启动了一个对话框,允许在其后显示上一 Activity,则有可能会发生这种情况。

  • 托管绑定到可见(或前台)Activity 的 Service

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值