viewholder recyclerview item holder getposition getadapterposition from current java android android-recyclerview widget position

java - item - RecyclerView-Obtenga vista en una posición particular



getposition recyclerview (10)

Tengo una actividad con un RecyclerView y un ImageView . Estoy usando RecyclerView para mostrar una lista de imágenes horizontalmente. Cuando hago clic en una imagen en RecyclerView ImageView en la actividad debería mostrar una imagen más grande de la imagen. Hasta ahora todo funciona bien.

Ahora hay dos ImageButtons más en la actividad: imageButton_left e imageButton_right . Cuando hago clic en imageButton_left , la imagen en ImageView debe girar a la izquierda y también, la miniatura en RecyclerView debe reflejar este cambio. Similar es el caso con imageButton_right .

Puedo rotar el ImageView . Pero, ¿cómo puedo rotar la miniatura en RecyclerView ? ¿Cómo puedo obtener el ImageView ViewHolder ?

Código:

XML de actividad:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerview" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:orientation="vertical"> <ImageView android:id="@+id/original_image" android:layout_width="200dp" android:layout_height="200dp" android:scaleType="fitXY" android:src="@drawable/image_not_available_2" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:gravity="center_horizontal" android:orientation="horizontal"> <ImageButton android:id="@+id/imageButton_left" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="20dp" android:background="@drawable/rotate_left_icon" /> <ImageButton android:id="@+id/imageButton_right" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/rotate_right_icon" /> </LinearLayout> </LinearLayout> </LinearLayout>

Mi código de actividad:

public class SecondActivity extends AppCompatActivity implements IRecyclerViewClickListener { RecyclerView mRecyclerView; LinearLayoutManager mLayoutManager; RecyclerViewAdapter mRecyclerViewAdapter; List<String> urls = new ArrayList<String>(); 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) { String portfolio = intent.getStringExtra("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); } }

Mi adaptador personalizado para RecyclerView:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> { Context context; List<String> mUrls = new ArrayList<String>(); IRecyclerViewClickListener mIRecyclerViewClickListener; public int position; public int getPosition() { return position; } public void setPosition(int position) { this.position = position; } public RecyclerViewAdapter(Context context, List<String> urls) { this.context = context; this.mUrls.clear(); this.mUrls = urls; Log.d(Const.DEBUG, "Urls Size: " + urls.size()); Log.d(Const.DEBUG, urls.toString()); 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()); } } }


Para obtener una vista específica de la lista de vista del reciclador O mostrar un error en el texto de edición de la vista del reciclador.

private void popupErrorMessageAtPosition(int itemPosition) { RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(itemPosition); View view = viewHolder.itemView; EditText etDesc = (EditText) view.findViewById(R.id.et_description); etDesc.setError("Error message here !"); }


Puede hacer ArrayList de ViewHolder:

ArrayList<MyViewHolder> myViewHolders = new ArrayList<>(); ArrayList<MyViewHolder> myViewHolders2 = new ArrayList<>();

y, todos almacenan ViewHolder (s) en la lista como:

@Override public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) { final String str = arrayList.get(position); myViewHolders.add(position,holder); }

y agregue / elimine otro ViewHolder en ArrayList según su requisito.


Puede obtener una vista para una posición particular en una vista de reciclador utilizando lo siguiente

int position = 2; RecyclerView.ViewHolder viewHolder = recyclerview.findViewHolderForItemId(position); View view = viewHolder.itemView; ImageView imageView = (ImageView)view.findViewById(R.id.imageView);


Puedes usar usar ambos

recyclerViewInstance.findViewHolderForAdapterPosition(adapterPosition) y recyclerViewInstance.findViewHolderForLayoutPosition(layoutPosition) . Asegúrese de que la vista RecyclerView utiliza dos tipos de posiciones

Posición del adaptador: posición de un elemento en el adaptador. Esta es la posición desde la perspectiva del Adaptador. Posición de diseño: posición de un elemento en el último cálculo de diseño. Esta es la posición desde la perspectiva del LayoutManager. Debe usar getAdapterPosition() para findViewHolderForAdapterPosition(adapterPosition) y getLayoutPosition() para findViewHolderForLayoutPosition(layoutPosition) .

Tome una variable miembro para mantener la posición del elemento previamente seleccionado en el adaptador de la vista de reciclaje y otra variable miembro para verificar si el usuario hace clic por primera vez o no.

Se adjuntan códigos de muestra y capturas de pantalla para obtener más información en la parte inferior.

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; String[] daysArray = new String[15]; String[] datesArray = new String[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<RecyclerAdapter.MyCardViewHolder>{ private final String TAG = "RecyclerAdapter"; private Context mContext = null; private TextView mDaysTxt = null, mDateTxt = null; private LinearLayout mDateContainerLayout = null; private String[] daysArray = null, datesArray = null; private RecyclerView mRecyclerList = null; private int previousPosition = 0; private boolean flagFirstItemSelected = false; public RecyclerAdapter(RecyclerView mRecyclerList, String[] daysArray, String[] 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(); } } }); } }

}


Si desea la View , asegúrese de acceder a la propiedad itemView de ViewHolder de la siguiente manera: myRecyclerView.findViewHolderForAdapterPosition(pos).itemView;


Simplemente puede usar el método " findViewHolderForAdapterPosition " de la vista de reciclador y obtendrá un objeto viewHolder de ese tipo, luego escriba ese marcador de vista en el marcador de vista del adaptador para que pueda acceder directamente a las vistas de su marcador

el siguiente es el código de muestra para kotlin

val viewHolder = recyclerView.findViewHolderForAdapterPosition(position) val textview=(viewHolder as YourViewHolder).yourTextView


Supongo que está utilizando un LinearLayoutManager para mostrar la lista. Tiene un buen método llamado findViewByPosition que

Encuentra la vista que representa la posición del adaptador dada.

Todo lo que necesita es la posición del adaptador del artículo que le interesa.

editar : como señaló Paul Woitaschek en los comentarios, findViewByPosition es un método de LayoutManager para que funcione con todos los LayoutManagers (es decir, StaggeredGridLayoutManager , etc.)


También puede hacer esto, esto ayudará cuando desee modificar una vista después de hacer clic en un elemento de posición de vista de reciclador

@Override public void onClick(View view, int position) { View v = rv_notifications.getChildViewHolder(view).itemView; TextView content = v.findViewById(R.id.tv_content); content.setText("Helloo"); }


Tenga en cuenta que debe esperar hasta que se agregue el adaptador a la lista, luego puede intentar obtener una vista por posición

final int i = 0; recyclerView.setAdapter(adapter); recyclerView.post(new Runnable() { @Override public void run() { View view = recyclerView.getLayoutManager().findViewByPosition(i); } });


Esto es lo que estás buscando .

Yo tuve este problema también. Y como tú, la respuesta es muy difícil de encontrar. Pero hay una manera fácil de obtener el ViewHolder desde una posición específica (algo que probablemente harás mucho en el adaptador).

myRecyclerView.findViewHolderForAdapterPosition(pos);

NOTA: Si la Vista ha sido reciclada, esto devolverá null . Gracias a Michael por captar rápidamente mi importante omisión.