RecyclerView – Obtenez la vue à une position particulière

J’ai une activité avec un RecyclerView et un ImageView . J’utilise le RecyclerView pour afficher une liste d’images horizontalement. Lorsque je clique sur une image dans RecyclerView ImageView dans l’activité doit afficher une image plus grande de l’image. Jusqu’à présent, tout fonctionne bien.

Il y a maintenant deux autres ImageButtons dans l’activité: imageButton_left et imageButton_right . Lorsque je clique sur imageButton_left , l’image dans ImageView doit tourner à gauche et la vignette dans RecyclerView doit également refléter ce changement. Le même est le cas avec imageButton_right .

Je suis capable de faire pivoter l’ ImageView . Mais comment faire pivoter la vignette dans RecyclerView ? Comment puis-je obtenir l’ ViewHolder de ViewHolder ?

Code:

XML d’activité:

            

Mon code d’activité:

 public class SecondActivity extends AppCompatActivity implements IRecyclerViewClickListener { RecyclerView mRecyclerView; LinearLayoutManager mLayoutManager; RecyclerViewAdapter mRecyclerViewAdapter; List urls = new ArrayList(); ImageView mOriginalImageView; ImageButton mLeftRotate, mRightRotate; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); urls.clear(); mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview); mLayoutManager = new LinearLayoutManager(this, android.support.v7.widget.LinearLayoutManager.HORIZONTAL, false); mLayoutManager.setOrientation(android.support.v7.widget.LinearLayoutManager.HORIZONTAL); mRecyclerView.setLayoutManager(mLayoutManager); mRecyclerViewAdapter = new RecyclerViewAdapter(this, urls); mRecyclerView.setAdapter(mRecyclerViewAdapter); mOriginalImageView = (ImageView) findViewById(R.id.original_image); mLeftRotate = (ImageButton) findViewById(R.id.imageButton_left); mLeftRotate.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mOriginalImageView.setRotation(mOriginalImageView.getRotation() - 90); } }); mRightRotate = (ImageButton) findViewById(R.id.imageButton_right); mRightRotate.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mOriginalImageView.setRotation(mOriginalImageView.getRotation() + 90); } }); Intent intent = getIntent(); if (intent != null) { Ssortingng portfolio = intent.getSsortingngExtra("portfolio"); try { JSONArray jsonArray = new JSONArray(portfolio); for (int i = 0; i < jsonArray.length(); i++) { JSONObject jsonObject = jsonArray.getJSONObject(i); String url = jsonObject.getString("url"); urls.add(url); } Log.d(Const.DEBUG, "URLs: " + urls.toString()); mRecyclerViewAdapter.notifyDataSetChanged(); } catch (Exception e) { e.printStackTrace(); } } } @Override public void onItemClick(int position) { Picasso.with(this).load(urls.get(position)).into(mOriginalImageView); } } 

Mon adaptateur personnalisé pour RecyclerView:

 public class RecyclerViewAdapter extends RecyclerView.Adapter { Context context; List mUrls = new ArrayList(); IRecyclerViewClickListener mIRecyclerViewClickListener; public int position; public int getPosition() { return position; } public void setPosition(int position) { this.position = position; } public RecyclerViewAdapter(Context context, List urls) { this.context = context; this.mUrls.clear(); this.mUrls = urls; Log.d(Const.DEBUG, "Urls Size: " + urls.size()); Log.d(Const.DEBUG, urls.toSsortingng()); if (context instanceof IRecyclerViewClickListener) mIRecyclerViewClickListener = (IRecyclerViewClickListener) context; else Log.d(Const.DEBUG, "Implement IRecyclerViewClickListener in Activity"); } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(context).inflate(R.layout.item_horizontal_recyclerview, parent, false); ViewHolder holder = new ViewHolder(view); return holder; } @Override public void onBindViewHolder(ViewHolder holder, int position) { Picasso.with(context).load(mUrls.get(position)).into(holder.mImageView); } @Override public int getItemCount() { return mUrls.size(); } public void rotateThumbnail() { } public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { public ImageView mImageView; public View v; public ViewHolder(View v) { super(v); v.setTag(getAdapterPosition()); v.setOnClickListener(this); this.mImageView = (ImageView) v.findViewById(R.id.image); } @Override public void onClick(View v) { this.v = v; mIRecyclerViewClickListener.onItemClick(getAdapterPosition()); } } } 

Je suppose que vous utilisez un LinearLayoutManager pour afficher la liste. Il a une belle méthode appelée findViewByPosition qui

Trouve la vue qui représente la position de l’adaptateur donnée.

Tout ce dont vous avez besoin est la position de l’adaptateur de l’article qui vous intéresse.

edit : comme l’a noté Paul Woitaschek dans les commentaires, findViewByPosition est une méthode de LayoutManager donc elle fonctionnerait avec tous les LayoutManagers ( StaggeredGridLayoutManager , etc.)

C’est ce que vous recherchez .

J’ai eu ce problème également. Et comme vous, la réponse est très difficile à trouver. Mais il existe un moyen simple d’obtenir le ViewHolder à partir d’une position spécifique (ce que vous ferez probablement beaucoup dans l’adaptateur).

myRecyclerView.findViewHolderForAdapterPosition(pos);

Remarque: si la vue a été recyclée, cela retournera null . Merci à Michael d’avoir rapidement remarqué mon omission importante.

