2017-06-26 14 views
2

これは以前のquestionのフォローアップです。LinearSnapHelperはRecyclerViewのエッジ項目にスナップしません

私のアプリでは、水平のRecyclerViewを中央のアイテムに自動的にスナップするようにしています。そうするために、私はLinearSnapHelperを添付しました。 RecyclerViewが最初に読み込まれるとき

public class OffsetItemDecoration extends RecyclerView.ItemDecoration { 

    private Context ctx; 

    public OffsetItemDecoration(Context ctx){ 
     this.ctx = ctx; 
    } 

    @Override 
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { 
     super.getItemOffsets(outRect, view, parent, state); 
     int nCols = ActivityUtils.getNumCols(ctx); 
     int colWidth = (int)(getScreenWidth()/(float)(nCols)); 

     if(parent.getChildAdapterPosition(view) == 0){ 
      int offset = Math.round(getScreenWidth()/2f - colWidth/2f); 
      setupOutRect(outRect, offset, true); 
     } 

     else if (parent.getChildAdapterPosition(view) == state.getItemCount()-1){ 
      int offset = Math.round(getScreenWidth()/2f - colWidth/2f); 
      setupOutRect(outRect, offset, false); 
     } 
    } 

    private void setupOutRect(Rect rect, int offset, boolean start){ 
     if(start) rect.left = offset; 
     else rect.right = offset; 
    } 

    private int getScreenWidth(){ 
     WindowManager wm = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE); 
     Display display = wm.getDefaultDisplay(); 
     Point size = new Point(); 
     display.getSize(size); 
     return size.x; 
    } 
} 

問題は、最初の項目が画面の中央に配置されていること:私も最初/最後の要素にいくつかの左/右のパディングを追加した項目の装飾を作成しましたまた選択されていますが、水平方向にスクロールして最初の項目に戻ると、選択できる最も左の項目は2番目の項目(位置1)です。最後のアイテムについても同じことが起こります。スナップできる最後のアイテムは最後から2番目です。 (state.getItemCount() - 2)。

新しいSnapHelperを実装する必要がありますか、何か間違っていますか?

+0

これは、listViewの長さのためです。最初と最後の項目には到達できません。私は同様の問題を抱えており、到達不可能な領域を補うためにデフォルトの不可視の項目を追加しました。しかし、このためには、画面サイズごとに計算を行う必要があります。しかし、これはちょっとしたハックな解決策です。もっと良い解決策があるのか​​もしれません。(ほしいですが) – Opiatefuchs

+0

@Opiatefuchs理論的には、私の「ItemDecoration」によって追加された人為的なオフセットが、このようなダミーアイテムを作成できないようにしてください。 – Vektor88

+0

はい....理論的には....私はオフセットでどんな成功もしていませんでした。しかし、これは私の必要性のために作られていませんでした。私の目標は、アイテムを左から右に(そしてその逆に)画面の端にスライドさせるhorizo​​ntal recyclerViewを持つことでした。オフセットはエッジをカットし、アイテムは画面の最後までスクロールしません。その問題のために、別の解決策が見つかるまで、私は不可視のビューをいくつか追加することにしました。 – Opiatefuchs

答えて

3

RecyclerViewには約ItemDecorationという独自のルールがあります。彼はそれらをアイテムそのものの一部と考えています。あなたはdecoration(たとえそれがちょうどpaddingであっても)あなたのmy_item.xmlの一部であると考えることができます。

LinearSnapHelperビューの中心を決定するためにLayoutManager.getDecoratedMeasuredWidth()ような方法を使用します。そしてそれは問題がどこから起こったかである。最初のアイテムは思っていたものよりもはるかに大きいので、最初のビューの中心点は実際には(padding + view.getWidth())/2です。 2番目のビューの中心よりもはるかに離れています。これは通常のview.getX() + view.getWidth()/2です。

関連する問題