如何在全屏幕中滚动GridView

时间:2014-12-04 06:51:47

标签: android gridview android-scrollview retrofit robospice

enter image description here

我继续使用GridView中的Show List of Items,如果我滚动GridView,整个屏幕必须Scroll不仅GridView为此我使用了自定义GridView类ExpandableHeightGridView。当Scroll发生时,它以全屏显示GridView。我遇到的问题是我从WebService API调用中获取了值列表,并且我在这个滚动过程中做了一些分页工作,这最初它只显示GridView中的第一个Ten项。如果我们向下滚动网格,它将调用WebService API调用另一个Ten值如果响应包含更多的值。它显示ExpandableHeightGridView呼叫呼叫WebService API中的所有项目列表,即使我们不滚动GridView。如果我使用默认的GridView而不是ExpandableHeightGridView它将适用于10,10分页但滚动仅适用于GridView而不是整个屏幕。我需要task(full screen Scroll,Pagination for 10,10,..etc)执行。

以下是我的代码 的 ExpandableHeightGridView.java

 public class ExpandableHeightGridView extends GridView {

        boolean expanded = true;

        public ExpandableHeightGridView(Context context){
            super(context);
        }

        public ExpandableHeightGridView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }

        public ExpandableHeightGridView(Context context, AttributeSet attrs,
                                        int defStyle) {
            super(context, attrs, defStyle);
        }

        public boolean isExpanded() {
            return expanded;
        }

        public void setExpanded(boolean expanded) {
            this.expanded = expanded;
        }

        @Override
        public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            // HACK! TAKE THAT ANDROID!
            if (isExpanded()) {
                // Calculate entire height by providing a very large height hint.
                // View.MEASURED_SIZE_MASK represents the largest height possible.
                int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK,
                        MeasureSpec.AT_MOST);
                super.onMeasure(widthMeasureSpec, expandSpec);

                ViewGroup.LayoutParams params = getLayoutParams();
                params.height = getMeasuredHeight();
            } else {
                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            }
        }
    }

