Mam aktywność z a RecyclerView
i ImageView
. Używam, RecyclerView
aby wyświetlić listę zdjęć w poziomie. Po kliknięciu na zdjęcie w w działalności powinny wykazywać większe zdjęcie obrazu. Jak dotąd wszystko działa dobrze.RecyclerView
ImageView
Teraz w ćwiczeniu są jeszcze dwa ImageButtons
: imageButton_left
i imageButton_right
. Kiedy kliknę imageButton_left
, obraz w ImageView
powinien obrócić się w lewo, a miniatura w RecyclerView
powinna odzwierciedlać tę zmianę. Podobnie jest z imageButton_right
.
Jestem w stanie obrócić ImageView
. Ale jak mogę obrócić miniaturę w RecyclerView
? Jak mogę dostać ViewHolder
„s ImageView
?
Kod:
XML aktywności:
<?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>
Kod mojej aktywności:
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);
}
}
Mój niestandardowy adapter dla 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());
}
}
}
Odpowiedzi:
Przypuszczam, że używasz a,
LinearLayoutManager
aby wyświetlić listę. Ma fajną metodę o nazwiefindViewByPosition
toWszystko, czego potrzebujesz, to pozycja adaptera interesującego Cię przedmiotu.
edycja : jak zauważył Paul Woitaschek w komentarzach,
findViewByPosition
jest to metoda,LayoutManager
więc działałaby ze wszystkimi LayoutManagerami (tj.StaggeredGridLayoutManager
itp.)źródło
LayoutManager
więc będzie działać dla wszystkich podklas LayoutManager.To jest to, czego szukasz .
Ja też miałem ten problem. I tak jak ty, odpowiedź jest bardzo trudna do znalezienia. Ale jest łatwy sposób na pobranie ViewHolder z określonej pozycji (coś, co prawdopodobnie zrobisz dużo w adapterze).
myRecyclerView.findViewHolderForAdapterPosition(pos);
UWAGA: Jeśli widok został poddany recyklingowi, powróci
null
. Dziękuję Michaelowi za szybkie złapanie mojego ważnego przeoczenia.źródło
ViewHolder
, do którego próbujesz się odwołać, został „poddany recyklingowi”, zostanie zwróconynull
.Jeśli chcesz
View
, upewnij się, że masz dostęp doitemView
właściwości ViewHolder w następujący sposób:myRecyclerView.findViewHolderForAdapterPosition(pos).itemView;
źródło
Możesz użyć obu
recyclerViewInstance.findViewHolderForAdapterPosition(adapterPosition)
irecyclerViewInstance.findViewHolderForLayoutPosition(layoutPosition)
. Upewnij się, że widok RecyclerView używa dwóch typów pozycjiPozycja adaptera: pozycja elementu w adapterze. To jest pozycja z perspektywy Adaptera. Pozycja układu: pozycja elementu w ostatnich obliczeniach układu. To jest pozycja z perspektywy LayoutManagera. Powinieneś używać
getAdapterPosition()
dlafindViewHolderForAdapterPosition(adapterPosition)
igetLayoutPosition()
dlafindViewHolderForLayoutPosition(layoutPosition)
.Weź zmienną składową, aby zachować poprzednio wybraną pozycję elementu w adapterze recyclinglerview i inną zmienną składową, aby sprawdzić, czy użytkownik kliknął po raz pierwszy, czy nie.
Przykładowy kod i zrzuty ekranu znajdują się na dole, aby uzyskać więcej informacji.
}
źródło
Możesz utworzyć ArrayList of ViewHolder:
i wszystkie przechowują ViewHolder na liście, na przykład:
i dodaj / usuń inne ViewHolder w ArrayList zgodnie z wymaganiami.
źródło
Możesz uzyskać widok dla określonej pozycji w widoku recyklingu, korzystając z poniższego
źródło
Możesz po prostu użyć metody " findViewHolderForAdapterPosition " widoku recyklera, a otrzymasz z niego obiekt viewHolder, a następnie typecast tego elementu widoku do elementu widoku adaptera, dzięki czemu uzyskasz bezpośredni dostęp do widoków elementu widoku
poniżej znajduje się przykładowy kod dla kotlin
źródło
Pamiętaj, że musisz poczekać, aż adapter zostanie dodany do listy, wtedy możesz spróbować uzyskać widok według pozycji
źródło
Aby uzyskać widok z określonej pozycji w RecyclerView, należy wywołać funkcję findViewHolderForAdapterPosition (pozycja) na obiekcie recyclinglerView, który zwróci RecyclerView.ViewHolder
z zwróconego obiektu RecyclerView.ViewHolder z itemView można uzyskać dostęp do wszystkich widoków w tej konkretnej pozycji
źródło
Możesz to również zrobić, to pomoże, gdy chcesz zmodyfikować widok po kliknięciu pozycji widoku recyklingu
źródło
Aby uzyskać określony widok z listy widoków recyklera LUB pokaż błąd w edytorze widoku recyklera.
źródło