Dlaczego RecyclerView nie ma funkcji onItemClickListener ()?
Badałem RecyclerView
i byłem zaskoczony widząc, że {[1] } nie ma onItemClickListener()
.
Pytanie Główne
Chcę wiedzieć dlaczego Google usunęło onItemClickListener()
?
Jest jakiś problem z wydajnością Czy coś innego?
Pytanie Drugorzędne
Rozwiązałem swój problem pisząc onClick
w moim RecyclerView.Adapter
:
public static class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener {
public TextView txtViewTitle;
public ImageView imgViewIcon;
public ViewHolder(View itemLayoutView) {
super(itemLayoutView);
txtViewTitle = (TextView) itemLayoutView.findViewById(R.id.item_title);
imgViewIcon = (ImageView) itemLayoutView.findViewById(R.id.item_icon);
}
@Override
public void onClick(View v) {
}
}
Czy jest jakiś lepszy sposób ? 30 answers
Tl; dr 2016 użyj RxJava i PublishSubject, aby odsłonić obserwowalny dla kliknięć.
public class ReactiveAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
String[] mDataset = { "Data", "In", "Adapter" };
private final PublishSubject<String> onClickSubject = PublishSubject.create();
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
final String element = mDataset[position];
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onClickSubject.onNext(element);
}
});
}
public Observable<String> getPositionClicks(){
return onClickSubject.asObservable();
}
}
Oryginalny Post:
Od wprowadzenia ListView
, onItemClickListener
było problematyczne. W momencie, gdy masz słuchacza kliknij dla każdego z elementów wewnętrznych callback nie zostanie uruchomiony, ale nie został powiadomiony lub dobrze udokumentowane (jeśli w ogóle), więc było wiele zamieszania i tak pytania o to.
Biorąc pod uwagę, że RecyclerView
idzie o krok dalej i nie ma pojęcia o wierszu / kolumnie, ale raczej arbitralnie określoną liczbę dzieci, przekazali onClick każdemu z nich lub do implementacji programisty.
Pomyśl o Recyclerview
nie jako zamienniku ListView
1:1, ale raczej jako bardziej elastycznym komponencie do złożonych zastosowań. I jak mówisz, Twoje rozwiązanie jest tym, czego oczekuje od Ciebie google. Teraz masz adapter, który może delegować onClick do interfejsu przekazanego konstruktora, który jest prawidłowym wzorem dla obu ListView
i Recyclerview
.
public static class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener {
public TextView txtViewTitle;
public ImageView imgViewIcon;
public IMyViewHolderClicks mListener;
public ViewHolder(View itemLayoutView, IMyViewHolderClicks listener) {
super(itemLayoutView);
mListener = listener;
txtViewTitle = (TextView) itemLayoutView.findViewById(R.id.item_title);
imgViewIcon = (ImageView) itemLayoutView.findViewById(R.id.item_icon);
imgViewIcon.setOnClickListener(this);
itemLayoutView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (v instanceof ImageView){
mListener.onTomato((ImageView)v);
} else {
mListener.onPotato(v);
}
}
public static interface IMyViewHolderClicks {
public void onPotato(View caller);
public void onTomato(ImageView callerImage);
}
}
A następnie na adapterze
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
String[] mDataset = { "Data" };
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_layout, parent, false);
MyAdapter.ViewHolder vh = new ViewHolder(v, new MyAdapter.ViewHolder.IMyViewHolderClicks() {
public void onPotato(View caller) { Log.d("VEGETABLES", "Poh-tah-tos"); };
public void onTomato(ImageView callerImage) { Log.d("VEGETABLES", "To-m8-tohs"); }
});
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
// Get element from your dataset at this position
// Replace the contents of the view with that element
// Clear the ones that won't be used
holder.txtViewTitle.setText(mDataset[position]);
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return mDataset.length;
}
...
Teraz przyjrzyj się temu ostatniemu fragmentowi kodu: onCreateViewHolder(ViewGroup parent, int viewType)
podpis już sugeruje różne typy widoków. Dla każdego z nich będziesz potrzebował innego viewholdera, a następnie każdy z nich może mieć inny zestaw kliknięć. Możesz też utworzyć ogólny viewholder, który przyjmuje dowolny widok i jeden onClickListener
i stosuje się odpowiednio. Lub delegować jeden poziom do orkiestratora, więc kilka fragmentów / działań mieć tę samą listę z różnymi zachowaniami kliknięć. Ponownie, Cała elastyczność jest po twojej stronie.
Jest to naprawdę potrzebny komponent i dość zbliżony do tego, co nasze wewnętrzne implementacje i ulepszenia do ListView
były do tej pory. Dobrze, że Google w końcu to uznaje.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-03 09:24:57
Dlaczego RecyclerView nie ma onItemClickListener
RecyclerView
jest zestawem narzędzi, w przeciwieństwie do starego ListView
ma mniej wbudowanych funkcji i większą elastyczność. onItemClickListener
nie jest jedyną funkcją usuniętą z ListView. Ale ma dużo słuchaczy i sposób, aby rozszerzyć go do swoich upodobań, jest o wiele mocniejszy we właściwych rękach ;).
Moim zdaniem najbardziej złożoną cechą usuniętą w RecyclerView
jest szybki przewijanie. Większość innych funkcji może być łatwo ponownie wdrożony.
Jeśli chcesz wiedzieć jakie inne fajne funkcje RecyclerView
dodał przeczytaj to odpowiedz na inne pytanie.
Memory efficient-drop-in solution for onItemClickListener
To rozwiązanie zostało zaproponowane przez Hugo Vissera, Androida GDE, zaraz po wydaniu {7]}. Udostępnił Ci klasę bez licencji, abyś mógł po prostu wrzucić swój kod i go użyć.Prezentuje niektóre z wszechstronności wprowadzonych z RecyclerView
przez korzystanie z RecyclerView.OnChildAttachStateChangeListener
.
Edit 2019 : wersja Kotlina autorstwa mnie, java one, od Hugo Vissera, trzymana poniżej
Kotlin / Java
Utwórz plik values/ids.xml
i umieść w nim to:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="item_click_support" type="id" />
</resources>
Następnie dodaj poniższy kod do swojego źródła
Kotlin
Użycie:
recyclerView.onItemClick { recyclerView, position, v ->
// do it
}
(obsługuje również długie kliknięcie pozycji i zobacz poniżej inną funkcję, którą dodałem).
Implementacja (moja adaptacja do kodu Javy Hugo Vissera):
typealias OnRecyclerViewItemClickListener = (recyclerView: RecyclerView, position: Int, v: View) -> Unit
typealias OnRecyclerViewItemLongClickListener = (recyclerView: RecyclerView, position: Int, v: View) -> Boolean
class ItemClickSupport private constructor(private val recyclerView: RecyclerView) {
private var onItemClickListener: OnRecyclerViewItemClickListener? = null
private var onItemLongClickListener: OnRecyclerViewItemLongClickListener? = null
private val attachListener: RecyclerView.OnChildAttachStateChangeListener = object : RecyclerView.OnChildAttachStateChangeListener {
override fun onChildViewAttachedToWindow(view: View) {
// every time a new child view is attached add click listeners to it
val holder = [email protected](view)
.takeIf { it is ItemClickSupportViewHolder } as? ItemClickSupportViewHolder
if (onItemClickListener != null && holder?.isClickable != false) {
view.setOnClickListener(onClickListener)
}
if (onItemLongClickListener != null && holder?.isLongClickable != false) {
view.setOnLongClickListener(onLongClickListener)
}
}
override fun onChildViewDetachedFromWindow(view: View) {
}
}
init {
// the ID must be declared in XML, used to avoid
// replacing the ItemClickSupport without removing
// the old one from the RecyclerView
this.recyclerView.setTag(R.id.item_click_support, this)
this.recyclerView.addOnChildAttachStateChangeListener(attachListener)
}
companion object {
fun addTo(view: RecyclerView): ItemClickSupport {
// if there's already an ItemClickSupport attached
// to this RecyclerView do not replace it, use it
var support: ItemClickSupport? = view.getTag(R.id.item_click_support) as? ItemClickSupport
if (support == null) {
support = ItemClickSupport(view)
}
return support
}
fun removeFrom(view: RecyclerView): ItemClickSupport? {
val support = view.getTag(R.id.item_click_support) as? ItemClickSupport
support?.detach(view)
return support
}
}
private val onClickListener = View.OnClickListener { v ->
val listener = onItemClickListener ?: return@OnClickListener
// ask the RecyclerView for the viewHolder of this view.
// then use it to get the position for the adapter
val holder = this.recyclerView.getChildViewHolder(v)
listener.invoke(this.recyclerView, holder.adapterPosition, v)
}
private val onLongClickListener = View.OnLongClickListener { v ->
val listener = onItemLongClickListener ?: return@OnLongClickListener false
val holder = this.recyclerView.getChildViewHolder(v)
return@OnLongClickListener listener.invoke(this.recyclerView, holder.adapterPosition, v)
}
private fun detach(view: RecyclerView) {
view.removeOnChildAttachStateChangeListener(attachListener)
view.setTag(R.id.item_click_support, null)
}
fun onItemClick(listener: OnRecyclerViewItemClickListener?): ItemClickSupport {
onItemClickListener = listener
return this
}
fun onItemLongClick(listener: OnRecyclerViewItemLongClickListener?): ItemClickSupport {
onItemLongClickListener = listener
return this
}
}
/** Give click-ability and long-click-ability control to the ViewHolder */
interface ItemClickSupportViewHolder {
val isClickable: Boolean get() = true
val isLongClickable: Boolean get() = true
}
// Extension function
fun RecyclerView.addItemClickSupport(configuration: ItemClickSupport.() -> Unit = {}) = ItemClickSupport.addTo(this).apply(configuration)
fun RecyclerView.removeItemClickSupport() = ItemClickSupport.removeFrom(this)
fun RecyclerView.onItemClick(onClick: OnRecyclerViewItemClickListener) {
addItemClickSupport { onItemClick(onClick) }
}
fun RecyclerView.onItemLongClick(onLongClick: OnRecyclerViewItemLongClickListener) {
addItemClickSupport { onItemLongClick(onLongClick) }
}
(pamiętaj musisz również dodać plik XML, patrz powyżej tej sekcji)
Bonus w wersji Kotlina
Czasami nie chcesz, aby wszystkie elementy RecyclerView były klikalne.
Aby sobie z tym poradzić, wprowadziłem interfejs ItemClickSupportViewHolder
, którego możesz użyć na swoim ViewHolder
, aby kontrolować, który element można kliknąć.
Przykład:
class MyViewHolder(view): RecyclerView.ViewHolder(view), ItemClickSupportViewHolder {
override val isClickable: Boolean get() = false
override val isLongClickable: Boolean get() = false
}
Java
Użycie:
ItemClickSupport.addTo(mRecyclerView)
.setOnItemClickListener(new ItemClickSupport.OnItemClickListener() {
@Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
// do it
}
});
(obsługuje również długie kliknięcie elementu)
Implementacja (komentarze dodane przez ja):
public class ItemClickSupport {
private final RecyclerView mRecyclerView;
private OnItemClickListener mOnItemClickListener;
private OnItemLongClickListener mOnItemLongClickListener;
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mOnItemClickListener != null) {
// ask the RecyclerView for the viewHolder of this view.
// then use it to get the position for the adapter
RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
mOnItemClickListener.onItemClicked(mRecyclerView, holder.getAdapterPosition(), v);
}
}
};
private View.OnLongClickListener mOnLongClickListener = new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (mOnItemLongClickListener != null) {
RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
return mOnItemLongClickListener.onItemLongClicked(mRecyclerView, holder.getAdapterPosition(), v);
}
return false;
}
};
private RecyclerView.OnChildAttachStateChangeListener mAttachListener
= new RecyclerView.OnChildAttachStateChangeListener() {
@Override
public void onChildViewAttachedToWindow(View view) {
// every time a new child view is attached add click listeners to it
if (mOnItemClickListener != null) {
view.setOnClickListener(mOnClickListener);
}
if (mOnItemLongClickListener != null) {
view.setOnLongClickListener(mOnLongClickListener);
}
}
@Override
public void onChildViewDetachedFromWindow(View view) {
}
};
private ItemClickSupport(RecyclerView recyclerView) {
mRecyclerView = recyclerView;
// the ID must be declared in XML, used to avoid
// replacing the ItemClickSupport without removing
// the old one from the RecyclerView
mRecyclerView.setTag(R.id.item_click_support, this);
mRecyclerView.addOnChildAttachStateChangeListener(mAttachListener);
}
public static ItemClickSupport addTo(RecyclerView view) {
// if there's already an ItemClickSupport attached
// to this RecyclerView do not replace it, use it
ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support);
if (support == null) {
support = new ItemClickSupport(view);
}
return support;
}
public static ItemClickSupport removeFrom(RecyclerView view) {
ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support);
if (support != null) {
support.detach(view);
}
return support;
}
public ItemClickSupport setOnItemClickListener(OnItemClickListener listener) {
mOnItemClickListener = listener;
return this;
}
public ItemClickSupport setOnItemLongClickListener(OnItemLongClickListener listener) {
mOnItemLongClickListener = listener;
return this;
}
private void detach(RecyclerView view) {
view.removeOnChildAttachStateChangeListener(mAttachListener);
view.setTag(R.id.item_click_support, null);
}
public interface OnItemClickListener {
void onItemClicked(RecyclerView recyclerView, int position, View v);
}
public interface OnItemLongClickListener {
boolean onItemLongClicked(RecyclerView recyclerView, int position, View v);
}
}
Jak to działa (dlaczego jest wydajne)
Klasa ta działa poprzez dołączenie RecyclerView.OnChildAttachStateChangeListener
do RecyclerView
. Ten słuchacz jest powiadamiany za każdym razem, gdy dziecko jest dołączone lub odłączone od RecyclerView
. Kod ten służy do dodania słuchacza kranu/długiego kliknięcia do widoku. Ten słuchacz pyta {[7] } o RecyclerView.ViewHolder
, który zawiera pozycję.
Jest to bardziej efektywne niż inne rozwiązania, ponieważ pozwala uniknąć tworzenia wielu słuchaczy dla każdego widoku i ciągle je niszczyć i tworzyć podczas przewijania RecyclerView
.
Możesz również dostosować kod, aby zwrócić sam uchwyt, jeśli potrzebujesz więcej.
Uwaga końcowa
Należy pamiętać, że jest to całkowicie w porządku, aby obsłużyć go w adapterze, ustawiając na każdym widoku listy słuchacza kliknięcia, tak jak inne proponowane odpowiedzi.
To po prostu nie jest najskuteczniejsza rzecz do zrobienia (tworzysz nowy słuchacz za każdym razem, gdy ponownie używasz widoku), ale to działa i w większości przypadków nie jest problemem.
Jest również trochę przeciwko rozdzielaniu obaw, ponieważ tak naprawdę nie jest zadaniem adaptera delegowanie zdarzeń kliknięć.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-07-05 23:21:11
Lubię ten sposób i używam go
Wewnątrz
public Adapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
Put
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_image_and_text, parent, false);
v.setOnClickListener(new MyOnClickListener());
I utwórz tę klasę gdziekolwiek chcesz
class MyOnClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
int itemPosition = recyclerView.indexOfChild(v);
Log.e("Clicked and Position is ",String.valueOf(itemPosition));
}
}
Czytałem wcześniej, że jest lepszy sposób, ale lubię ten sposób jest łatwy i nie skomplikowany.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-05 18:13:26
Android Recyclerview Z onItemClickListener
,
Dlaczego nie możemy spróbować to działa jak ListView
tylko.
Źródło: Link
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;
public interface OnItemClickListener {
public void onItemClick(View view, int position);
}
GestureDetector mGestureDetector;
public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
}
return false;
}
@Override
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
I ustaw to na RecyclerView:
recyclerView = (RecyclerView)rootView. findViewById(R.id.recyclerView);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.addOnItemTouchListener(
new RecyclerItemClickListener(getActivity(), new RecyclerItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
// TODO Handle item click
Log.e("@@@@@",""+position);
}
})
);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-13 13:36:05
Dzięki @ marmor, zaktualizowałem swoją odpowiedź.
Myślę, że dobrym rozwiązaniem jest obsługa onclick () w konstruktorze klasy viewholder i przekazanie go do klasy nadrzędnej poprzez interfejs onitemclicklistener.
MyAdapter.java
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{
private LayoutInflater layoutInflater;
private List<MyObject> items;
private AdapterView.OnItemClickListener onItemClickListener;
public MyAdapter(Context context, AdapterView.OnItemClickListener onItemClickListener, List<MyObject> items) {
layoutInflater = LayoutInflater.from(context);
this.items = items;
this.onItemClickListener = onItemClickListener;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = layoutInflater.inflate(R.layout.my_row_layout, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
MyObject item = items.get(position);
}
public MyObject getItem(int position) {
return items.get(position);
}
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView title;
private ImageView avatar;
public ViewHolder(View itemView) {
super(itemView);
title = itemView.findViewById(R.id.title);
avatar = itemView.findViewById(R.id.avatar);
title.setOnClickListener(this);
avatar.setOnClickListener(this);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
//passing the clicked position to the parent class
onItemClickListener.onItemClick(null, view, getAdapterPosition(), view.getId());
}
}
}
Użycie adaptera w innych klasach:
Mój fragment.java
public class MyFragment extends Fragment implements AdapterView.OnItemClickListener {
private RecyclerView recycleview;
private MyAdapter adapter;
.
.
.
private void init(Context context) {
//passing this fragment as OnItemClickListener to the adapter
adapter = new MyAdapter(context, this, items);
recycleview.setAdapter(adapter);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//you can get the clicked item from the adapter using its position
MyObject item = adapter.getItem(position);
//you can also find out which view was clicked
switch (view.getId()) {
case R.id.title:
//title view was clicked
break;
case R.id.avatar:
//avatar view was clicked
break;
default:
//the whole row was clicked
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-30 07:57:25
Faceci używają tego kodu w Twojej głównej aktywności. Bardzo Skuteczna Metoda
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.users_list);
UsersAdapter adapter = new UsersAdapter(users, this);
recyclerView.setAdapter(adapter);
adapter.setOnCardClickListner(this);
Oto twoja klasa adaptera.
public class UsersAdapter extends RecyclerView.Adapter<UsersAdapter.UserViewHolder> {
private ArrayList<User> mDataSet;
OnCardClickListner onCardClickListner;
public UsersAdapter(ArrayList<User> mDataSet) {
this.mDataSet = mDataSet;
}
@Override
public UserViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.user_row_layout, parent, false);
UserViewHolder userViewHolder = new UserViewHolder(v);
return userViewHolder;
}
@Override
public void onBindViewHolder(UserViewHolder holder, final int position) {
holder.name_entry.setText(mDataSet.get(position).getUser_name());
holder.cardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onCardClickListner.OnCardClicked(v, position);
}
});
}
@Override
public int getItemCount() {
return mDataSet.size();
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
public static class UserViewHolder extends RecyclerView.ViewHolder {
CardView cardView;
TextView name_entry;
public UserViewHolder(View itemView) {
super(itemView);
cardView = (CardView) itemView.findViewById(R.id.user_layout);
name_entry = (TextView) itemView.findViewById(R.id.name_entry);
}
}
public interface OnCardClickListner {
void OnCardClicked(View view, int position);
}
public void setOnCardClickListner(OnCardClickListner onCardClickListner) {
this.onCardClickListner = onCardClickListner;
}
}
Następnie otrzymasz tę metodę nadpisywania w swojej aktywności.
@Override
public void OnCardClicked(View view, int position) {
Log.d("OnClick", "Card Position" + position);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-09 12:15:27
> czym RecyclerView różni się od Listview?
Jedna różnica polega na tym, że istnieje LayoutManager
klasa z RecyclerView, dzięki której możesz zarządzać swoimRecyclerView
Jak-
poziome lub przewijanie pionowe przez
LinearLayoutManager
GridLayout by
GridLayoutManager
StaggeredGridLayoutManager
Jak do poziomego przewijania dla RecyclerView-
LinearLayoutManager llm = new LinearLayoutManager(context);
llm.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(llm);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-01 13:53:49
Jak to wszystko połączyć przykład...
- obsługa onclick ()
- Cursor-RecyclerView
-
public class OrderListCursorAdapter extends CursorRecyclerViewAdapter<OrderListCursorAdapter.ViewHolder> { private static final String TAG = OrderListCursorAdapter.class.getSimpleName(); private static final int ID_VIEW_HOLDER_ACTUAL = 0; private static final int ID_VIEW_HOLDER = 1; public OrderListCursorAdapter(Context context, Cursor cursor) { super(context, cursor); } public static class ViewHolderActual extends ViewHolder { private static final String TAG = ViewHolderActual.class.getSimpleName(); protected IViewHolderClick listener; protected Button button; public ViewHolderActual(View v, IViewHolderClick listener) { super(v, listener); this.listener = listener; button = (Button) v.findViewById(R.id.orderList_item_button); button.setOnClickListener(this); } public void initFromData(OrderData data) { Log.d(TAG, "><initFromData(data=" + data + ")"); orderId = data.getId(); vAddressStart.setText(data.getAddressStart()); vAddressEnd.setText(data.getAddressEnd()); } @Override public void onClick(View view) { if (view instanceof Button) { listener.onButtonClick((Button) view, getPosition(), this); } else { super.onClick(view); } } public interface IViewHolderClick extends ViewHolder.IViewHolderClick { public void onButtonClick(Button button, int position, ViewHolder viewHolder); } } public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { private static final String TAG = ViewHolder.class.getSimpleName(); protected long orderId; protected IViewHolderClick listener; protected TextView vAddressStart; protected TextView vAddressEnd; protected TextView vStatus; public ViewHolder(View v, IViewHolderClick listener) { super(v); this.listener = listener; v.setOnClickListener(this); vAddressStart = (TextView) v.findViewById(R.id.addressStart); vAddressEnd = (TextView) v.findViewById(R.id.addressEnd); vStatus = (TextView) v.findViewById(R.id.status); } public void initFromData(OrderData data) { Log.d(TAG, "><initFromData(data=" + data + ")"); orderId = data.getId(); vAddressStart.setText(data.getAddressStart()); vAddressEnd.setText(data.getAddressEnd()); } public long getOrderId() { return orderId; } @Override public void onClick(View view) { listener.onCardClick(view, getPosition(), this); } public interface IViewHolderClick { public void onCardClick(View view, int position, ViewHolder viewHolder); } } @Override public int getItemViewType(int position) { return position == 0 ? ID_VIEW_HOLDER_ACTUAL : ID_VIEW_HOLDER; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { Log.d(TAG, ">>onCreateViewHolder(parent=" + parent + ", viewType=" + viewType + ")"); ViewHolder result; switch (viewType) { case ID_VIEW_HOLDER_ACTUAL: { View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_layout_actual, parent, false); result = new ViewHolderActual(itemView, new ViewHolderActual.IViewHolderClick() { @Override public void onCardClick(View view, int position, ViewHolder viewHolder) { Log.d(TAG, "><onCardClick(view=" + view + ", position=" + position + ", viewHolder=" + viewHolder + ")"); Intent intent = new Intent(view.getContext(), OrderDetailActivity.class); intent.putExtra(OrderDetailActivity.ARG_ORDER_ID, viewHolder.getOrderId()); view.getContext().startActivity(intent); } @Override public void onButtonClick(Button button, int position, ViewHolder viewHolder) { Log.d(TAG, "><onButtonClick(button=" + button + ", position=" + position + ", viewHolder=" + viewHolder + ")"); Intent intent = new Intent(button.getContext(), OrderMapActivity.class); intent.putExtra(OrderMapActivity.ARG_ORDER_ID, viewHolder.getOrderId()); button.getContext().startActivity(intent); } }); break; } case ID_VIEW_HOLDER: default: { View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_layout, parent, false); result = new ViewHolder(itemView, new ViewHolder.IViewHolderClick() { @Override public void onCardClick(View view, int position, ViewHolder viewHolder) { Log.d(TAG, "><onCardClick(view=" + view + ", position=" + position + ", viewHolder=" + viewHolder + ")"); Intent intent = new Intent(view.getContext(), OrderDetailActivity.class); intent.putExtra(OrderDetailActivity.ARG_ORDER_ID, viewHolder.getOrderId()); view.getContext().startActivity(intent); } }); break; } } Log.d(TAG, "<<onCreateViewHolder(parent=" + parent + ", viewType=" + viewType + ")= " + result); return result; } @Override public void onBindViewHolder(ViewHolder viewHolder, Cursor cursor) { Log.d(TAG, "><onBindViewHolder(viewHolder=" + viewHolder + ", cursor=" + cursor + ")"); final OrderData orderData = new OrderData(cursor); viewHolder.initFromData(orderData); } }
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:25
Kontynuacja MLProgrammer-doskonałe rozwiązanie RxJava CiM
Konsumuj / Obserwuj kliknięcia
Consumer<String> mClickConsumer = new Consumer<String>() {
@Override
public void accept(@NonNull String element) throws Exception {
Toast.makeText(getApplicationContext(), element +" was clicked", Toast.LENGTH_LONG).show();
}
};
ReactiveAdapter rxAdapter = new ReactiveAdapter();
rxAdapter.getPositionClicks().subscribe(mClickConsumer);
RxJava 2.+
Zmodyfikuj oryginalny tl;dr jako:
public Observable<String> getPositionClicks(){
return onClickSubject;
}
PublishSubject#asObservable()
został usunięty. Po prostu zwróć PublishSubject
, który jest Observable
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-03-04 07:07:42
O ile dobrze rozumiem MLProgrammer-CiM odpowiedz, po prostu można to zrobić:
class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private ImageView image;
private TextView title;
private TextView price;
public MyViewHolder(View itemView) {
super(itemView);
image = (ImageView)itemView.findViewById(R.id.horizontal_list_image);
title = (TextView)itemView.findViewById(R.id.horizontal_list_title);
price = (TextView)itemView.findViewById(R.id.horizontal_list_price);
image.setOnClickListener(this);
title.setOnClickListener(this);
price.setOnClickListener(this);
}
@Override
public void onClick(View v) {
Toast.makeText(context, "Item click nr: "+getLayoutPosition(), Toast.LENGTH_SHORT).show();
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-24 20:01:23
Po przeczytaniu @MLProgrammer-CIM's odpowiedź, Oto Mój kod:
class NormalViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
@Bind(R.id.card_item_normal)
CardView cardView;
public NormalViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
cardView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if(v instanceof CardView) {
// use getAdapterPosition() instead of getLayoutPosition()
int itemPosition = getAdapterPosition();
removeItem(itemPosition);
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-12 08:07:32
Zrobiłem tak, to bardzo proste:
Po prostu dodaj 1 linię dla Kliknij pozycję RecyclerView:
int position = getLayoutPosition()
Pełny kod dla viewholder klasa:
private class ChildViewHolder extends RecyclerView.ViewHolder {
public ImageView imageView;
public TextView txtView;
public ChildViewHolder(View itemView) {
super(itemView);
imageView= (ImageView)itemView.findViewById(R.id.imageView);
txtView= (TextView) itemView.findViewById(R.id.txtView);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.i("RecyclerView Item Click Position", String.valueOf(getLayoutPosition()));
}
});
}
}
Mam nadzieję, że to ci pomoże.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-03 13:44:31
Używam tej metody, aby rozpocząć intencję z RecyclerView:
@Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
final MyClass myClass = mList.get(i);
viewHolder.txtViewTitle.setText(myclass.name);
...
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v){
Intent detailIntent = new Intent(mContext, type.class);
detailIntent.putExtra("MyClass", myclass);
mContext.startActivity(detailIntent);
}
}
);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-06 17:54:10
RecyclerView nie posiada onItemClickListener
, ponieważ RecyclerView jest odpowiedzialny zaRecycling views (niespodzianka!), więc to właśnie za obsługę zdarzeń kliknięć odpowiada widok, który jest poddawany recyklingowi.
To sprawia, że jest znacznie łatwiejsze w użyciu, zwłaszcza jeśli Masz Przedmioty, które można kliknąć w wielu miejscach.
Tak czy inaczej, wykrywanie kliknięcia na elemencie RecyclerView jest bardzo proste. Wystarczy zdefiniować interfejs (jeśli nie korzystasz z Kotlina, w którym jeśli tylko zdasz w lambdzie):
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
private final Clicks clicks;
public MyAdapter(Clicks clicks) {
this.clicks = clicks;
}
private List<MyObject> items = Collections.emptyList();
public void updateData(List<MyObject> items) {
this.items = items;
notifyDataSetChanged(); // TODO: use ListAdapter for diffing instead if you need animations
}
public interface Clicks {
void onItemSelected(MyObject myObject, int position);
}
public class MyViewHolder extends RecyclerView.ViewHolder {
private MyObject myObject;
public MyViewHolder(View view) {
super(view);
// bind views
view.setOnClickListener((v) -> {
int adapterPosition = getAdapterPosition();
if(adapterPosition >= 0) {
clicks.onItemSelected(myObject, adapterPosition);
}
});
}
public void bind(MyObject myObject) {
this.myObject = myObject;
// bind data to views
}
}
}
Ten sam kod w Kotlinie:
class MyAdapter(val itemClicks: (MyObject, Int) -> Unit): RecyclerView.Adapter<MyViewHolder>() {
private var items: List<MyObject> = Collections.emptyList()
fun updateData(items: List<MyObject>) {
this.items = items
notifyDataSetChanged() // TODO: use ListAdapter for diffing instead if you need animations
}
inner class MyViewHolder(val myView: View): RecyclerView.ViewHolder(myView) {
private lateinit var myObject: MyObject
init {
// binds views
myView.onClick {
val adapterPosition = getAdapterPosition()
if(adapterPosition >= 0) {
itemClicks.invoke(myObject, adapterPosition)
}
}
}
fun bind(myObject: MyObject) {
this.myObject = myObject
// bind data to views
}
}
}
Thing you DON ' t need to do:
1. nie musisz ręcznie przechwytywać zdarzeń dotykowych]}
2.) nie musisz zadzierać z dziećmi dołączaj zmiany stanu słuchaczy
3.) nie musisz PublishSubject / PublishRelay z RxJava
Wystarczy użyć słuchacza kliknięcia.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-26 13:21:51
Zobacz moje podejście do tego:
Najpierw zadeklaruj interfejs w ten sposób:
/**
* Interface used for delegating item click events in a {@link android.support.v7.widget.RecyclerView}
* Created by Alex on 11/28/2015.
*/
public interface OnRecyclerItemClickListener<T> {
/**
* Called when a click occurred inside a recyclerView item view
* @param view that was clicked
* @param position of the clicked view
* @param item the concrete data that is displayed through the clicked view
*/
void onItemClick(View view, int position, T item);
}
Następnie utwórz adapter:
public class CustomRecyclerAdapter extends RecyclerView.Adapter {
private class InternalClickListener implements View.OnClickListener{
@Override
public void onClick(View v) {
if(mRecyclerView != null && mItemClickListener != null){
// find the position of the item that was clicked
int position = mRecyclerView.getChildAdapterPosition(v);
Data data = getItem(position);
// notify the main listener
mItemClickListener.onItemClick(v, position, data);
}
}
}
private final OnRecyclerItemClickListener mItemClickListener;
private RecyclerView mRecyclerView;
private InternalClickListener mInternalClickListener;
/**
*
* @param itemClickListener used to trigger an item click event
*/
public PlayerListRecyclerAdapter(OnRecyclerItemClickListener itemClickListener){
mItemClickListener = itemClickListener;
mInternalClickListener = new InternalClickListener();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item, parent, false);
v.setOnClickListener(mInternalClickListener);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
// do your binding here
}
@Override
public int getItemCount() {
return mDataSet.size();
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
mRecyclerView = recyclerView;
}
@Override
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
super.onDetachedFromRecyclerView(recyclerView);
mRecyclerView = null;
}
public Data getItem(int position){
return mDataset.get(position);
}
}
A teraz zobaczmy, jak zintegrować to z fragmentu:
public class TestFragment extends Fragment implements OnRecyclerItemClickListener<Data>{
private RecyclerView mRecyclerView;
@Override
public void onItemClick(View view, int position, Data item) {
// do something
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.test_fragment, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
mRecyclerView = view.findViewById(idOfTheRecycler);
mRecyclerView .setAdapter(new CustomRecyclerAdapter(this));
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-28 13:09:28
Jeśli chcesz dodać onclick() do widoku potomnego elementów, na przykład przycisk W item, odkryłem, że możesz to zrobić łatwo w oncreateviewholder() własnego RecyclerView.Adapter właśnie tak:
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater
.from(parent.getContext())
.inflate(R.layout.cell, null);
Button btn = (Button) v.findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//do it
}
});
return new MyViewHolder(v);
}
Nie wiem, czy to dobry sposób, ale działa dobrze. Jeśli ktoś ma lepszy pomysł, bardzo mi miło powiedzieć i poprawić moją odpowiedź! :)Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-30 12:46:20
Oto sposób, aby zaimplementować go dość łatwo, jeśli masz listę Pojo i chcesz pobrać jeden po kliknięciu spoza adaptera.
W adapterze Utwórz detektor zdarzeń kliknięć i metodę, aby go ustawić:
public class MyAdapter extends RecyclerView.Adapter<SitesListAdapter.ViewHolder> {
...
private List<MyPojo> mMyPojos;
private static OnItemClickListener mOnItemClickListener;
...
public interface OnItemClickListener {
public void onItemClick(MyPojo pojo);
}
...
public void setOnItemClickListener(OnItemClickListener onItemClickListener){
mOnItemClickListener = onItemClickListener;
}
...
}
W Twoim Viewholderze, zaimplementuj onClickListener i utwórz członka klasy, aby tymczasowo przechowywał POJO, które prezentuje widok, w ten sposób (to jest przykład, utworzenie settera byłoby lepsze):
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public MyPojo mCurrentPojo;
...
public ViewHolder(View view) {
super(v);
...
view.setOnClickListener(this); //You could set this on part of the layout too
}
...
@Override
public void onClick(View view) {
if(mOnItemClickListener != null && mCurrentPojo != null){
mOnItemClickListener.onItemClick(mCurrentPojo);
}
}
Wróć do adaptera, Ustaw bieżące POJO, gdy ViewHolder jest związany (lub do null, Jeśli bieżący widok go nie ma):
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final MyPojo currentPojo = mMyPojos.get(position);
holder.mCurrentPojo = currentPojo;
...
To jest to, teraz możesz użyć go w ten sposób ze swojego fragmentu / aktywności:
mMyAdapter.setOnItemClickListener(new mMyAdapter.OnItemClickListener() {
@Override
public void onItemClick(MyPojo pojo) {
//Do whatever you want with your pojo here
}
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-01 18:25:24
Yes you can
public ViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {
//inflate the view
View view = LayoutInflator.from(parent.getContext()).inflate(R.layout.layoutID,null);
ViewHolder holder = new ViewHolder(view);
//here we can set onClicklistener
view.setOnClickListener(new View.OnClickListeener(){
public void onClick(View v)
{
//action
}
});
return holder;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-28 07:21:30
Tutaj możesz obsłużyć wiele onclick patrz poniżej kod i jest bardzo wydajny
public class RVNewsAdapter extends RecyclerView.Adapter<RVNewsAdapter.FeedHolder> {
private Context context;
List<News> newsList;
// Allows to remember the last item shown on screen
private int lastPosition = -1;
public RVNewsAdapter(List<News> newsList, Context context) {
this.newsList = newsList;
this.context = context;
}
public static class FeedHolder extends RecyclerView.ViewHolder implements OnClickListener {
ImageView img_main;
TextView tv_title;
Button bt_facebook, bt_twitter, bt_share, bt_comment;
public FeedHolder(View itemView) {
super(itemView);
img_main = (ImageView) itemView.findViewById(R.id.img_main);
tv_title = (TextView) itemView.findViewById(R.id.tv_title);
bt_facebook = (Button) itemView.findViewById(R.id.bt_facebook);
bt_twitter = (Button) itemView.findViewById(R.id.bt_twitter);
bt_share = (Button) itemView.findViewById(R.id.bt_share);
bt_comment = (Button) itemView.findViewById(R.id.bt_comment);
img_main.setOnClickListener(this);
bt_facebook.setOnClickListener(this);
bt_twitter.setOnClickListener(this);
bt_comment.setOnClickListener(this);
bt_share.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (v.getId() == bt_comment.getId()) {
Toast.makeText(v.getContext(), "Comment " , Toast.LENGTH_SHORT).show();
} else if (v.getId() == bt_facebook.getId()) {
Toast.makeText(v.getContext(), "Facebook " , Toast.LENGTH_SHORT).show();
} else if (v.getId() == bt_twitter.getId()) {
Toast.makeText(v.getContext(), "Twitter " , Toast.LENGTH_SHORT).show();
} else if (v.getId() == bt_share.getId()) {
Toast.makeText(v.getContext(), "share " , Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(v.getContext(), "ROW PRESSED = " + String.valueOf(getAdapterPosition()), Toast.LENGTH_SHORT).show();
}
}
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
@Override
public FeedHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.feed_row, parent, false);
FeedHolder feedHolder = new FeedHolder(view);
return feedHolder;
}
@Override
public void onBindViewHolder(FeedHolder holder, int position) {
holder.tv_title.setText(newsList.get(position).getTitle());
// Here you apply the animation when the view is bound
setAnimation(holder.img_main, position);
}
@Override
public int getItemCount() {
return newsList.size();
}
/**
* Here is the key method to apply the animation
*/
private void setAnimation(View viewToAnimate, int position) {
// If the bound view wasn't previously displayed on screen, it's animated
if (position > lastPosition) {
Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left);
viewToAnimate.startAnimation(animation);
lastPosition = position;
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-05 13:07:03
Zmodyfikował mój komentarz...
public class MyViewHolder extends RecyclerView.ViewHolder {
private Context mContext;
public MyViewHolder(View itemView) {
super(itemView);
mContext = itemView.getContext();
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int itemPosition = getLayoutPosition();
Toast.makeText(mContext, "" + itemPosition, Toast.LENGTH_SHORT).show();
}
});
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-20 18:51:05
Sprawdź ten, w którym zaimplementowałem wszystkie rzeczy w odpowiedni sposób
Klasa RecyclerViewHolder
public class RecyclerViewHolder extends RecyclerView.ViewHolder {
//view holder is for girdview as we used in the listView
public ImageView imageView,imageView2;
public RecyclerViewHolder(View itemView) {
super(itemView);
this.imageView=(ImageView)itemView.findViewById(R.id.image);
}
}
Adapter
public class RecyclerView_Adapter extends RecyclerView.Adapter<RecyclerViewHolder> {
//RecyclerView will extend to recayclerview Adapter
private ArrayList<ModelClass> arrayList;
private Context context;
private static RecyclerViewClickListener itemListener;
//constructor of the RecyclerView Adapter
RecyclerView_Adapter(Context context,ArrayList<ModelClass> arrayList,RecyclerViewClickListener itemListener){
this.context=context;
this.arrayList=arrayList;
this.itemListener=itemListener;
}
@Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//this method will inflate the custom layout and return as viewHolder
LayoutInflater layoutInflater=LayoutInflater.from(parent.getContext());
ViewGroup mainGroup=(ViewGroup) layoutInflater.inflate(R.layout.single_item,parent,false);
RecyclerViewHolder listHolder=new RecyclerViewHolder(mainGroup);
return listHolder;
}
@Override
public void onBindViewHolder(RecyclerViewHolder holder, final int position) {
final ModelClass modelClass=arrayList.get(position);
//holder
RecyclerViewHolder mainHolder=(RecyclerViewHolder)holder;
//convert the drawable image into bitmap
Bitmap image= BitmapFactory.decodeResource(context.getResources(),modelClass.getImage());
//set the image into imageView
mainHolder.imageView.setImageBitmap(image);
//to handle on click event when clicked on the recyclerview item and
// get it through the RecyclerViewHolder class we have defined the views there
mainHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//get the position of the image which is clicked
itemListener.recyclerViewListClicked(v,position);
}
});
}
@Override
public int getItemCount() {
return (null!=arrayList?arrayList.size():0);
}
}
Interfejs
public interface RecyclerViewClickListener {
//this is method to handle the event when clicked on the image in Recyclerview
public void recyclerViewListClicked(View v,int position);
}
//and to call this method in activity
RecyclerView_Adapter adapter=new RecyclerView_Adapter(Wallpaper.this,arrayList,this);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
@Override
public void recyclerViewListClicked(View v,int position){
imageView.setImageResource(wallpaperImages[position]);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-04 20:56:44
To mi pomogło:
@Override
public void onBindViewHolder(PlacesListViewAdapter.ViewHolder holder, int position) {
----
----
----
// Set setOnClickListener(holder);
}
@Override
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
----
----
----
@Override
public void onClick(View view) {
// Use to get the item clicked getAdapterPosition()
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-27 00:54:10
Dostęp do mainView
z rowLayout(cell)
dla Ciebie RecyclerView
i w twoim OnBindViewHolder
napisz ten kod:
@Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
Movie movie = moviesList.get(position);
holder.mainView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
System.out.println("pos " + position);
}
});
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-18 15:06:40
U mnie zadziałało. Mam nadzieję, że to pomoże. Najprostszy sposób.
Inside View Holder
class GeneralViewHolder extends RecyclerView.ViewHolder {
View cachedView = null;
public GeneralViewHolder(View itemView) {
super(itemView);
cachedView = itemView;
}
Inside OnBindViewHolder()
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
final GeneralViewHolder generalViewHolder = (GeneralViewHolder) holder;
generalViewHolder.cachedView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, "item Clicked at "+position, Toast.LENGTH_SHORT).show();
}
});
i daj mi znać, masz jakieś pytania dotyczące tego rozwiązania ?
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-06 10:18:32
Zamiast implementacji widoku interfejsu.Onclicklistener wewnątrz uchwyt widok lub tworzenie i interfejs i wdrożenie interfejsu w swojej działalności.. Użyłem tego kodu do prostej implementacji OnClickListener.
public static class SimpleStringRecyclerViewAdapter
extends RecyclerView.Adapter<SimpleStringRecyclerViewAdapter.ViewHolder> {
// Your initializations goes here...
private List<String> mValues;
public static class ViewHolder extends RecyclerView.ViewHolder {
//create a variable mView
public final View mView;
/*All your row widgets goes here
public final ImageView mImageView;
public final TextView mTextView;*/
public ViewHolder(View view) {
super(view);
//Initialize it here
mView = view;
/* your row widgets initializations goes here
mImageView = (ImageView) view.findViewById(R.id.avatar);
mTextView = (TextView) view.findViewById(android.R.id.text1);*/
}
}
public String getValueAt(int position) {
return mValues.get(position);
}
public SimpleStringRecyclerViewAdapter(Context context, List<String> items) {
mBackground = mTypedValue.resourceId;
mValues = items;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item, parent, false);
view.setBackgroundResource(mBackground);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.mBoundString = mValues.get(position);
holder.mTextView.setText(mValues.get(position));
//Here it is simply write onItemClick listener here
holder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext();
Intent intent = new Intent(context, ExampleActivity.class);
context.startActivity(intent);
}
});
}
@Override
public int getItemCount() {
return mValues.size();
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-07 06:38:43
main_recyclerview.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e)
{
int position=rv.getChildAdapterPosition(rv.findChildViewUnder(e.getX(),e.getY()));
switch (position)
{
case 0:
{
wifi(position);
adapter2.notifyDataSetChanged();
}
break;
case 1:
{
sound(position);
adapter2.notifyDataSetChanged();
}
break;
case 2:
{
bluetooth(position);
adapter2.notifyDataSetChanged();
}
break;
}
return true;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e)
{
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-07 10:17:54
Use PlaceHolderView
@Layout(R.layout.item_view_1)
public class View1{
@View(R.id.txt)
public TextView txt;
@Resolve
public void onResolved() {
txt.setText(String.valueOf(System.currentTimeMillis() / 1000));
}
@Click(R.id.btn)
public void onClick(){
txt.setText(String.valueOf(System.currentTimeMillis() / 1000));
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-19 08:51:16
Napisałem bibliotekę do obsługi android recycler view item click event. Cały tutorial znajdziesz w https://github.com/ChathuraHettiarachchi/RecycleClick
RecycleClick.addTo(YOUR_RECYCLEVIEW).setOnItemClickListener(new RecycleClick.OnItemClickListener() {
@Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
// YOUR CODE
}
});
Lub do obsługi pozycji long press można użyć
RecycleClick.addTo(YOUR_RECYCLEVIEW).setOnItemLongClickListener(new RecycleClick.OnItemLongClickListener() {
@Override
public boolean onItemLongClicked(RecyclerView recyclerView, int position, View v) {
// YOUR CODE
return true;
}
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-02 11:54:47
Animacja Recyclerview nie została przetestowana, druga jest normalna. Myślę, że został zoptymalizowany do maksimum. Interfejs ma inne zastosowania, możesz tymczasowo zignorować.
public abstract class BaseAdapterRV<VH extends BaseViewHolder> extends RecyclerView.Adapter<VH> implements AdapterInterface {
public final String TAG = getClass().getSimpleName();
protected final Activity mActivity;
protected final LayoutInflater mInflater;
protected ItemClickInterface<?, Integer> mListener;
public BaseAdapterRV(Activity activity) {
mActivity = activity;
mInflater = LayoutInflater.from(mActivity);
}
@Override
public final VH onCreateViewHolder(ViewGroup parent, int viewType) {
return onCreateViewHolder(parent, viewType, mInflater);
}
@Override
public final void onBindViewHolder(VH holder, int position) {
holder.itemView.setTag(R.id.tag_view_click, position);
//创建点击事件
holder.itemView.setOnClickListener(mListener);
holder.itemView.setOnLongClickListener(mListener);
onBindVH(holder, position);
}
///////////////////////////////////////////////////////////////////////////
// 以下是增加的方法
///////////////////////////////////////////////////////////////////////////
/**
* 注意!涉及到notifyItemInserted刷新时立即获取position可能会不正确
* 里面也有onItemLongClick
*/
public void setOnItemClickListener(ItemClickInterface<?, Integer> listener) {
mListener = listener;
notifyDataSetChanged();
}
@NonNull
protected abstract VH onCreateViewHolder(ViewGroup parent, int viewType, LayoutInflater inflater);
protected abstract void onBindVH(VH holder, int position);
}
To jest Interfejs
/**
* OnItemClickListener的接口
* 见子类实现{@link OnItemClickListener}{@link OnItemItemClickListener}
*/
public interface ItemClickInterface<DATA1, DATA2> extends View.OnClickListener, View.OnLongClickListener {
void onItemClick(DATA1 data1, DATA2 data2);
boolean onItemLongClick(DATA1 data1, DATA2 data2);
}
Jest to klasa abstrakcyjna
public abstract class OnItemClickListener<DATA> implements ItemClickInterface<View, DATA> {
@Override
public void onClick(View v) {
onItemClick(v, (DATA) v.getTag(R.id.tag_view_click));
}
@Override
public boolean onLongClick(View v) {
return onItemLongClick(v, (DATA) v.getTag(R.id.tag_view_click));
}
@Override
public boolean onItemLongClick(View view, DATA data) {
return false;
}
}
You only need it
mAdapter.setOnItemClickListener(new OnItemClickListener<Integer>() {
@Override
public void onItemClick(View view, Integer integer) {
}
@Override
public boolean onItemLongClick(View view, Integer integer) {
return true;
}
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-16 03:07:20
Znalazłem jeden z najkrótszych sposobów korzystania z androidx lifecycle mutable live data
Adapter:
private val onItemClickListener = MutableLiveData<YourAdapterItem>()
override fun onBindViewHolder(holder: GifsViewHolder, position: Int) {
holder.itemView.setOnClickListener { onItemClickListener.value = gifs[position] }
}
fun getOnItemClickListener(): MutableLiveData<Gif> {
return onItemClickListener
}
Anywhere in Main
yourFancyAdapter.getOnItemClickListener().observe(this, Observer {
println(it)
})
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-11 14:48:24