活动类

    private void loadFeed(boolean keepListViewShown) {       

            final FeedRequest<ItemsFeed, ?> request = ItemFeedRequest(0, getLastPostDate());
            feedState.lastRequestPageAndSortParams = request.getPageAndSortParams();
            getFeedListView().setAdapter(createAdapter(new ArrayList<String>()));
        }




    private FeedRequest<ItemsFeed, ?> ItemFeedRequest(int page, Date lastPostDate) {
            return VisitedItemFeedRequest.builder(this.user.getId())
                    .pageAndOrdering(PageAndSortParams.builder()
                            .limit(10).dateOffset(lastPostDate).page(page).build())
                    .build();
        }

    private ListAdapter createAdapter(List<String> items) {
        PagedAsyncDataLoader<ItemsFeed> pagedDataProvider = new PagedAsyncDataLoader<ItemsFeed>() {
            @Override
            @SuppressWarnings("unchecked")
            public void loadPage(int page, RequestListener<ItemsFeed> requestListener) {

                final FeedRequest request =
                        ItemFeedRequest(page, getLastPostDate());
                feedState.lastRequestPageAndSortParams = request.getPageAndSortParams();

                //use cache only for the first page of data
                long cacheExpirationDelay = page == 0 ? Constants.CacheExpirationDuration.ONE_SECOND :
                        Constants.CacheExpirationDuration.ALWAYS_EXPIRED;

                getRequestController().execute(request, cacheExpirationDelay, requestListener);
            }
        };
        endlessFeedAdapter = new FeedAdapter(createListAdapter(items), pagedDataProvider);

        mergeAdapter = new MergeAdapter();
        mergeAdapter.addAdapter(endlessFeedAdapter);

        return mergeAdapter;
    }

    }
    private final class FeedAdapter extends EndlessFeedAdapter<String,ItemsFeed> {
        int count = 0;
        public FeedAdapter(ArrayAdapter<String> wrapped, PagedAsyncDataLoader<ItemsFeed>
                pagedDataProvider) {
            super(wrapped, pagedDataProvider);
        }

        @Override
        protected List<String> collectItems(ItemsFeed FEED) {
            return FEED.getData();
        }

        @Override
        protected boolean shouldLoadNextPage(ItemsFeed feed) {
            if (feed.getPaging() == null || feed.getPaging().getNext() == null
                    || feed.getPaging().getNext().isEmpty())
                return false;
            return true;

        }

        @Override
        protected void onRequestStarted() {         
                super.onRequestStarted();
                hideErrorLoading();       

        }
        protected void showErrorLoading(String errorMessage) {
            getErrorPanelController().showActionButton(android.R.drawable.ic_menu_rotate,
                    endlessAdapterLoadErrorClickListener)
                    .errorWithDefaultIcon(errorMessage).show();
        }

        private final View.OnClickListener endlessAdapterLoadErrorClickListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                hideErrorLoading();
                if (endlessFeedAdapter.getCurrentPage() <= 1) {
                    reloadData();
                } else {
                    endlessFeedAdapter.restartAppending();
                }
            }
        };
        protected void hideErrorLoading() {
            getErrorPanelController().hide();
        }

        private void reloadData() {
            feedState.clear();
            loadFeed(false);
        }
        @Override
        public void onRequestFailure(Exception spiceException) {
            super.onRequestFailure(spiceException);
            showErrorLoading(getString(R.string.failed_to_load_feed));
        }

        @Override
        public void onRequestSuccess(ItemsFeed feed, boolean cached) {
            super.onRequestSuccess(feed, cached);
            feedState.updatePaging(feed.getPaging());
            if (cached) {
                //ASOC-221 - handle cached result and display message to user that "offline" results were shown
                showErrorLoading(getString(R.string.offline_data_displayed));
            }
        }

        @Override
        protected void onItemsAdded(List<String> items) {
            super.onItemsAdded(items);
            feedState.appendItems(items);
        }

        @Override
        protected void onNoMoreData() {
            if (feedState.getItems() != null && feedState.getItems().size() > 0) {
                //show "No more data" only if current list do not contain any items
                //otherwise it is more like "Feed is empty" or "No data" message
                mergeAdapter.setActive(noMoreDataView, true);
            }
        }
    }

 protected ArrayAdapter<String> createListAdapter(List<String> feed) {

        return (new VisitedItemListAdapter(this, feed));//Adapter class to show List Items in Grid
    }

EndlessFeedAdapter.java

