Recyclerview视图不能与setNestedScrollingEnabled一起使用,它也永远不会回收任何视图

时间:2017-08-03 07:53:43

标签: android android-recyclerview android-nestedscrollview onscrolllistener

我面临两个问题:

  1. 滚动侦听器不起作用
  2. RecyclerView附加到NestedScrollView时, <android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/nestedScroll" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#ffffff" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <FrameLayout android:layout_width="match_parent" android:layout_height="240dp" android:layout_alignParentTop="true"/> </LinearLayout> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/youtube_layout" android:visibility="visible"/> </LinearLayout> </android.support.v4.widget.NestedScrollView> 永远不会回收任何视图。它就像ScrollView中的线性布局。它使用大量内存并造成滞后。
  3. 我在回收者视图的顶部附加了一个youtube播放器片段,因为我无法在回收器视图中放置片段。在我的代码中,您可以看到有一个框架布局。

    我的布局如下:

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        Log.i(TAG, "onScrolled: ");
        // bail out if scrolling upward or already loading data
        if (dy < 0 || dataLoading.isDataLoading()) return;
    
        final int visibleItemCount = recyclerView.getChildCount();
        final int totalItemCount = layoutManager.getItemCount();
        final int firstVisibleItem = layoutManager.findFirstVisibleItemPosition();
    
        if ((totalItemCount - visibleItemCount) <= (firstVisibleItem )) {
            onLoadMore();
        }
    
    
    }
    

    我想使用滚动侦听器来加载更多项目 所以我尝试了以下内容:

    layoutManager.findFirstVisibleItemPosition()==0

    onScrolled never called twice所以它不起作用,而且自我设定以来onBindView更多 recyclerview.setNestedScrollingEnabled(假)

    所以我尝试了 public void onBindViewHolder(RecyclerView.ViewHolder customViewHolder, int i) { Log.w("d","inside bind view"); if(i>=getItemCount()-1 && !datamanager.isDataLoading()){ datamanager.loadmoreData(); } 这样的

       echo "Declare @montant int =$mobile ,@categorie varchar(12) = 'mobile',@nom varchar(50) = '%'+$filename+'%',@temps varchar(12) = $Tmobile
    
     Print @montant
     Print @categorie
     Print @nom
     Print @temps
    
     EXEC Test @montant, @categorie, @nom, @temps
     go
     " > tempfile
    

    但是在我开始滚动之前,recylerview会立即绑定所有视图,因此这种方法也不起作用。

2 个答案:

答案 0 :(得分:11)

The recycler view never recycle any views when its attached to nested scroll view,its acts as set on linear layout inside scroll view.its create a huge memory and lags the screen.

Exactly. You can't put a RecyclerView inside another scrolling view.

It will not work, because the wrapping view needs to know the total height of the RecyclerView and the RecyclerView can only know its total height by measuring and layouting all of its items.

How to fix this?

Don't put a RecyclerView inside another scrolling view.

If you need a header or footer you will have to add it to the RecyclerView and let the RecyclerView take care of displaying it. Get rid of your ScrollView and move your header inside of the RecyclerView.

Technically it is possible to also load fragments inside a RecyclerView, but I have to admit getting this to work properly is a bit tricky.

There are also a lot of libraries that facilitate the process, my personal favorite being Epoxy made by AirBnb, but there's also Groupie, and a lot of others.

答案 1 :(得分:-1)

以下是我实现它的方法,我尝试将代码剥离到最小的

public class DataAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private static final int VIEW_TYPE_LOADING = 0;
    private static final int VIEW_TYPE_ITEM = 1;

    public boolean isLoading;
    private int visibleThreshold = 5;
    private int lastVisibleItem, totalItemCount;

    public ArrayList<Data> datas;

    private OnLoadMoreListener mOnLoadMoreListener;

    public DataAdapter(RecyclerView mRecyclerView, ArrayList<Data> datas) {
        this.datas = datas;

        final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                totalItemCount = linearLayoutManager.getItemCount();
                lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();

                if (!isLoading && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
                    if (mOnLoadMoreListener != null) {
                        DataAdapter.this.datas.remove(null);
                        mOnLoadMoreListener.onLoadMore();
                    }
                }
            }
        });
    }
    public static class DataObjectHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        //your views

        public DataObjectHolder(View itemView) {
            super(itemView);
            //initialize your views
        }

        @Override
        public void onClick(View v) {
            if (onItemClickListener != null) onItemClickListener.onItemClick(getAdapterPosition(), v);
        }
    }

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    @Override
    public int getItemViewType(int position) {
        return datas.get(position) == null ? VIEW_TYPE_LOADING : VIEW_TYPE_ITEM;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == VIEW_TYPE_ITEM) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_data, parent, false);
            DataObjectHolder dataObjectHolder = new DataObjectHolder(view);
            return dataObjectHolder;
        } else if (viewType == VIEW_TYPE_LOADING) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_loading_item, parent, false);
            return new LoadingViewHolder(view);
        }
        return null;
    }

    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder hldr, final int position) {
        if (hldr instanceof DataObjectHolder) {
            final Data data = datas.get(position);
            final DataObjectHolder holder = (DataObjectHolder) hldr;

            //bind your views


        } else if (hldr instanceof LoadingViewHolder) {
            LoadingViewHolder loadingViewHolder = (LoadingViewHolder) hldr;

            if (isLoading) {
                loadingViewHolder.progressBar.setVisibility(View.VISIBLE);
                loadingViewHolder.progressBar.setIndeterminate(true);

                loadingViewHolder.tv_load_more.setVisibility(View.GONE);
                loadingViewHolder.tv_load_more.setOnClickListener(null);
            } else {
                loadingViewHolder.progressBar.setVisibility(View.GONE);

                loadingViewHolder.tv_load_more.setVisibility(View.VISIBLE);
                loadingViewHolder.tv_load_more.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        if (mOnLoadMoreListener != null) {
                            datas.remove(null);
                            mOnLoadMoreListener.onLoadMore();
                        }
                    }
                });
            }
        }
    }

    @Override
    public int getItemCount() {
        return datas.size();
    }

    public void setOnLoadMoreListener(OnLoadMoreListener mOnLoadMoreListener) {
        this.mOnLoadMoreListener = mOnLoadMoreListener;
    }

}

loadingViewHolder的XML如下所示,你基本上只是为了获得持有者而膨胀

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

    <ProgressBar
        android:id="@+id/progressBar1"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_centerInParent="true"
        android:layout_gravity="center"
        android:indeterminate="true"/>

    <TextView
        android:id="@+id/tv_load_more"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:text="Tap to load more"
        android:textSize="14sp"/>

</RelativeLayout>

希望你能找到这个有用的