Android编程权威指南第三版 第25章

一、分页显示

1.问题

getRecent方法默认返回一页包含100个结果的数据。不过,该方法还有个叫作page的参数, 可以用它返回第二页、第三页等更多页数据。 请实现一个RecyclerView.OnScrollListener方法,只要用户看完当前页,就使用下页返 回结果替换当前页。想更有挑战的话,可以尝试把后续结果页添加到当前结果页后面。

2.提示

onScrollListener 有两个可以重写的方法,一个是 onScrollStateChanged(),还有一个是 onScrolled,对我们这个需求来说,显然 onScrollStateChanged 比较合适,ScrollState 也有三种:

SCROLL_STATE_IDLE: 视图没有被拖动,处于静止
SCROLL_STATE_DRAGGING: 视图正在拖动中
SCROLL_STATE_SETTLING: 视图在惯性滚动

3.解决办法

3.1.实现RecyclerView.OnScrollListener方法

    private RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
            //获取LayoutManager
            GridLayoutManager layoutManager = (GridLayoutManager)recyclerView.getLayoutManager();
            //最后显示位置
            int mLastPosition = layoutManager.findLastCompletelyVisibleItemPosition();
            if (mPhotoAdapter == null) {
                return;
            }
            if (newState == RecyclerView.SCROLL_STATE_IDLE && mLastPosition >= mPhotoAdapter.getItemCount() -1){
                if (mFetchItemsTask.getStatus() == AsyncTask.Status.FINISHED){
                    mNextPage++;
                    if (mNextPage <= MAX_PAGES){
                        Toast.makeText(getActivity(),"waiting to loading......",Toast.LENGTH_SHORT).show();
                        mFetchItemsTask = new FetchItemsTask();
                        mFetchItemsTask.execute(mNextPage);
                    }else {
                        Toast.makeText(getActivity(),"This is the end!",Toast.LENGTH_SHORT).show();
                    }
                }
            }
        }
    };

 

3.2.添加数据并展示

在 Adapter 中加入一个 addData 方法,将新的数据加入到数据集中,然后使用 notifyDataSetChanged 方法更新视图。

public void addData(List mItem) {
    mGalleryItems.addAll(mItem);
    notifyDataSetChanged();
}

然后修改setAdapter方法

    private void setupAdapter() {
        if (isAdded()){
            if (mNextPage == 1){
                mPhotoAdapter = new PhotoAdapter(mItem);
                mPhotoRecyclerView.setAdapter(mPhotoAdapter);
                mPhotoRecyclerView.addOnScrollListener(onScrollListener);
            }else {
                mPhotoAdapter.addData(mItem);
            }
        }
    }

二、动态调整网格列 

1.问题

当前,显示图片标题的网格固定有3列。编写代码动态调整网格列数,实现在横屏或大屏幕 设备上显示更多列标题。 

2.提示

实现这个目标有个简单方法:分别为不同的设备配置或屏幕尺寸提供整数修饰资源。这实际和第17章中为不同尺寸屏幕提供不同布局的方式差不多。整数修饰资源应放置在res/values目录 中。具体实施细节可参阅Android开发者文档。 提供整数修饰资源的方式不太好确定网格列细分粒度(只能凭经验预先定义列数)。下面再 介绍一个颇具挑战的方法:在fragment的视图创建时就计算并设置好网格列数。显然,这种方式 更加灵活实用。基于RecyclerView的当前宽度和预定义网格列宽,就可以计算出列数。 实施前还有个问题要解决:你不能在onCreateView()方法中计算网格列数,因为这个时候 RecyclerView还没有改变。不过,可以实现ViewTreeObserver.OnGlobalLayoutListener监 听器方法和计算列数的onGlobalLayout()方法,然后使用addOnGlobalLayoutListener()把 监听器添加给RecyclerView视图。 

3.解决办法

实现OnGlobalLayoutListener

mPhotoRecyclerView.getViewTreeObserver()
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        // 计算列数,以 1080p 屏幕显示3列为基准
        int columns = mPhotoRecyclerView.getWidth() / 350;
        // 重新设置 LayoutManager、Adapter 和 Listener
        mPhotoRecyclerView.setLayoutManager(new GridLayoutManager(getActivity(), columns));
        mPhotoRecyclerView.setAdapter(mPhotoAdapter);
        mPhotoRecyclerView.addOnScrollListener(onButtomListener);
        // 滚动到之前看到的位置
        mPhotoRecyclerView.getLayoutManager().scrollToPosition(mLastPosition);
        //将 GlobalLayoutListener 去掉以避免多次触发
        mPhotoRecyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
    }
});

 

你可能感兴趣的:(Android编程权威指南第三版 第25章)