public abstract class EndlessFeedAdapter<TYPE, RESPONSE> extends EndlessAdapter
        implements RequestListener<RESPONSE> {
    private PagedAsyncDataLoader<RESPONSE> pagedAsyncDataLoader;
    private int currentPage = 1;

    private boolean shouldLoadMore = true;

    private volatile boolean requestInProgress = false;

    public EndlessFeedAdapter(ArrayAdapter<TYPE> wrapped, PagedAsyncDataLoader<RESPONSE>
            pagedAsyncDataLoader) {
        super(wrapped);
        super.setRunInBackground(false);
        this.pagedAsyncDataLoader = pagedAsyncDataLoader;
    }

    @Override
    protected boolean cacheInBackground()  {
        if (shouldLoadMore) {
            if (requestInProgress) {
                return true;
            }
            onRequestStarted();
            pagedAsyncDataLoader.loadPage(currentPage, this);
            return true;
        }
        return false;
    }

    protected void onRequestStarted() {
        requestInProgress = true;
    }

    @Override
    public void onRequestFailure(Exception spiceException) {
        requestInProgress = false;
        stopAppending();
    }

    @Override
    public void onRequestSuccess(RESPONSE response, boolean cached) {
        //ASOC-221 - it is handled in overriding classes
        requestInProgress = false;
        ++currentPage;
        List<TYPE> items = collectItems(response);
        if (items == null || items.isEmpty()) {
            stopAppending();
            onNoMoreData();
            return;
        }
        @SuppressWarnings("unchecked") final ArrayAdapter<TYPE> wrappedAdapter =
                ((ArrayAdapter<TYPE>)getWrappedAdapter());
        List<TYPE> newItems = new ArrayList<>(10);
        for (TYPE item : items) {
            if (wrappedAdapter.getPosition(item) == -1) {
                newItems.add(item);
            }
        }

        if (!newItems.isEmpty()) {
            onItemsAdded(newItems);
            wrappedAdapter.addAll(newItems);
        }
        if (!shouldLoadNextPage(response)) {
            stopAppending();
            onNoMoreData();
        }

        onDataReady();
    }

    /**
     * Called when adapter has been detected that feed doesn't have more data to load
     * it happened inside {@link #onRequestSuccess(Object, boolean)}} if response do not contain any data
     * or if call to {@link #shouldLoadNextPage(Object)} returned false
     */
    protected void onNoMoreData() {}

    /**
     * Called when new items have been added to wrapped adapter
     * @param items items
     */
    protected void onItemsAdded(List<TYPE> items) {}

    @Override
    protected void appendCachedData() {
    }

    /**
     *
     * @param response    server response
     * @return items returned in response to server request
     */
    protected abstract List<TYPE> collectItems(RESPONSE response);

    @Override
    public void stopAppending() {
        this.shouldLoadMore = false;
        super.stopAppending();
    }

    @Override
    protected View getPendingView(ViewGroup parent) {
        return LayoutInflater.from(parent.getContext()).inflate(R.layout.pending_row, null);
    }

    @Override
    public void setRunInBackground(boolean runInBackground) {
        throw new UnsupportedOperationException("EndlessFeedAdapter works only " +
                "in runInBackground = false mode");
    }

    /**
     *
     * @param response    server response
     * @return <tt>true</tt> if current response should result in loading of new data page,
     * <tt>false</tt> otherwise
     */
    protected abstract boolean shouldLoadNextPage(RESPONSE response);

    /**
     * Make sure that this endless ListView will start loading new data
     */
    @Override
    public void restartAppending() {
        shouldLoadMore = true;
        onDataReady();
        super.restartAppending();
        cacheInBackground();
    }


    public int getCurrentPage() {
        return currentPage;
    }
}

PagedAsyncDataLoader.java

public interface PagedAsyncDataLoader<RESULT> {
    /**
     * Loads page of data asynchronously passing result in provided request listener
     * @param page page number (first page is represented by 0)
     * @param requestListener    request listener
     */
    void loadPage(int page,RequestListener<RESULT> requestListener);
}

VisitedItemFeedRequest.java

public class VisitedItemFeedRequest extends FeedRequest<ItemsFeed,ItemApi> {

    protected String userId;


    protected VisitedItemFeedRequest(Builder builder) {
        super(builder);
        this.userId = builder.userId;

    }

    @Override
    public ItemsFeed execute(ItemApi itemApi) throws Exception {
        PageAndSortParams pageAndSortParams = getPageAndSortParams();

        ItemsFeed itemFeed =  itemApi.userItemFeed(userId,1,
                1,pageAndSortParams.getPage(),10,    
               pageAndSortParams.getLimit(),true);

        return itemFeed;
    }
    public static Builder builder(String capsuleId){
        return new Builder(capsuleId);
    }


    public static class Builder extends FeedRequest.Builder<VisitedItemFeedRequest> {

        private String userId;


        public Builder(String capsuleId) {
            this.userId = capsuleId;
        }

        @Override
        public VisitedItemFeedRequest build(){
            return new VisitedItemFeedRequest(this);
        }
    }


}

1 个答案:

答案 0 :(得分:2)

您应该使用GridView之类https://stackoverflow.com/a/24617051/754439并将ImageView添加为标题。不建议在AdapterView下嵌套ScrollViewHow can I put a ListView into a ScrollView without it collapsing?