如何在recyclerview项目中点击多个视图?

时间:2016-10-03 21:26:48

标签: android android-recyclerview recyclerview-layout

我有这个适配器类,我有一个带有列表的对象。

public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductViewHolder> {
private Context context;
private Shop shop;

public ProductAdapter(Context context, Shop shop) {
    this.context = context;
    this.shop = shop;
}

@Override
public ProductViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    View v = inflater.inflate(R.layout.product_row, parent, false);
    return new ProductViewHolder(v);
}

@Override
public void onBindViewHolder(ProductViewHolder holder, int position) {
    holder.tvProductTitle.setText(shop.products.get(position).getTitle());
    holder.tvProductDescription.setText(shop.products.get(position).getDescription());
    Glide.with(context)
            .load(shop.products.get(position).getImageUrl())
            .placeholder(android.R.drawable.ic_menu_upload_you_tube)
            .error(android.R.drawable.stat_notify_error)
            .diskCacheStrategy(DiskCacheStrategy.RESULT)
            .into(holder.ivProduct);
}

@Override
public int getItemCount() {
    if (shop.products != null) {
        return shop.products.size();
    }
    return 0;
}

public static class ProductViewHolder extends RecyclerView.ViewHolder {
    private TextView tvProductTitle, tvProductDescription;
    private ImageView ivProduct;

    public ProductViewHolder(View itemView) {
        super(itemView);
        tvProductTitle = (TextView) itemView.findViewById(R.id.tvProductTitle);
        tvProductDescription = (TextView) itemView.findViewById(R.id.tvProductDescription);
        ivProduct = (ImageView) itemView.findViewById(R.id.ivProduct);
    }
}

public interface ClickListener {
    void onClick(View v, int position);

    void onLongClick(View v, int position);
}

public static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {
    private GestureDetector gestureDetector;
    private ProductAdapter.ClickListener clickListener;

    public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ProductAdapter.ClickListener clickListener) {
        this.clickListener = clickListener;
        gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }

            @Override
            public void onLongPress(MotionEvent e) {
                View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
                if (child != null && clickListener != null) {
                    clickListener.onLongClick(child, recyclerView.getChildAdapterPosition(child));
                }
            }
        });
    }

    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        View child = rv.findChildViewUnder(e.getX(), e.getY());
        if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
            clickListener.onClick(child, rv.getChildAdapterPosition(child));
        }
        return false;
    }

    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {

    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }
}

我在我的片段中使用此适配器,我可以从recyclerview中单击一个项目,该项目将打开包含所选产品及其参数的另一个活动。我没有点击整个项目,而是点击它的一部分(比如imageview),它将像现在一样做。但是,我还想在recyclerview项目中放置一个复选框,它将具有不同的功能。目前,我不能在适配器类中使用intent。它现在的设置方式我只能点击整个项目。我怎样才能使它像上面解释的那样工作?

public class ProductsFragment extends android.support.v4.app.Fragment {
private RecyclerView rvProduct;
private RecyclerView.LayoutManager layoutManager;
private ProductAdapter productAdapter;

public static ProductsFragment newInstance(Bundle args) {
    ProductsFragment fragment = new ProductsFragment();
    fragment.setArguments(args);
    return fragment;
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_products, container, false);
    rvProduct = (RecyclerView) v.findViewById(R.id.rvProduct);
    rvProduct.setHasFixedSize(true);
    layoutManager = new GridLayoutManager(getContext(), 2);
    rvProduct.setLayoutManager(layoutManager);
    Bundle bundle = getArguments();
    final Shop shop = (Shop) bundle.getSerializable("shop");
    productAdapter = new ProductAdapter(getContext(), shop);
    rvProduct.setAdapter(productAdapter);
    productAdapter.notifyDataSetChanged();

    rvProduct.addOnItemTouchListener(new ProductAdapter.RecyclerTouchListener(getContext(), rvProduct, new ProductAdapter.ClickListener() {
        @Override
        public void onClick(View v, int position) {
            Intent details = new Intent(getContext(), ProductDetailsActivity.class);
            details.putExtra("product", shop.products.get(position));
            startActivity(details);
        }

        @Override
        public void onLongClick(View v, int position) {

        }
    }));
    return v;
}
}

修改 我已成功做到这一点,请告诉我这是否正确有效:

holder.tvProductTitle.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent i = new Intent(context, ProductDetailsActivity.class);
            i.putExtra("product", shop.products.get(position));
            context.startActivity(i);
        }
    });

2 个答案:

答案 0 :(得分:1)

你这样做的方式不正确。 当您滚动列表时,将重复调用onBindViewHolder,每次设置新的侦听器时都会。

相反,您应该在ViewHolder类的Adapter中设置侦听器。并使用getAdapterPosition()方法获取单击项目的位置。 例如:

public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductViewHolder> {     
private Context context; private Shop shop;
 public ProductAdapter(Context context, Shop shop) { 
this.context = context;
 this.shop = shop;
 } 
@Override public ProductViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
 LayoutInflater inflater = LayoutInflater.from(parent.getContext());
 View v = inflater.inflate(R.layout.product_row, parent, false);
 return new ProductViewHolder(v); 
}   
@Override public void onBindViewHolder(ProductViewHolder holder, int position) { 
holder.tvProductTitle.setText(shop.products.get(position).getTitle());
 holder.tvProductDescription.setText(shop.products.get(position).getDescription()); 
Glide.with(context) .load(shop.products.get(position).getImageUrl()) .placeholder(android.R.drawable.ic_menu_upload_you_tube) .error(android.R.drawable.stat_notify_error) .diskCacheStrategy(DiskCacheStrategy.RESULT) .into(holder.ivProduct); 
} 
@Override public int getItemCount() 
{ 
   if (shop.products != null) {
     return shop.products.size();
    } return 0;
 } 

public static class ProductViewHolder extends RecyclerView.ViewHolder {
 private TextView tvProductTitle, tvProductDescription;
 private ImageView ivProduct; 
public ProductViewHolder(View itemView)
 { 
    super(itemView); 
    tvProductTitle = (TextView) itemView.findViewById(R.id.tvProductTitle);
  tvProductDescription = (TextView) itemView.findViewById(R.id.tvProductDescription); 
ivProduct = (ImageView) itemView.findViewById(R.id.ivProduct); 
// Set onclickListener on image
ivProduct.setOnCliCkListener(new onClickListener(){
   @Override
    public void onClick(View v){
     Intent i = new Intent(context, ProductDetailsActivity.class);    
i.putExtra("product",    
shop.products.get(getAdapterPosition()));
 context.startActivity(i);
}
}
} 
 } 
public interface ClickListener { 
 void onClick(View v, int position);
  void onLongClick(View v, int position); 
}
   }

答案 1 :(得分:0)

您可以在公共onBindViewHolder中为点击项目的每个相应视图添加点击侦听器。你考虑过吗?

编辑:好的,这就是你做的。我不知道效率,但这是我的方式。