Tengo una actividad con ay RecyclerView
an ImageView
. Estoy usando el RecyclerView
para mostrar una lista de imágenes horizontalmente. Cuando hago clic en una imagen en el RecyclerView
la ImageView
en la actividad debe mostrar un panorama más amplio de la imagen. Hasta ahora todo funciona bien.
Ahora hay dos más ImageButtons
en la actividad: imageButton_left
y imageButton_right
. Cuando hago clic en imageButton_left
, la imagen en el ImageView
debería girar a la izquierda y también, la miniatura en el RecyclerView
debería reflejar este cambio. Similar es el caso con imageButton_right
.
Soy capaz de rotar el ImageView
. Pero, ¿cómo puedo rotar la miniatura en el RecyclerView
? ¿Cómo puedo obtener los ViewHolder
's ImageView
?
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());
}
}
}
Respuestas:
Supongo que está utilizando a
LinearLayoutManager
para mostrar la lista. Tiene un buen método llamadofindViewByPosition
esoTodo 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étodoLayoutManager
para que funcione con todos los LayoutManagers (es decirStaggeredGridLayoutManager
, etc.)fuente
LayoutManager
lo que funcionará para todas las subclases de LayoutManagerEsto 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 volverá
null
. Gracias a Michael por captar rápidamente mi importante omisión.fuente
ViewHolder
que intenta hacer referencia fue "reciclado", volveránull
.Si desea que el
View
, asegúrese de acceso a laitemView
propiedad de la ViewHolder de este modo:myRecyclerView.findViewHolderForAdapterPosition(pos).itemView;
fuente
Puedes usar usar ambos
recyclerViewInstance.findViewHolderForAdapterPosition(adapterPosition)
yrecyclerViewInstance.findViewHolderForLayoutPosition(layoutPosition)
. Asegúrese de que la vista RecyclerView utiliza dos tipos de posicionesPosició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()
parafindViewHolderForAdapterPosition(adapterPosition)
ygetLayoutPosition()
parafindViewHolderForLayoutPosition(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.
}
fuente
Puede hacer ArrayList de ViewHolder:
y, todos almacenan ViewHolder (s) en la lista como:
y agregue / elimine otro ViewHolder en ArrayList según su requisito.
fuente
Puede obtener una vista para una posición particular en una vista de reciclador utilizando lo siguiente
fuente
Simplemente puede usar el método " findViewHolderForAdapterPosition " de la vista de reciclador y obtendrá un objeto viewHolder a partir de ese entonces, escriba ese marcador de vista en el marcador de adaptador para que pueda acceder directamente a las vistas de su marcador
el siguiente es el código de muestra para kotlin
fuente
Tenga en cuenta que debe esperar hasta que se agregue el adaptador a la lista, luego puede intentar obtener una vista por posición
fuente
Para obtener una vista desde una posición específica de recyclerView, debe llamar a findViewHolderForAdapterPosition (posición) en el objeto recyclerView que devolverá RecyclerView.ViewHolder
desde el objeto RecyclerView.ViewHolder devuelto con itemView puede acceder a todas las Vistas en esa posición particular
fuente
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
fuente
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.
fuente