儿童RecyclerView项目的父级RecyclerView点击事件

时间:2018-01-28 10:47:18

标签: java android android-recyclerview

我有一个显示项目列表的回收站视图。 在每个项目中,有一个标题和另一个显示项目列表的RecyclerView。

我想访问子RecyclerView项目的点击事件。

布局截图:

Layout Preview

父级RecyclerView:

public class DetailsGroupAdapter extends RecyclerView.Adapter<DetailsGroupAdapter.ViewHolder>{
private static OnItemClickListener listener;
private Context context;
private int lastPosition = -1;
RecyclerView mRecyclerView;

public interface OnItemClickListener {
    void onItemClick(View itemView, int position);
    void onGroupItemLongClick(View itemView, int groupPosition, int itemPosition);
    void onGroupItemClick(View itemView, int groupPosition, int itemPosition);
}

public void setOnItemClickListener(OnItemClickListener listener) {
    DetailsGroupAdapter.listener = listener;
}

public static class ViewHolder extends RecyclerView.ViewHolder {

    public TextView tvTitle;
    public CardView cvContainer;
    public RecyclerView rvItems;

    public ViewHolder(final View itemView)
    {
        super(itemView);
        tvTitle = itemView.findViewById(R.id.group_title);
        cvContainer = itemView.findViewById(R.id.container);
        rvItems = itemView.findViewById(R.id.rv_group_items);
        //click listener setup
        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Triggers click upwards to the adapter on click
                if (listener != null)
                    listener.onItemClick(itemView, getLayoutPosition());
            }
        });
    }

    public void clearAnimation()
    {
        cvContainer.clearAnimation();
    }
}

private List<DetailsGroup> itemList;

public DetailsGroupAdapter(List<DetailsGroup> itemList)
{
    this.itemList = itemList;
}

@Override
public DetailsGroupAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
    context = parent.getContext();
    LayoutInflater inflater = LayoutInflater.from(context);
    View layoutView = inflater.inflate(R.layout.item_details_group, parent, false);
    mRecyclerView = (RecyclerView) parent;
    return new ViewHolder(layoutView);
}

@Override
public void onBindViewHolder(final DetailsGroupAdapter.ViewHolder viewHolder, int groupPosition){
    final DetailsGroup detailsGroup = itemList.get(groupPosition);
    if(detailsGroup.Title != null){
        viewHolder.tvTitle.setText(detailsGroup.Title);
    } else {
        viewHolder.tvTitle.setVisibility(View.GONE);
    }

    final DetailsGroupItemsAdapter detailsGroupAdapter = new DetailsGroupItemsAdapter(detailsGroup.itemsList, groupPosition);

    detailsGroupAdapter.setOnItemClickListener(new DetailsGroupItemsAdapter.OnItemClickListener() {
        @Override
        public void onItemClick(View itemView, int position) {
            if (listener != null){
                listener.onGroupItemClick(itemView, (int) itemView.getTag(), position);
            }
        }
        @Override
        public void onLongClick(View itemView, int position) {
            if (listener != null){
                listener.onGroupItemLongClick(itemView, (int) itemView.getTag(), position);
            }
        }
    });

    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context) {};
    viewHolder.rvItems.setLayoutManager(linearLayoutManager);
    viewHolder.rvItems.setAdapter(detailsGroupAdapter);
}

private void setAnimation(View viewToAnimate, int position)
{
    if (position > lastPosition) {
        AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
        anim.setDuration(1000);
        viewToAnimate.startAnimation(anim);
        lastPosition = position;
    }
}

@Override
public void onViewDetachedFromWindow(final ViewHolder holder)
{
    ((ViewHolder)holder).cvContainer.clearAnimation();
}

@Override
public long getItemId(int position) {
    return itemList.get(position).hashCode();
}

@Override
public int getItemCount()
{
    return itemList.size();
}

public void clear() {
    itemList.clear();
    notifyDataSetChanged();
}

public void addAll(List<DetailsGroup> list){
    itemList.addAll(list);
    notifyDataSetChanged();
}

}

儿童RecyclerView:

public class DetailsGroupItemsAdapter extends RecyclerView.Adapter<DetailsGroupItemsAdapter.ViewHolder>{
private static OnItemClickListener listener;
private Context context;
private int lastPosition = -1;
private int groupPosition;
public interface OnItemClickListener {
    void onItemClick(View itemView, int position);
    void onLongClick(View itemView,int position);
}

public void setOnItemClickListener(OnItemClickListener listener) {
    DetailsGroupItemsAdapter.listener = listener;
}

public static class ViewHolder extends RecyclerView.ViewHolder {

    public TextView tvTitle;
    public TextView tvSubTitle;
    public ImageView ivThumbnail;
    public LinearLayout llContainer;

    public ViewHolder(final View itemView)
    {
        super(itemView);
        ivThumbnail = itemView.findViewById(R.id.thumbnail);
        tvTitle = itemView.findViewById(R.id.title);
        tvSubTitle = itemView.findViewById(R.id.subtitle);
        llContainer = itemView.findViewById(R.id.container);

        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (listener != null)
                    listener.onItemClick(itemView, getLayoutPosition());
            }
        });

        itemView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                if (listener != null)
                    listener.onLongClick(itemView, getLayoutPosition());
                return false;
            }
        });
    }

    public void clearAnimation()
    {
        llContainer.clearAnimation();
    }
}

