android记事本开发笔记

   一直以来都没时间好好写一个安卓平台的客户端,一是因为自己水平还很有限,二是需要花很多时间来维护这个网站。但自从百度无情的把网站k了之后,我觉得好好的投入android平台上来了。

   我现在想做的是一个记事本程序。

   为了实现这个程序,在刚刚开始学习安卓的时候我找了很多文章,仔细阅读了安卓sdk中的notepad例子程序,这个例子程序确实很适合入门,可以让你很快接触到listview这样的基础控件,安卓中数据库(SQLite)的操作、数据存储--ContentProviderFragmentInstanceState数据保存,以及意图Intent的用法,但是里面的很多处理方式(比如新建一个记事本的逻辑),显得非常混乱,很容易发生bug,毕竟这只是一个学习的demo,让你获得更多的只是比让你获得一个app重要。

   这我的这个网站里面有很多刚刚所提到的相关文章,都是我平时总结的,等我完成这篇文章之后,我会找时间把这些资料搜集在此,方便大家参考。

   在这个记事本中,为了实现记事本左右滑动能翻到上一篇或者下一篇,我们引入了一个自定义的scrollLayout类,scrollLayout类继承自ViewGroup,由三个子view构成,但是能无限循环显示。scrollLayout类的实现借鉴了网上很多ViewGroup自定义左右滑动类的实现,只是增加了无限循环滑动的功能。

   其实实现这一功能在最开始我想到的不是ViewGroup,而是ViewPager,在打算写记事本之前,我最先在豆瓣的阅读器上看到这种左右滑动翻页的效果,后来发现豆瓣就是用ViewPager来实现的。但是ViewPager有个天然的缺陷,就是ViewPager必须给他赋一个子View的个数。如果要实现循环滑动的话,这个个数必须很大,比如int的最大值。最后修改一下ViewPager的一些方法,就能模拟少数几个子View无限循环。这种方式的效果其实还不错。但是一想到这个循环在直观上可能有很大的浪费(事实上有没有浪费不确定),我果断放弃了这种方式。

   scrollLayout类要实现无限循环滑动还是比较难的,其中有几个需要非常仔细的地方,不然滑动起来总是有让人不满意的情况。

   1.computeScroll()方法:

   computeScroll()方法负责在mScroller(一个滚动类成员变量)滚动和手指拖动的时候移动scrollLayout的显示位置。很多人都不明白ViewGroup的显示位置到底代表什么,这里我只说这个显示位置体现在getScrollX这个值中。

if (mScroller.computeScrollOffset()) {
    mTouchX = mScroller.getCurrX();
    Log.i("scroll","scrollling  mTouchX="+mTouchX);
    scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
    postInvalidate();
}

上面的代码表示如果滚动仍在继续,那么之行其中的代码。但是一旦滚动结束,下面这段代码仍将会执行,即使你的手指什么都没做。也就是说computeScroll方法在没有任何操作的情况下,会从mScroller开始的瞬间一直调用到结束的瞬间(包括结束)。

else if (mNextScreen != INVALID_SCREEN) {
            if (mNextScreen == -1) {
                mCurrentScreen = getChildCount() - 1;
                mHander.queryForNewPage(PREVIEOUS, mCurrentScreen);
                scrollTo(mCurrentScreen * getWidth(), getScrollY());
            } else if (mNextScreen == getChildCount()) {
                mCurrentScreen = 0;
                mHander.queryForNewPage(NEXT, mCurrentScreen);
                scrollTo(0, getScrollY());
            } else {
                int temp = mCurrentScreen;
                mCurrentScreen = Math.max(0,
                        Math.min(mNextScreen, getChildCount() - 1));
                if (mNextScreen > temp) {
                    mHander.queryForNewPage(NEXT, mCurrentScreen);
                } else {
                    mHander.queryForNewPage(PREVIEOUS, mCurrentScreen);
                }
            }
            mNextScreen = INVALID_SCREEN;
        }