Si vous voulez la View , veillez à accéder à la propriété itemView du ViewHolder comme myRecyclerView.findViewHolderForAdapterPosition(pos).itemView; : myRecyclerView.findViewHolderForAdapterPosition(pos).itemView;

Vous pouvez utiliser les deux

recyclerViewInstance.findViewHolderForAdapterPosition(adapterPosition) et recyclerViewInstance.findViewHolderForLayoutPosition(layoutPosition) . Assurez-vous que la vue RecyclerView utilise deux types de positions

Position de l’adaptateur: position d’un élément dans l’adaptateur. C’est la position du sharepoint vue de l’adaptateur. Position de la mise en page: position d’un élément dans le dernier calcul de mise en page. C’est la position du sharepoint vue de LayoutManager. Vous devez utiliser getAdapterPosition() pour findViewHolderForAdapterPosition(adapterPosition) et getLayoutPosition() pour findViewHolderForLayoutPosition(layoutPosition) .

Prenez une variable membre pour contenir la position d’élément précédemment sélectionnée dans l’adaptateur recyclerview et une autre variable membre pour vérifier si l’utilisateur clique pour la première fois ou non.

Des exemples de code et des captures d’écran sont joints pour plus d’informations en bas.

 public class MainActivity extends AppCompatActivity { private RecyclerView mRecyclerList = null; private RecyclerAdapter adapter = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mRecyclerList = (RecyclerView) findViewById(R.id.recyclerList); } @Override protected void onStart() { RecyclerView.LayoutManager layoutManager = null; Ssortingng[] daysArray = new Ssortingng[15]; Ssortingng[] datesArray = new Ssortingng[15]; super.onStart(); for (int i = 0; i < daysArray.length; i++){ daysArray[i] = "Sunday"; datesArray[i] = "12 Feb 2017"; } adapter = new RecyclerAdapter(mRecyclerList, daysArray, datesArray); layoutManager = new LinearLayoutManager(MainActivity.this); mRecyclerList.setAdapter(adapter); mRecyclerList.setLayoutManager(layoutManager); } } public class RecyclerAdapter extends RecyclerView.Adapter{ private final Ssortingng TAG = "RecyclerAdapter"; private Context mContext = null; private TextView mDaysTxt = null, mDateTxt = null; private LinearLayout mDateContainerLayout = null; private Ssortingng[] daysArray = null, datesArray = null; private RecyclerView mRecyclerList = null; private int previousPosition = 0; private boolean flagFirstItemSelected = false; public RecyclerAdapter(RecyclerView mRecyclerList, Ssortingng[] daysArray, Ssortingng[] datesArray){ this.mRecyclerList = mRecyclerList; this.daysArray = daysArray; this.datesArray = datesArray; } @Override public MyCardViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater layoutInflater = null; View view = null; MyCardViewHolder cardViewHolder = null; mContext = parent.getContext(); layoutInflater = LayoutInflater.from(mContext); view = layoutInflater.inflate(R.layout.date_card_row, parent, false); cardViewHolder = new MyCardViewHolder(view); return cardViewHolder; } @Override public void onBindViewHolder(MyCardViewHolder holder, final int position) { mDaysTxt = holder.mDaysTxt; mDateTxt = holder.mDateTxt; mDateContainerLayout = holder.mDateContainerLayout; mDaysTxt.setText(daysArray[position]); mDateTxt.setText(datesArray[position]); if (!flagFirstItemSelected){ mDateContainerLayout.setBackgroundColor(Color.GREEN); flagFirstItemSelected = true; }else { mDateContainerLayout.setBackground(null); } } @Override public int getItemCount() { return daysArray.length; } class MyCardViewHolder extends RecyclerView.ViewHolder{ TextView mDaysTxt = null, mDateTxt = null; LinearLayout mDateContainerLayout = null; LinearLayout linearLayout = null; View view = null; MyCardViewHolder myCardViewHolder = null; public MyCardViewHolder(View itemView) { super(itemView); mDaysTxt = (TextView) itemView.findViewById(R.id.daysTxt); mDateTxt = (TextView) itemView.findViewById(R.id.dateTxt); mDateContainerLayout = (LinearLayout) itemView.findViewById(R.id.dateContainerLayout); mDateContainerLayout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { LinearLayout linearLayout = null; View view = null; if (getAdapterPosition() == previousPosition){ view = mRecyclerList.findViewHolderForAdapterPosition(previousPosition).itemView; linearLayout = (LinearLayout) view.findViewById(R.id.dateContainerLayout); linearLayout.setBackgroundColor(Color.GREEN); previousPosition = getAdapterPosition(); }else { view = mRecyclerList.findViewHolderForAdapterPosition(previousPosition).itemView; linearLayout = (LinearLayout) view.findViewById(R.id.dateContainerLayout); linearLayout.setBackground(null); view = mRecyclerList.findViewHolderForAdapterPosition(getAdapterPosition()).itemView; linearLayout = (LinearLayout) view.findViewById(R.id.dateContainerLayout); linearLayout.setBackgroundColor(Color.GREEN); previousPosition = getAdapterPosition(); } } }); } } 

} premier élément sélectionné le deuxième élément sélectionné et l'élément précédemment sélectionné ne sont plus sélectionnés le cinquième élément sélectionné et l'élément sélectionné précédemment ne sont plus sélectionnés