如何从RecyclerView获取子视图?

时间:2016-02-16 09:35:57

标签: android android-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获取子视图?

编辑BOUNTY

enter image description here

我有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时。

我的问题:如何使用项目的位置从回收站视图获取视图(没有点击监听器)?

enter image description here

11 个答案:

答案 0 :(得分:19)

使用recyclerView.findViewHolderforLayoutPosition(position)reyclerView.findViewHolderforAdaperPosition(position)获取posholder的视图。然后,您可以访问查看者中的任何孩子。

结帐Recyclerview

答案 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)

希望这有助于某人: 我得到了空指针异常:

  • recyclerView.findViewHolderForAdapterPosition
  • recyclerView.findViewHolderForItemId
  • layoutManager.findViewByPosition。

原因是视图的创建时间略有延迟。 我在这里找到了解决方案: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));
}

http://developer.android.com/reference/android/support/v7/widget/RecyclerView.html#findViewHolderForAdapterPosition(int)

作为旁注,最好将实际项目点击监听器实现到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,是对您的回收者视图的引用