我正试图通过职位获得儿童观点。单击一个项目时我可以查看:
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获取子视图?
编辑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时。
我的问题:如何使用项目的位置从回收站视图获取视图(没有点击监听器)?
答案 0 :(得分:19)
使用recyclerView.findViewHolderforLayoutPosition(position)
或
reyclerView.findViewHolderforAdaperPosition(position)
获取posholder的视图。然后,您可以访问查看者中的任何孩子。
答案 1 :(得分:7)
您可以使用RecyclerView的LayoutManager。
View view = layoutManager.findViewByPosition(position)
答案 2 :(得分:4)
RecyclerView.ViewHolder holder = recycleView.findViewHolderForAdapterPosition(position);
ImageView imageView = holder.itemView.findViewById(R.id.iv_product);
这是对@Ravi Teja的回答的补充。您可以使用特定项目的位置从recyclerView获取viewHolder,然后从viewHolder获取特定视图,如上所示
答案 3 :(得分:2)
我发布了一个答案,因为这对于来自RecyclerView的findviews()非常复杂。
@Joe:花了4个小时后找到了一个答案。这给了我正确的索引视图。mAdapter is adapter of RecyclerView
View v = recyclerView.findViewHolderForItemId(mAdapter.getItemId(index/position)).itemView;
现在只需访问您的观点:
v.findViewById(R.id.edittext)
或任何身份证明。
答案 4 :(得分:1)
希望这有助于某人: 我得到了空指针异常:
原因是视图的创建时间略有延迟。 我在这里找到了解决方案:https://stackoverflow.com/a/33414430/7952427
答案 5 :(得分:1)
它帮助了我,在操作它之前要延迟100毫秒,就像这样:
Handler handler = new Handler();
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
// rcv is my recyclerview
rcvStatus.getChildAt(1).setBackground(getActivity().getResources().getDrawable(R.drawable.disabled));
// or:
rcvStatus.getChildAt(1).setClickable(false);
}
}, 100);
答案 6 :(得分:0)
将此方法写入适配器。
public Object getItem(int position) {
return yourArrayList.get(position);
}
你需要像
一样调用它yourAdapter.getItem(2);
通过你所需的职位。 希望它能解决你的问题。
答案 7 :(得分:0)
只需将此方法放入您的代码中即可随意调用
void someMagicalMethodWhichReturnsViewByPosition(int position){
//I assumes child views are CardView
CardView c = (CardView)rvSellRecords.getItem(int position);
///optional codes
//////////
}
答案 8 :(得分:0)
现在我明白你的问题了。您需要使用接口来连接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(I));
答案 9 :(得分:0)
我不建议您自己跟踪视图列表。这可能会导致项目更新,职位更新等方面的奇怪问题。
而不是在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));
}
作为旁注,最好将实际项目点击监听器实现到ViewHolder上的itemView,而不是使用触摸监听器。网上有很多这样的例子。
答案 10 :(得分:0)
因此,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(position)会返回最新的视图。
此处MyViewHolder是您的观察者类和yourRecyclerview,是对您的回收者视图的引用