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.