2017-05-22 5 views
1

これは私の最初のスタックオーバーフローに関する質問です。私は最後の数時間でスタックオーバーフローでこの問題の解決策を見つけようとしていましたが、何も見つかりませんでした。リサイクルスペースItemDecorationはスクロール中も増加し続ける

私はここに作成していますアプリ(または比活性)は、非常にシンプルで、基本的TextViewのとRecyclerView、のようなもの含む垂直リサイクル:

垂直RecyclerView

---のTextView(タイトル)

---水平RecyclerView(カードビュー)

---のTextView(タイトル)

---ホリゾント垂直のアルRecyclerView(カードビュー)

...(もっとここに)

---のTextView(タイトル)

---水平RecyclerView(カードビュー)

(エンドRecyclerView)

垂直リサイクラーをスクロール(上下)すると、最初と最後の2つのRecyclerViewのスペースアイテムの装飾(以下を参照)が増加し続けます。私は、問題がどこにあるかと私の推測を持っていますが、それを修正する方法がわかりません。

(非常に標準である)水平リサイクラーアダプタ

public class HorizontalRecyclerViewAdapter extends RecyclerView.Adapter<HorizontalRecyclerViewAdapter.ViewHolder> { 
private ArrayList<String> mDataset; 
private Context mContext; 

// Provide a reference to the views for each data item 
// Complex data items may need more than one view per item, and 
// you provide access to all the views for a data item in a view holder 
public class ViewHolder extends RecyclerView.ViewHolder { 
    // each data item is just a string in this case 
    public TextView txtViewTitle; 
    public ImageView imgViewIcon; 

    public ViewHolder(View itemLayoutView) { 
     super(itemLayoutView); 
     txtViewTitle = (TextView) itemLayoutView.findViewById(R.id.text_view); 
     imgViewIcon = (ImageView) itemLayoutView.findViewById(R.id.image_view); 
    } 
} 

// Provide a suitable constructor (depends on the kind of mDataset) 
public HorizontalRecyclerViewAdapter(Context myContext, ArrayList myDataset) { 
    this.mContext = myContext; 
    this.mDataset = myDataset; 
} 

// Create new views (invoked by the layout manager) 
@Override 
public HorizontalRecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, 
                    int viewType) { 
    // create a new view 
    View v = LayoutInflater.from(parent.getContext()) 
      .inflate(R.layout.view_image, parent, false); 
    // Goes here: set the view's size, margins, paddings and layout parameters 

    ViewHolder viewHolder = new ViewHolder(v); 
    return viewHolder; 
} 

// Replace the contents of a view (invoked by the layout manager) 
@Override 
public void onBindViewHolder(ViewHolder holder, int position) { 
    // - get element from your mDataset at this position 
    // - replace the contents of the view with that element 

    String mDrawableName = mDataset.get(position); 
    int resID = mContext.getResources().getIdentifier(mDrawableName , "drawable", mContext.getPackageName()); 
    holder.imgViewIcon.setImageResource(resID); 
} 

// Return the size of your mDataset (invoked by the layout manager) 
@Override 
public int getItemCount() { 
    return mDataset.size(); 
} 

スペース項目デコレーション

class HorizantalSpaceItemDecoration extends RecyclerView.ItemDecoration { 

private final int mHorizantalSpaceWidth; 

public HorizantalSpaceItemDecoration(int horizantalItemSpace) { 
    mHorizantalSpaceWidth = horizantalItemSpace; 
} 

@Override 
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, 
          RecyclerView.State state) { 
    outRect.right = mHorizantalSpaceWidth; 
} 

垂直リサイクラーアダプタ:各水平リサイクル業者に

public class VerticalRecyclerViewAdapter extends RecyclerView.Adapter<VerticalRecyclerViewAdapter.ViewHolder> { 

private ArrayList<String> mHeaderList; 
private ArrayList<String> mSportList; 
private ArrayList<Boolean> mSpaceItemDecorationFlagList; 
private Context context; 

public static final int HORIZANTAL_ITEM_SPACE = 30; 

// Provide a reference to the views for each data item 
// Complex data items may need more than one view per item, and 
// you provide access to all the views for a data item in a view holder 
public class ViewHolder extends RecyclerView.ViewHolder { 
    // each data item is just a string in this case 
    public TextView textView; 
    public CardView cardView; 
    public RecyclerView recyclerView; 