private List<ItemDetail> itemList;

public DetailsGroupItemsAdapter(List<ItemDetail> itemList, int groupPosition)
{
    this.itemList = itemList;
    this.groupPosition = groupPosition;
}

@Override
public DetailsGroupItemsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
    context = parent.getContext();
    LayoutInflater inflater = LayoutInflater.from(context);
    View layoutView = inflater.inflate(R.layout.item_details, parent, false);
    return new ViewHolder(layoutView);
}

@Override
public void onBindViewHolder(DetailsGroupItemsAdapter.ViewHolder viewHolder, int position){
    viewHolder.itemView.setTag(groupPosition);

    ItemDetail itemDetail = itemList.get(position);

    if(itemDetail.Title != null){
        viewHolder.tvTitle.setText(itemDetail.Title);
    } else {
        viewHolder.tvTitle.setVisibility(View.GONE);
    }

    if(itemDetail.Sub_Title != null){
        viewHolder.tvSubTitle.setText(itemDetail.Sub_Title);
    } else {
        viewHolder.tvSubTitle.setVisibility(View.GONE);
    }

    if(itemDetail.Thumbnail_Enabled){
        PicManipulationUtility.SetGenericPictureFromThumbnailType(viewHolder.ivThumbnail, itemDetail.Thumbnail_Type, itemDetail.Thumbnail);
    } else {
        viewHolder.ivThumbnail.setVisibility(View.GONE);
    }

    setAnimation(viewHolder.llContainer, position);
}

private void setAnimation(View viewToAnimate, int position)
{
    if (position > lastPosition) {
        AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
        anim.setDuration(1000);
        viewToAnimate.startAnimation(anim);
        lastPosition = position;
    }
}

@Override
public void onViewDetachedFromWindow(final ViewHolder holder)
{
    ((ViewHolder)holder).llContainer.clearAnimation();
}

@Override
public long getItemId(int position) {
    return itemList.get(position).hashCode();
}

@Override
public int getItemCount()
{
    return itemList.size();
}

public void clear() {
    itemList.clear();
    notifyDataSetChanged();
}

public void addAll(List<ItemDetail> list){
    itemList.addAll(list);
    notifyDataSetChanged();
}
}

使用的课程: ItemDetail和DetailsGroup是将JSON转换为对象的POJO。

到目前为止我设法做的暂时解决问题的方法是:

  1. 在父级RecyclerView的onBindViewHolder中,我抓住了小组位置。
  2. 然后我将父母的小组位置传递给了孩子 适配器初始化程序(DetailsGroupItemsAdapter)
  3. 最后,在子onBindViewHolder中,我将标记设置为父标记 组位置(viewHolder.itemView.setTag(groupPosition);)
  4. 所以在孩子的点击事件中,我可以说:

    listener.onGroupItemClick(itemView, (int) itemView.getTag(), position);
    

    因此,在我的Activity或Fragment中的冒泡事件中同时拥有组位置和子位置。

    但我确信通过的群组位置可以因任何原因而更改,例如更新群组项目或删除项目。 我想知道在这种情况下是否有更强大的解决方案来实现嵌套项的点击事件。

1 个答案:

答案 0 :(得分:0)

我使用了这个https://gist.github.com/riyazMuhammad/1c7b1f9fa3065aa5a46f,尤其是

CustomItemClickListener.java

public interface CustomItemClickListener {
    public void onItemClick(View v, int position);
}

(父)RecyclerView修改:

public class ItemsListAdapter extends RecyclerView.Adapter<ItemsListAdapter.ViewHolder> {
    ArrayList<ItemListSingleItem> data;

    Context mContext;
    CustomItemClickListener listener;

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.items_list_single_item, parent, false);
        final ViewHolder mViewHolder = new ViewHolder(mView);
        mView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                listener.onItemClick(v, mViewHolder.getPosition());
            }
        });
        return mViewHolder;
    }

//[... the other "classical" parts of your code...]

}
  • 单独,它允许我在子和父

  • 上有单独的点击事件
  • 经过一些修改后,它让我得到类似于你的“修复”的东西,我想,但也许它会给你一些线索:我在建造时给予孩子的父母位置和父听众它,然后点击孩子会产生与点击父母

  • 相同的行为

Child RecyclerView构造函数:

public AppsAdapter(ArrayList<PackageInformation.InfoObject> dataSet, CustomOnItemClickListener customItemClickListener, int parentPos) {
    appsDataSet = dataSet;
    onItemClickListener = customItemClickListener;
    parentPosition = parentPos;
}

Child RecyclerView onCreateViewHolder

@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {

    // Create a new view.
    View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_app, viewGroup, false);

    // Create the ViewHolder to return
    final AppsAdapter.ViewHolder mViewHolder = new AppsAdapter.ViewHolder(v);

    // Add the Listener
    v.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) { onItemClickListener.onItemClick(v, parentPosition); }
    });

    return mViewHolder;