小试 Material Design:一大波养眼妹纸

458 查看

嗯……就是偶然看到了一个网站,于是经得站长同意后,决定写一个~~极致单手操作体验的~~ App 练练~~手~~。

咳,这里才是重点

主要用了这些玩意:

RecyclerView 网格布局

关于 RecyclerView 的用法不重复了,可以戳我之前写过的一片博客。网格布局(Grid Layout)和线性布局(Linear Layout)大同小异,只是把 Layout Manager 指定为 GridLayoutManager,并指定要多少列(span)而已,看源代码吧

GalleryAdapter adapter = new GalleryAdapter(this, this);

GridLayoutManager layoutManager = new GridLayoutManager(this, 3);

RecyclerView albums = (RecyclerView) findViewById(R.id.albums);
albums.setHasFixedSize(true);
albums.setLayoutManager(layoutManager);
albums.setAdapter(adapter);

向上滚动隐藏 Action Bar

我知道你们想要这个的。

祭出神器:ksoichiro/Android-ObservableScrollView

compile('com.github.ksoichiro:android-observablescrollview:1.2.0') {
    // 显然我们希望用我们自己项目里引用的 Support Library
    // 所以把它引用的这个依赖排除掉吧
    exclude group: 'com.android.support', module: 'recyclerview-v7'
}

这位大神呢,把 ScrollView ListView WebView RecyclerView 等等一大堆可滚动控件都做了二次开发,把触摸事件做了处理。

public class GalleryActivity extends ActionBarActivity implements
        ObservableScrollViewCallbacks {

    private ObservableRecyclerView albums;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        /* ... */
        albums = (ObservableRecyclerView) findViewById(R.id.albums);
        albums.setScrollViewCallbacks(this);
        /* ... */
    }

    @Override
    public void onUpOrCancelMotionEvent(ScrollState scrollState) {
        ActionBar actionBar = getSupportActionBar();
        if (scrollState == ScrollState.UP) {
            if (actionBar.isShowing()) {
                actionBar.hide();
            }
        } else if (scrollState == ScrollState.DOWN) {
            if (!actionBar.isShowing()) {
                actionBar.show();
            }
        }
    }

}

编译,运行。咦?发现问题了没?对了,ActionBar 隐藏的时候带着整个 RecyclerView 一起向上滑了。

以前用 ListView 的做法是 addHeaderView 在顶部加一个和 ActionBar 等高的占位 View 对不?

RecyclerView 加头

<?xml version="1.0" encoding="utf-8"?>
<View xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize" />

额,你说 RecyclerView 哪来的 addHeaderView?嗯,为了避免我懒得码太多字的尴尬,我已经封装好一个 HeaderListRecyclerAdapter 了。这个继承自我写的 ListRecyclerAdapter,用于将 List<E> 直接绑定到一个 RecyclerView.Adapter 上。同一个项目里自己找吧……

好了,现在我们稍微迂回地成功地在 RecyclerView 最开头放了一个和 ActionBar 同高的占~~坑~~位 View。等下,我们是网格布局耶……

网格布局控制

GridLayoutManager 提供了一个 setSpanSizeLookup() 的方法。可以让你传入一个继承自 GridLayoutManager.SpanSizeLookup 的类,在里面你可以决定每个 position 上的项应该跨越多少列。既然是头部,那么就应该和 span size 一致吧:HeaderSpanSizeLookup

public class HeaderSpanSizeLookup extends GridLayoutManager.SpanSizeLookup {

    private final GridLayoutManager layoutManager;

    public HeaderSpanSizeLookup(GridLayoutManager layoutManager) {
        this.layoutManager = layoutManager;
    }

    @Override
    public int getSpanSize(int position) {
        return position == 0 ? layoutManager.getSpanCount() : 1;
    }

}

好像我又编不下去了……