最后
给大家分享一份移动架构大纲,包含了移动架构师需要掌握的所有的技术体系,大家可以对比一下自己不足或者欠缺的地方有方向的去学习提升;
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
mFinished = mScroller.isFinished();
if(mFinished){
int x = (int) ev.getX();
int width = getWidth();
if(mPanelInvisible)// 左侧面板可见
{
if(x > (width - mHandlebarWidth)){ // 当前手指按下的坐标x值 ,是在手柄宽度范围内
isClick = true;
mAllowScroll = true;
return true;
} else {
isClick = false;
mAllowScroll = false;
}
} else { // 左侧面板不可见
if(x < mHandlebarWidth ){ // 当前手指按下的坐标x值 < 手柄宽度 (也就是说在手柄宽度范围内,是可以相应用户的向右滑动手势)
mAllowScroll = true;
}else{
mAllowScroll = false;
}
}
} else {
// 当前正在滚动子View,其它的事不响应
return false;
}
break;
case MotionEvent.ACTION_MOVE:
Log.i(TAG, "dispatchTouchEvent(): ACTION_MOVE");
int margin = getWidth() - (int) ev.getX();
if (margin < mHandlebarWidth && mAllowScroll) {
Log.e(TAG, "dispatchTouchEvent ACTION_MOVE margin = " + margin + "\t mHandlebarWidth = " + mHandlebarWidth);
return true;
}
break;
case MotionEvent.ACTION_UP:
Log.i(TAG, "dispatchTouchEvent(): ACTION_UP");
if (isClick && mPanelInvisible && mAllowScroll) {
isClick = false;
mPanelInvisible = false;
int scrollX = getChildAt(1).getScrollX();
mScroller.startScroll(scrollX, 0, -scrollX, 0, ANIMATION_DURATION_TIME);
invalidate();
return true;
}
break;
case MotionEvent.ACTION_CANCEL:
Log.i(TAG, "dispatchTouchEvent(): ACTION_CANCEL");
break;
default:
break;
}
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.e(TAG, "onInterceptTouchEvent()");
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.i(TAG, "onInterceptTouchEvent(): ACTION_DOWN");
mFinished = mScroller.isFinished();
if(!mFinished){
return false;
}
break;
case MotionEvent.ACTION_MOVE:
Log.i(TAG, "onInterceptTouchEvent(): ACTION_MOVE");
mVelocityTracker = VelocityTracker.obtain();
mVelocityTracker.addMovement(ev);
// 一秒时间内移动了多少个像素
mVelocityTracker.computeCurrentVelocity(1000, ViewConfiguration.getMaximumFlingVelocity());
float velocityValue = Math.abs(mVelocityTracker.getXVelocity()) ;
Log.d(TAG, "onInterceptTouchEvent(): mVelocityValue = " + velocityValue);
if (velocityValue > 300 && mAllowScroll) {
return true;
}
break;
case MotionEvent.ACTION_UP:
Log.i(TAG, "onInterceptTouchEvent(): ACTION_UP");
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
break;
case MotionEvent.ACTION_CANCEL:
Log.i(TAG, "onInterceptTouchEvent(): ACTION_CANCEL");
break;
default:
break;
}
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.e(TAG, "onTouchEvent()");
float x = event.getX();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.i(TAG, "onTouchEvent(): ACTION_DOWN");
mFinished = mScroller.isFinished();
if(!mFinished){
return false;
}
break;
case MotionEvent.ACTION_MOVE:
Log.i(TAG, "onTouchEvent(): ACTION_MOVE");
getChildAt(1).scrollTo(-(int)x, 0);
break;
case MotionEvent.ACTION_UP:
Log.i(TAG, "onTouchEvent(): ACTION_UP");
if(!mAllowScroll){
break;
}
float width = getWidth();
// 响应滚动子View的临界值,若觉得响应过于灵敏,可以将只改大些。
// 比如:criticalWidth = width / 3或criticalWidth = width / 2,看情况而定,呵呵。
float criticalWidth = width / 5;
Log.i(TAG, "onTouchEvent(): ACTION_UP x = " + x + "\t criticalWidth = " + criticalWidth);
int scrollX = getChildAt(1).getScrollX();
if ( x < criticalWidth) {
Log.i(TAG, "onTouchEvent(): ACTION_UP 向左滑动");
mPanelInvisible = false;
mScroller.startScroll(scrollX, 0, -scrollX, 0, ANIMATION_DURATION_TIME);
invalidate();
} else if ( x > criticalWidth){
Log.i(TAG, "onTouchEvent(): ACTION_UP 向右滑动");
mPanelInvisible = true;
int toX = (int)(width - Math.abs(scrollX) - mHandlebarWidth);
mScroller.startScroll(scrollX, 0, -toX, 0, ANIMATION_DURATION_TIME);
invalidate();
}
break;
case MotionEvent.ACTION_CANCEL:
Log.i(TAG, "onTouchEvent(): ACTION_CANCEL");
break;
default:
break;
}
return super.onTouchEvent(event);
}
@Override
public void computeScroll() {
// super.computeScroll();
if(mScroller.computeScrollOffset()){
this.getChildAt(1).scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
this.postInvalidate();
}
}
/**
* 向右滑动View,让左侧操作面饭可见
*/
public void slideToRight() {
mFinished = mScroller.isFinished();
if(mFinished && !mPanelInvisible){
mPanelInvisible = true;
float width = getWidth();
int scrollX = getChildAt(1).getScrollX();
int toX = (int)(width - Math.abs(scrollX) - mHandlebarWidth);
mScroller.startScroll(scrollX, 0, -toX, 0, ANIMATION_DURATION_TIME);
invalidate();
}
}
/**
* View滑动事件监听器
* @author android_ls
*/
public interface OnSlideListener {
/**
* 向左滑动子View
*/
public abstract void toLeft();
/**
* 向右滑动子View
*/
public abstract void toRight();
}
}
主应用界面源码:
package com.everyone.android.ui;
import android.os.Bundle;
import android.view.ViewGroup.LayoutParams;
import com.everyone.android.AppBaseActivity;
import com.everyone.android.widget.FreshNewsLayout;
import com.everyone.android.widget.LeftPanelLayout;
import com.everyone.android.widget.ScrollerContainer;
import com.everyone.android.widget.ScrollerContainer.OnSlideListener;
/**
-
功能描述:应用主界面
-
@author android_ls
*/
public class EveryoneActivity extends AppBaseActivity implements OnSlideListener {
/**
* 滚动(滑动)容器
*/
private ScrollerContainer mSlideContainer;
/**
* 左侧面板
*/
private LeftPanelLayout mLeftPanelLayout;
/**
* 新鲜事
*/
private FreshNewsLayout mFreshNewsLayout;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(mSlideContainer);
}
@Override
protected int getLayoutId() {
return 0;
}
@Override
protected void setupView() {
mSlideContainer = new ScrollerContainer(mContext);
mLeftPanelLayout = new LeftPanelLayout(mContext);
mFreshNewsLayout = new FreshNewsLayout(mContext);
mFreshNewsLayout.setOnSlideListener(this);
LayoutParams layoutParams = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
mSlideContainer.addView(mLeftPanelLayout, layoutParams);
mSlideContainer.addView(mFreshNewsLayout, layoutParams);
}
@Override
protected void initialized() {
// TODO Auto-generated method stub
}
@Override
public void toLeft() {
// TODO Auto-generated method stub
}
@Override
public void toRight() {
mSlideContainer.slideToRight();
}
最后
题外话,我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在IT学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多程序员朋友无法获得正确的资料得到学习提升,故此将并将重要的Android进阶资料包括自定义view、性能优化、MVC与MVP与MVVM三大框架的区别、NDK技术、阿里面试题精编汇总、常见源码分析等学习资料。
【Android思维脑图(技能树)】
知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。
【Android进阶学习视频】、【全套Android面试秘籍】
希望我能够用我的力量帮助更多迷茫、困惑的朋友们,帮助大家在IT道路上学习和发展
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在IT学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多程序员朋友无法获得正确的资料得到学习提升,故此将并将重要的Android进阶资料包括自定义view、性能优化、MVC与MVP与MVVM三大框架的区别、NDK技术、阿里面试题精编汇总、常见源码分析等学习资料。
【Android思维脑图(技能树)】
知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。
[外链图片转存中…(img-mL7R2X81-1715012899495)]
【Android进阶学习视频】、【全套Android面试秘籍】
希望我能够用我的力量帮助更多迷茫、困惑的朋友们,帮助大家在IT道路上学习和发展
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!