    public ViewHolder(View itemLayoutView) { 
     super(itemLayoutView); 
     cardView = (CardView) itemLayoutView.findViewById(R.id.card_view); 
     textView = (TextView) itemLayoutView.findViewById(R.id.text_view); 
     recyclerView = (RecyclerView) itemLayoutView.findViewById(R.id.recycler_view); 
    } 
} 

// Provide a suitable constructor (depends on the kind of mHeaderList) 
public VerticalRecyclerViewAdapter(Context context) { 
    Resources res = context.getResources(); 
    String[] headers = res.getStringArray(R.array.header_home); 
    mHeaderList = new ArrayList<String>(Arrays.asList(headers)); 
    String[] sports = res.getStringArray(R.array.sports); 
    mSportList = new ArrayList<String>(Arrays.asList(sports)); 
    mSpaceItemDecorationFlagList = new ArrayList<Boolean>(); 
    for(int i = 0; i < mHeaderList.size(); i++){ 
     mSpaceItemDecorationFlagList.add(false); 
    } 
    this.context = context; 
} 

@Override 
public int getItemViewType(int position) { 
    // Just as an example, return 0 or 2 depending on position 
    // Note that unlike in ListView adapters, types don't have to be contiguous 
    return position % 2 * 2; 
} 

// Create new views (invoked by the layout manager) 
@Override 
public VerticalRecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, 
                   int viewType) { 
    // Create a new view depends on view type 
    // 0: Text View (Header) 
    // 1: Recycler View (Category Explorer) 
    View newView; 

    if(viewType == 0) { 
     newView = LayoutInflater.from(parent.getContext()) 
       .inflate(R.layout.view_text, parent, false); 
    }else{ 
     newView = LayoutInflater.from(parent.getContext()) 
       .inflate(R.layout.view_recycler, parent, false); 
    } 
    // Goes here: set the view's size, margins, paddings and layout parameters 

    ViewHolder viewHolder = new ViewHolder(newView); 
    return viewHolder; 
} 

// Replace the contents of a view (invoked by the layout manager) 
@Override 
public void onBindViewHolder(ViewHolder holder, int position) { 

    // - get element from your mHeaderList at this position 
    // - replace the contents of the view with that element 
    if(position % 2 == 0) 
    { 
     String header = mHeaderList.get(position); 
     holder.textView.setText(header); 
    }else{ 
     // ?????????????? 
     // Problem might be holder.recyclerView not reset properly? 

     RecyclerView.LayoutManager popularLayoutManager= new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false); 
     RecyclerView.Adapter adapter = new HorizontalRecyclerViewAdapter(context, mSportList); 
     holder.recyclerView.setLayoutManager(popularLayoutManager); 
     holder.recyclerView.setAdapter(adapter); 

     //add Space ItemDecoration 
     holder.recyclerView.addItemDecoration(new HorizantalSpaceItemDecoration(HORIZANTAL_ITEM_SPACE)); 
     holder.recyclerView.setHasFixedSize(true); 

    } 
} 

// Return the size of your mHeaderList (invoked by the layout manager) 
@Override 
public int getItemCount() { 
    return mHeaderList.size(); 
} 

、私がしようとしています各イメージ/アイテムの間に30 dpのスペースを追加しますが、スクロール中は最初のhori最後の2つの水平なリサイクル・ビューが増加し続けた。

私の推測はonBindViewHolder()で、私の所有者のリサイクラビューは正しくリセットされず、rect.rightは新しい値(old + 30)に更新され続けます。 。しかしこれは純粋に私の推測です。他に誰かを喜ばせることができますか

ありがとうございます。

+0

を、どのようにホルダーをしようとなります別の要素、おそらく別のitemDecorationをバインドします。あなたのonBindViewHolder()メソッドの中に別の条件が必要かどうかを確認してください。 –

答えて

1

ここでの問題は、のデータがビュー所有者にバインドされるたびに、アイテムデコレータがに追加されることです。以前に追加されたものは決して削除されません。

これを防ぐためにチェックを行うか、既存のものを削除することができます。しかし、デコレータを宣言して追加するのは、ビューホルダを作成するときだけです。現在、あなたはonBindViewHolder方法でアイテムの装飾を追加する

  • :クラスVerticalRecyclerViewAdapter

    :だからこれを解決する

    。これは、ホルダーが再レンダリングされるたびに呼び出されます(スクロールするときに起こります)ので、ここから削除する必要があります。

  • 次に、onCreateViewHolderメソッドに移動し、そこのビューホルダーに装飾を追加します。

  • viewType == 1が状況にあるかどうかを確認する必要があります。そうでない場合は、NullPointerが発生します。

だから、次のようにあなたの結果onCreateViewHolder方法は見ることができる:あなたが最後の項目に到達すると、あなたがitemdecoratorを追加し、同時にスクロールさ

// Create new views (invoked by the layout manager) 
@Override 
public VerticalRecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, 
                   int viewType) { 
    // Create a new view depends on view type 
    // 0: Text View (Header) 
    // 1: Recycler View (Category Explorer) 
    View newView; 

    if (viewType == 0) { 
     newView = LayoutInflater.from(parent.getContext()) 
       .inflate(R.layout.view_text, parent, false); 
    } else { 
     newView = LayoutInflater.from(parent.getContext()) 
       .inflate(R.layout.view_recycler, parent, false); 
    } 
    // Goes here: set the view's size, margins, paddings and layout parameters 

    ViewHolder viewHolder = new ViewHolder(newView); 
    if (viewType == 1) { 
     // Adding the itemDecorator here 
     viewHolder.recyclerView.addItemDecoration(new HorizantalSpaceItemDecoration(HORIZANTAL_ITEM_SPACE)); 
    } 
    return viewHolder; 
} 
+0

ありがとう、私の質問に答えました。大きな助け。 – user8048493

+0

これが問題を完全に解決すればあなたの歓迎、答えを解決策としてマークしてください@ user8048493 – Alex

関連する問題