Как получить дочерний вид из RecyclerView?
Я пытаюсь получить детское представление по положению. Я мог получить представление, когда щелкнули один элемент:
rvSellRecords.addOnItemTouchListener(new RecyclerItemClickListener(getActivity(), new RecyclerItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
((MainActivity) getActivity()).showSellRecordFragment(position, view);
}
}));
Теперь я не могу получить дочерний вид, без щелчка - допустим, например, по позиции:
rvSellRecords.someMagicalMethodWhichReturnsViewByPosition(5);
Вопрос: Как получить дочерний вид из RecyclerView?
EDIT FOR BOUNTY:
![введите описание изображения здесь]()
У меня есть RecyclerView
, чтобы показать список продуктов. Когда я нажимаю на нее, я добавляю новый фрагмент, где я показываю информацию о продукте. При открытии я обновляю панель инструментов с видом из RecyclerView
- это отлично работает:
rvSellRecords.addOnItemTouchListener(new RecyclerItemClickListener(getContext(), new RecyclerItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
sellPresenter.onSellRecordSelected(position, view);
}
}));
When I click blue button with "+", I am incrementing quantity by 1.
public void onIncrementButtonClicked(){
sellRecord.setCount(sellRecord.getCount() + 1);
showQuantity();
bus.post(new SellRecordChangedEvent(sellRecord, sellRecordPosition));
}
Then I am posting updated sellRecord to first fragment using EventBus. There I am updating list data. I supposed that updating value(sell) automatically updates adapter. Now I am getting view from adapter using custom method(getView) which was created by me(you can find it below).
@Subscribe
public void onEvent(SellRecordChangedEvent event){
sell.getSellRecords().set(event.getSellRecordPosition(), event.getSellRecord());
sell.recalculate();
int position = event.getSellRecordPosition();
View view = adapter.getView(position);
bus.post(new TransactionTitleChangedEvent(null, view));
}
This is my adapter class - I changed adapter little bit to collect view in list and added method which returns view for respective position:
public class SellRecordsAdapter extends RecyclerView.Adapter<SellRecordsAdapter.ViewHolder> {
.....
.....
.....
List<View> viewList;
public SellRecordsAdapter(List<SellRecord> sellRecordList) {
.....
viewList = new ArrayList<>();
}
.....
.....
.....
@Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
.....
.....
.....
viewList.add(i, viewHolder.itemView);
}
public View getView(int position){
return viewList.get(position);
}
}
Моя проблема: при обновлении вида на панели инструментов я становлюсь старым. Когда количество равно 3, я получаю представление с 2. Когда количество 10 - просмотр с 9.
Мой вопрос: как получить представление из вида recycler с использованием позиции элемента (без прослушивателя кликов)?
![введите описание изображения здесь]()
Ответы
Ответ 1
Используйте recyclerView.findViewHolderForLayoutPosition(position)
или reyclerView.findViewHolderForAdapterPosition(position)
чтобы получить видоискатель для позиции. Тогда вы можете получить доступ к любому ребенку из вашего видоискателя.
Оформить заказ Recyclerview
Ответ 2
Для этого вы можете использовать RecyclerView LayoutManager.
View view = layoutManager.findViewByPosition(position)
Ответ 3
RecyclerView.ViewHolder holder = recycleView.findViewHolderForAdapterPosition(position);
ImageView imageView = holder.itemView.findViewById(R.id.iv_product);
Это дополнение к ответу @Ravi Teja. Вы можете получить viewHolder из recyclerView, используя положение определенного элемента, а затем получить определенный вид из viewHolder, как показано выше.
Ответ 4
Я отправляю ответ, потому что он действительно сложный для findviews() из RecyclerView.
@Joe: После траты 4 часа нашли один ответ. Это дает мне правильное представление об индексе.
mAdapter is adapter of RecyclerView
View v = recyclerView.findViewHolderForItemId(mAdapter.getItemId(index/position)).itemView;
Теперь просто получите доступ к своим представлениям:
v.findViewById(R.id.edittext)
ИЛИ любой id.
Ответ 5
Надеюсь, это кому-нибудь поможет: я получаю исключения с нулевым указателем с:
- recyclerView.findViewHolderForAdapterPosition
- recyclerView.findViewHolderForItemId
- layoutManager.findViewByPosition.
Причина заключалась в том, что создание виджета немного задерживается. Я нашел решение здесь: fooobar.com/questions/10887100/...
Ответ 6
Запишите этот метод в адаптер.
public Object getItem(int position) {
return yourArrayList.get(position);
}
и вам просто нужно называть его как
yourAdapter.getItem(2);
передайте нужную вам позицию.
Надеюсь, он решает вашу проблему.
Ответ 7
просто поместите этот метод в свой код, и вы можете называть его как хотите
void someMagicalMethodWhichReturnsViewByPosition(int position){
//I assumes child views are CardView
CardView c = (CardView)rvSellRecords.getItem(int position);
///optional codes
//////////
}
Ответ 8
Теперь я понимаю вашу проблему. вам нужно использовать интерфейс для включения элемента recyclerview и активности.
вы должны определить класс интерфейса, как показано ниже:
public interface IViewClick {
public void onClickButtonAdd();
}
добавьте этот параметр в класс адаптера:
private IViewClick mListener;
и инициализировать его в конструкторе со значением, которое получается из входов.
когда пользователь нажимает кнопку PLUS, вы отправляете событие в действие по этой строке:
mListener.onClickButtonAdd();
в вашем классе активности вы должны реализовать интерфейс IViewClick и добавить свой код, например:
@Override
public void onClickButtonAdd() {
/// TODO every thing that you want.
/// change your toolbar values.
}
это нехорошее решение для вас.
RecyclerView.ViewHolder holder =
mRecyclerView.findViewHolderForItemId(mAdapter.getItemId(я));
Ответ 9
Я бы не рекомендовал отслеживать список просмотров самостоятельно. Это может привести к появлению странных проблем с обновлением позиций, обновлением позиций и т.д.
Вместо вашего SellRecordChangedEvent используйте findViewHolderForAdapterPosition() вместо adapter.getView().
@Subscribe
public void onEvent(SellRecordChangedEvent event){
sell.getSellRecords().set(event.getSellRecordPosition(), event.getSellRecord());
sell.recalculate();
int position = event.getSellRecordPosition();
View view = yourrecyclerview.findViewHolderForAdapterPosition(position);
bus.post(new TransactionTitleChangedEvent(null, view));
}
http://developer.android.com/reference/android/support/v7/widget/RecyclerView.html#findViewHolderForAdapterPosition(int)
И как побочная заметка, лучше использовать фактический элемент для прослушивания элемента itemView на ViewHolder вместо использования сенсорного прослушивателя. Там много примеров этого онлайн.
Ответ 10
Итак, recyclerview и ваша информация о продукте находятся в двух разных фрагментах да? Вы ожидаете, что просмотры recyclerview будут обновляться, даже если они не находятся на переднем плане? также вы меняете данные элемента данных адаптера в позиции event.getSellRecordPosition()
, но вы не уведомляете адаптер о том, что его набор данных был изменен, либо с помощью adapter.notifyDataSetChanged()
, либо других методов notifyItemChanged(position)
.
Я бы изменил ваш onEvent() следующим образом:
@Subscribe
public void onEvent(SellRecordChangedEvent event){
sell.getSellRecords().set(event.getSellRecordPosition(), event.getSellRecord());
sell.recalculate();
int position = event.getSellRecordPosition();
MyViewHolder holder = adapter.onCreateViewHolder(yourRecyclerView, 0);
adapter.onBindViewHolder(holder,position);
View view = adapter.getView(position);
bus.post(new TransactionTitleChangedEvent(null, view));
}
Вызов createViewHolder и следующего BindViewHolder на вашем адаптере определенно обновит представления для этой позиции, тогда ваш adapter.getView(позиция) должен вернуть вам последний вид.
Здесь MyViewHolder - ваш класс зрителя и вашRecyclerview, является ссылкой на ваш просмотр recycler