2017-07-18 337 views
3

我这个问题挣扎了很长一段时间,我试图用recyclerview来代替我的ListView和我的列表视图看起来像这样: -为什么findFirstVisibleItemPosition不能按预期工作?

<ListView 
      android:id="@+id/browser_sub_list_view" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_alignParentBottom="true" 
      android:layout_alignParentTop="true" 
      android:clipToPadding="false" 
      android:drawSelectorOnTop="true" 
      android:paddingTop="340dp"/> 

现在,当我打电话

view.getFirstVisiblePosition(); 

在此列表视图我返回第一个项目的位置为零,因为我给了顶部填充,所以它将只返回0,直到第一个项目超出屏幕界限。

但是,当我试图用recyclerview做同样的事情,即使第一个recyclerview项目是可见的,它仍然给我不同的第一个可见项目的值,这是因为recyclerview认为toppadding作为屏幕绑定现在我没有任何线索如何解决这个问题。 请帮忙。

这是我的代码。

MainActivity.Java

public class MainActivity extends AppCompatActivity { 
    private RecyclerView mRecyclerView; 
    private TheAdapter adapter; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview); 
     mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); 

     ArrayList<String> items = new ArrayList<>(); 
     for (int i = 0; i < 300; i++) { 
      items.add("This is item:-" + i); 
     } 

     adapter = new TheAdapter(items); 
     mRecyclerView.setAdapter(adapter); 
     mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { 
      @Override 
      public void onScrollStateChanged(RecyclerView recyclerView, int newState) { 
       super.onScrollStateChanged(recyclerView, newState); 
      } 

      @Override 
      public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
       LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); 
       Log.d("DISTANCE", "" + linearLayoutManager.findFirstVisibleItemPosition()); 
      } 
     }); 
    } 
} 

activity_main.xml中

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       xmlns:tools="http://schemas.android.com/tools" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       tools:context=".MainActivity"> 

    <android.support.v7.widget.RecyclerView 
     android:id="@+id/recyclerview" 
     android:layout_width="match_parent" 
     android:clipToPadding="false" 
     android:paddingTop="340dp" 
     android:layout_height="match_parent" 
     /> 

</RelativeLayout> 

这是我的适配器类

class TheAdapter extends RecyclerView.Adapter<TheAdapter.ItemHolder> { 

    public TheAdapter(ArrayList<String> data) { 
     mData = data; 
    } 

    private ArrayList<String> mData; 

    @Override 
    public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false); 

     return new ItemHolder(view); 
    } 

    @Override 
    public void onBindViewHolder(ItemHolder holder, int position) { 
     holder.mTextView.setText(mData.get(position)); 
    } 

    @Override 
    public int getItemCount() { 

     return mData == null ? 0 : mData.size(); 
    } 

    public class ItemHolder extends RecyclerView.ViewHolder { 
     private TextView mTextView; 

     public ItemHolder(View itemView) { 
      super(itemView); 
      mTextView = (TextView) itemView.findViewById(R.id.textTitle); 
     } 
    } 
} 
+0

这完全是疯狂的行为是违反直觉的。你有没有提到这是正确的行为?它看起来像'android:clipToPadding =“false”'不符合'findFirstVisibleItemPosition()'。 – Cheticamp

+0

对不起,我没有任何引用,但技术上这应该是这样的情况下,如果第一个项目仍然可见,那么为什么要跳转到第二个android:clipToPadding =“false”在listview中很荣幸。可能b我应该发布示例项目。 – George

回答

2

,直到找到一个更好的答案,你可以试试下面的代码。 int pos是由findFirstVisibleItemPosition()报告的位置。此方法将返回RecyclerView中最顶端的可见位置。

public int findRealFirstVisibleItemPosition(int pos) { 
    View view; 
    final LinearLayoutManager linearLayoutManager = 
      (LinearLayoutManager) mRecyclerView.getLayoutManager(); 

    while (pos > 0) { 
     view = linearLayoutManager.findViewByPosition(pos - 1); 
     if (view == null) { 
      break; 
     } 
     pos = pos - 1; 
    } 

    return pos; 
} 

我似乎记得大填充导致这些类型的滚动视图问题。

+0

伟大的完美答案,如果接受,但我不得不知道如何处理它,如果它是gridlayoutmanager与两列所有,因为它是以这样的顺序返回我像0,2,4这显然是真的所以我分为位置/ 2但它几乎完美,如果你有任何与gridlayoutmanger的解决方案也请更新。 – George

相关问题