【问题标题】:ListView load more at scroll beginListView 在滚动开始时加载更多
【发布时间】:2017-06-24 22:08:43
【问题描述】:

我正在尝试实现一些聊天活动。 消息必须从旧消息到最新消息(新消息在底部,旧消息在我的 ListView 顶部),因为我在我的布局中使用android:transcriptMode="alwaysScroll"android:stackFromBottom="true"。 当用户向上滚动时,应该从我的 SQL 数据库中的旧消息更新 ListView。这是一些代码:

 public void onLoadFinished(Loader loader, Object data) {
        final Cursor cursor = (Cursor)data;

        if(cursor.getCount() > API_REQUEST_COUNT) {
            this.lsView.setStackFromBottom(false);
        }

        this.mAdapter.changeCursor(cursor);

        if(this.mAdapter.getCount() > 0) {
           this.isLoading = false;                
            }, 500);
        }
    }

这就是我实现加载更多功能的方式:

 this.lsView.setOnScrollListener(new AbsListView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {

        }

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            int currentItemPosition = totalItemCount - firstVisibleItem;

            // TODO without refreshing cache :-(
            if(totalItemCount == 0 && !isLoading) {
                isLoading = true;

                if(getLoaderManager().getLoader(loaderId) != null) {
                    getLoaderManager().restartLoader(loaderId, getArguments(), ConversationFragment.this);
                } else {
                    getLoaderManager().initLoader(loaderId, getArguments(), ConversationFragment.this);
                }

                // TODO pagination
                ApiManager.getInstance().getDialog(dialogId, pageNum);
            }

            if(!isLoading && totalItemCount != 0 && currentItemPosition == (API_REQUEST_COUNT * pageNum) - 1) {
                pageNum++;

                ApiManager.getInstance().getDialog(dialogId, pageNum);
            }
        }
    });

问题是,当我更新我的适配器ListView 时向上滚动,但我希望他冻结在当前位置。 有人可以帮忙吗?

【问题讨论】:

    标签: android listview android-listview android-cursor


    【解决方案1】:

    将新数据加载到 Adpater 后应该可以正常工作

     this.lsView.setSelection(this.mAdapter.getCount() - 1);
    

    为此试试这个,这将保留滚动位置

    if(listView.getAdapter()==null)
       listView.setAdapter(this.mAdapter);
    else{
       this.myAdapter.updateData(myNewData); //update your adapter's data
       this.myAdapter.notifyDatasetChanged();
    }
    

    【讨论】:

    • 是的,更新后这条线应该滚动到我的列表视图底部。但我想在更新后留在当前位置
    【解决方案2】:

    使用这个,

    listview.setOnScrollListener(new OnScrollListener() {
    
                @Override
                public void onScrollStateChanged(AbsListView view, int scrollState1) {
                    // TODO Auto-generated method stub
                    scrollState = scrollState1;
                    isScrollCompleted();
    
                }
    
                @Override
                public void onScroll(AbsListView view, int firstVisibleItem1,
                        int visibleItemCount1, int totalItemCount1) {
                    // TODO Auto-generated method stub
                     firstVisibleItem = firstVisibleItem1;
                        visibleItemCount = visibleItemCount1;
                        totalItemCount=totalItemCount1;
    
                }
            });
    

    这是 isScrollCompleted()。

    private void isScrollCompleted() {
    
            if(arrayList.size()>20)
            {
                Log.v("firstVisible", firstVisibleItem+"");
                Log.v("visibli", "item count"+visibleItemCount);
                Log.v("ScrollState", "scrollState"+scrollState);
                Log.v("total", totalItemCount+"");
                int lastInScreen=firstVisibleItem+visibleItemCount;
                if (lastInScreen == totalItemCount && scrollState == 0) {
                    start=start+20;
                    //get new twenty recornd in list and notify adapter
                    cAdapter.notifyDataSetChanged();
                }
            }
            else
            {
                Log.v("arrayList", "size="+arrayList.size());
            }
    
        }
    

    【讨论】:

      【解决方案3】:

      存储更多数据时的firstVisible位置项索引 加载(到达 ListView 顶部时)。数据加载时 成功然后将此值位置设置为第一个选定项 使用:-

      setSelection(index);
      

      如果它不能解决您的问题,请告诉我?

      【讨论】:

        【解决方案4】:

        我遇到了同样的问题。 对我有用的解决方案是在添加新项目以更改 TranscriptMode 之前:

        listView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_NORMAL);
        

        添加后:

        //inserted= number of inserted items
        listView.setSelection(inserted+firstVisibleItem);
        

        在 onScrollStateChanged 和 onScroll 我把 TranscriptMode 放回原来的样子:

        if (inserted>0) {
        listView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
        inserted = 0;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-12-05
          • 1970-01-01
          • 2013-08-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多